@ -0,0 +1,25 @@ |
|||||
|
{ |
||||
|
"root": true, |
||||
|
"rules": { |
||||
|
"import/extensions": [ |
||||
|
2, |
||||
|
"ignorePackages", |
||||
|
{ |
||||
|
"js": "never", |
||||
|
"jsx": "never", |
||||
|
"ts": "never", |
||||
|
"tsx": "never" |
||||
|
} |
||||
|
], |
||||
|
"sort-imports": [ |
||||
|
"error", |
||||
|
{ |
||||
|
"ignoreCase": false, |
||||
|
"ignoreDeclarationSort": false, |
||||
|
"ignoreMemberSort": false, |
||||
|
"memberSyntaxSortOrder": ["none", "all", "multiple", "single"], |
||||
|
"allowSeparatedGroups": false |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
{ |
||||
|
"printWidth": 120, |
||||
|
"tabWidth": 2, |
||||
|
"useTabs": false, |
||||
|
"semi": true, |
||||
|
"ssingleQuote": true, |
||||
|
"squoteProps": "as-needed", |
||||
|
"sjsxSingleQuote": false, |
||||
|
"strailingComma": "all", |
||||
|
"sbracketSpacing": true, |
||||
|
"sjsxBracketSameLine": false, |
||||
|
"sarrowParens": "always", |
||||
|
"srangeStart": 0, |
||||
|
"srangeEnd": "Infinity", |
||||
|
"srequirePragma": false, |
||||
|
"sinsertPragma": false, |
||||
|
"sproseWrap": "preserve", |
||||
|
"shtmlWhitespaceSensitivity": "css", |
||||
|
"svueIndentScriptAndStyle": false, |
||||
|
"endOfLine": "lf" |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"recommendations": [ |
||||
|
"Vue.volar", |
||||
|
] |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
"search.exclude": { |
||||
|
"lib": true |
||||
|
}, |
||||
|
"editor.formatOnSave": true, |
||||
|
"liveServer.settings.port": 9527 |
||||
|
} |
@ -0,0 +1,169 @@ |
|||||
|
import { get, post } from "../request/index.js"; |
||||
|
|
||||
|
async function getLocalizationAsync() { |
||||
|
// const url = "abp/application-configuration";
|
||||
|
// const data = (await get(url, null, null, true, true)).data;
|
||||
|
return { |
||||
|
options: [ |
||||
|
{ |
||||
|
value: "zh", |
||||
|
label: "中文", |
||||
|
}, |
||||
|
{ |
||||
|
value: "en", |
||||
|
label: "English", |
||||
|
}, |
||||
|
], |
||||
|
locale: "zh", |
||||
|
messages: { |
||||
|
zh: { |
||||
|
application: "北京北汽模塑-SAS结算分析系统", |
||||
|
copyright: "长春市闻荫科技有限公司 ©2023", |
||||
|
test: "测试", |
||||
|
compareAttribute: "{0}”和{1}不匹配", |
||||
|
fileExtensionsAttribute: "{0}只接受一下扩展名的文件: {1}", |
||||
|
maxLengthAttribute: "{0}的最大长度为 {1}", |
||||
|
minLengthAttribute: "{0}的最小长度为 {1}", |
||||
|
rangeAttribute: "{0}必需在 {1} 和 {2} 之间", |
||||
|
regularExpressionAttribute: "{0}”必需匹配{1}", |
||||
|
requiredAttribute: "{0}不能为空", |
||||
|
stringLengthAttribute: "{0}的最大长度为 {1}", |
||||
|
stringLengthAttributeIncludingMinimum: "{0}的长度在 {2} 和 {1} 之间", |
||||
|
dataTypeAttribute_CreditCard: "{0}不是有效的信用卡号码", |
||||
|
dataTypeAttribute_EmailAddress: "{0}不是有效的 Email 地址", |
||||
|
dataTypeAttribute_PhoneNumber: "{0}不是有效的手机号码", |
||||
|
dataTypeAttribute_Url: "{0}不是有效的 Url", |
||||
|
dataTypeAttribute_Upload: "{0}的扩展名必须为:{1}", |
||||
|
dataTypeAttribute_DateTime: "{0}不是有效的日期格式", |
||||
|
customValidationAttribute: "{0}验证失败", |
||||
|
validationAttribute: "{0}验证失败", |
||||
|
true: "是", |
||||
|
false: "否", |
||||
|
select: "选择", |
||||
|
confirm: "确定", |
||||
|
reset: "重置", |
||||
|
rowIndex: "行号", |
||||
|
name: "名称", |
||||
|
number: "编号", |
||||
|
value: "值", |
||||
|
order: "序号", |
||||
|
isDisabled: "禁用", |
||||
|
properties: "属性", |
||||
|
parentId: "上级", |
||||
|
lockoutEnabled: "启用锁定", |
||||
|
lockoutEnd: "锁定截止", |
||||
|
accessFailedCount: "登录失败次数", |
||||
|
isSystem: "系统内置", |
||||
|
isReadonly: "只读", |
||||
|
audit: "审计", |
||||
|
selectAll: "全选", |
||||
|
selectInverse: "反选", |
||||
|
filter: "过滤", |
||||
|
createdOn: "创建时间", |
||||
|
createdBy: "创建人", |
||||
|
updatedOn: "修改时间", |
||||
|
updatedBy: "修改人", |
||||
|
deletedOn: "删除时间", |
||||
|
deletedBy: "删除人", |
||||
|
concurrencyStamp: "并发戳", |
||||
|
operations: "操作", |
||||
|
disabled: "已禁用", |
||||
|
displayOrder: "序号", |
||||
|
isDeleted: "已删除", |
||||
|
path: "路径", |
||||
|
method: "方法", |
||||
|
isTop: "顶部", |
||||
|
htmlClass: "class", |
||||
|
internalPath: "内部路径", |
||||
|
component: "组件", |
||||
|
serverTime: "服务器时间", |
||||
|
osArchitecture: "系统架构", |
||||
|
osDescription: "操作系统", |
||||
|
processArchitecture: "进程架构", |
||||
|
tip: "提示", |
||||
|
cancel: "操作取消", |
||||
|
index: "查询", |
||||
|
details: "详情", |
||||
|
create: "新建", |
||||
|
update: "更新", |
||||
|
import: "导入", |
||||
|
export: "导出", |
||||
|
remove: "移除", |
||||
|
restore: "还原", |
||||
|
delete: "删除", |
||||
|
authenticate: "验证", |
||||
|
loginModel: "登录", |
||||
|
login: "登录", |
||||
|
logout: "注销", |
||||
|
confirmLogout: "确认退出?", |
||||
|
register: "注册", |
||||
|
userName: "用户名", |
||||
|
password: "密码", |
||||
|
email: "邮箱", |
||||
|
emailConfirmed: "邮箱已确认", |
||||
|
rememberMe: "记住我", |
||||
|
resetPassword: "重置密码", |
||||
|
userCenter: "用户中心", |
||||
|
avatar: "头像", |
||||
|
tenant: "租户", |
||||
|
connectionString: "连接字符串", |
||||
|
tenantId: "租户", |
||||
|
tenants: "租户管理", |
||||
|
identity: "认证中心", |
||||
|
systemManagement: "基础数据", |
||||
|
roleId: "角色", |
||||
|
permissionId: "权限", |
||||
|
userRoles: "用户角色", |
||||
|
enableColumnLimit: "列权限", |
||||
|
enableRowLimit: "行权限", |
||||
|
rolePermissions: "角色权限", |
||||
|
departmentId: "部门", |
||||
|
cron: "定时器", |
||||
|
icon: "图标", |
||||
|
type: "类型", |
||||
|
isExternal: "外链", |
||||
|
isHidden: "隐藏", |
||||
|
redirect: "跳转", |
||||
|
columns: "列", |
||||
|
identityModule: "系统管理", |
||||
|
user: "用户", |
||||
|
role: "角色", |
||||
|
permission: "权限", |
||||
|
department: "部门", |
||||
|
post: "岗位", |
||||
|
dict: "字典", |
||||
|
systemMonitor: "系统监控", |
||||
|
monitor: "服务监控", |
||||
|
monitorModule: "系统监控", |
||||
|
jobItem: "定时任务", |
||||
|
captcha: "验证码", |
||||
|
captchaExpired: "验证码已过期", |
||||
|
captchaError: "验证码错误", |
||||
|
dictionaryItem: "数据字典", |
||||
|
userLogin: "登录历史", |
||||
|
connectionId: "连接Id", |
||||
|
isOnline: "在线", |
||||
|
heartbeat: "心跳", |
||||
|
userAgent: "用户代理", |
||||
|
}, |
||||
|
en: { |
||||
|
application: "WTA Framework", |
||||
|
copyright: "all rights reserved © copyright", |
||||
|
test: "test", |
||||
|
login: "Login", |
||||
|
logout: "Logout", |
||||
|
confirmLogout: "Confirm Logout?", |
||||
|
register: "Register", |
||||
|
tip: "Tip", |
||||
|
cancel: "Cancel", |
||||
|
userName: "User Name", |
||||
|
password: "Password", |
||||
|
rememberMe: "Remember Me", |
||||
|
resetPassword: "Reset Password", |
||||
|
userCenter: "User Center", |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export { getLocalizationAsync }; |
@ -0,0 +1,80 @@ |
|||||
|
import router from "../router/index.js"; |
||||
|
import { get, post } from "../request/index.js"; |
||||
|
import jwt_decode from "../lib/jwt-decode/jwt-decode.esm.js"; |
||||
|
import qs from "../lib/qs/shim.js"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import { refreshRouter } from "../router/index.js"; |
||||
|
import Enumerable from "linq"; |
||||
|
import { connection } from "../signalr/index.js"; |
||||
|
|
||||
|
const isLogin = async () => { |
||||
|
const appStore = useAppStore(); |
||||
|
// 有 token,判断是否过期,失败设置 token 为 null
|
||||
|
if (appStore.token) { |
||||
|
const exp = new Date(jwt_decode(appStore.token).exp * 1000); |
||||
|
if (exp > new Date()) { |
||||
|
return true; |
||||
|
} else { |
||||
|
appStore.token = null; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}; |
||||
|
|
||||
|
const login = async (data) => { |
||||
|
const url = "connect-token"; |
||||
|
const appStore = useAppStore(); |
||||
|
const result = await post(url, data, { headers: { "Content-Type": "application/x-www-form-urlencoded" } }, true); |
||||
|
if (!result.errors) { |
||||
|
appStore.token = result.data.access_token; |
||||
|
setRefreshToken(result.data.refresh_token); |
||||
|
appStore.user = await getUser(); |
||||
|
await refreshRouter(); |
||||
|
const redirect = router.currentRoute.value.query?.redirect ?? "/"; |
||||
|
router.push(redirect); |
||||
|
} |
||||
|
return result; |
||||
|
}; |
||||
|
|
||||
|
const logout = () => { |
||||
|
const appStore = useAppStore(); |
||||
|
appStore.token = null; |
||||
|
removeRefreshToken(); |
||||
|
router.push({ path: "/login", query: { redirect: router.currentRoute.value.fullPath } }); |
||||
|
}; |
||||
|
|
||||
|
const getUser = async () => { |
||||
|
const result = await get("abp/application-configuration"); |
||||
|
const data = result.data; |
||||
|
const user = {}; |
||||
|
user.name = data.currentUser.userName; |
||||
|
user.email = data.currentUser.email; |
||||
|
user.roles = data.currentUser.roles; |
||||
|
const menus = (await get("base/role-menus")).data; |
||||
|
user.permissions = menus.items; |
||||
|
return user; |
||||
|
}; |
||||
|
|
||||
|
const hasPermission = (to) => { |
||||
|
const appStore = useAppStore(); |
||||
|
const permission = to.meta?.permission; |
||||
|
if (permission) { |
||||
|
const hasPermission = Enumerable.from(appStore.user.permissions).any((o) => o.number === permission); |
||||
|
return hasPermission; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const refreshTokenKey = "refresh_token"; |
||||
|
|
||||
|
const getRefreshToken = () => localStorage.getItem(refreshTokenKey); |
||||
|
|
||||
|
const setRefreshToken = (refreshToken) => localStorage.setItem(refreshTokenKey, refreshToken); |
||||
|
|
||||
|
const removeRefreshToken = () => { |
||||
|
localStorage.removeItem(refreshTokenKey); |
||||
|
connection.stop(); |
||||
|
}; |
||||
|
|
||||
|
export { isLogin, login, logout, getUser, hasPermission }; |
@ -0,0 +1,27 @@ |
|||||
|
import html from "html"; |
||||
|
import { ElConfigProvider } from "element-plus"; |
||||
|
import zh from "./lib/element-plus/locale/zh-cn.min.mjs"; |
||||
|
import en from "./lib/element-plus/locale/en.min.mjs"; |
||||
|
import { Suspense, reactive, onMounted } from "vue"; |
||||
|
|
||||
|
export default { |
||||
|
components: { ElConfigProvider, Suspense }, |
||||
|
template: html`<suspense>
|
||||
|
<el-config-provider :locale="localeMap.get($i18n.locale)"> |
||||
|
<router-view></router-view> |
||||
|
</el-config-provider> |
||||
|
<template #fallback> Loading... </template> |
||||
|
</suspense>`, |
||||
|
setup() { |
||||
|
const localeMap = reactive( |
||||
|
new Map([ |
||||
|
["zh", zh], |
||||
|
["en", en], |
||||
|
]) |
||||
|
); |
||||
|
onMounted(() => document.querySelector("#loading.loading").classList.remove("loading")); |
||||
|
return { |
||||
|
localeMap, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,18 @@ |
|||||
|
Markdown |
||||
|
======== |
||||
|
|
||||
|
## flowchart |
||||
|
|
||||
|
```mermaid |
||||
|
flowchart LR |
||||
|
Start --> Stop |
||||
|
``` |
||||
|
|
||||
|
## highlight |
||||
|
|
||||
|
```javascript |
||||
|
function (){ |
||||
|
let a=1; |
||||
|
alert(a); |
||||
|
} |
||||
|
``` |
After Width: | Height: | Size: 237 B |
After Width: | Height: | Size: 471 B |
After Width: | Height: | Size: 500 B |
After Width: | Height: | Size: 283 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 595 B |
After Width: | Height: | Size: 287 B |
After Width: | Height: | Size: 942 B |
After Width: | Height: | Size: 945 B |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 282 B |
After Width: | Height: | Size: 279 B |
After Width: | Height: | Size: 558 B |
After Width: | Height: | Size: 856 B |
After Width: | Height: | Size: 594 B |
After Width: | Height: | Size: 577 B |
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,37 @@ |
|||||
|
import { nextTick, ref } from 'vue'; |
||||
|
import VCharts from 'vue-echarts'; |
||||
|
|
||||
|
const template = `<VCharts
|
||||
|
v-if="renderChart" |
||||
|
:option="options" |
||||
|
:autoresize="autoresize" |
||||
|
:style="{ width, height }" |
||||
|
/>`; |
||||
|
|
||||
|
export default { |
||||
|
template, |
||||
|
components: { VCharts }, |
||||
|
props: { |
||||
|
options: { |
||||
|
default: {}, |
||||
|
}, |
||||
|
autoresize: { |
||||
|
default: true, |
||||
|
}, |
||||
|
width: { |
||||
|
default: '100%', |
||||
|
}, |
||||
|
height: { |
||||
|
default: '100%', |
||||
|
}, |
||||
|
}, |
||||
|
setup() { |
||||
|
const renderChart = ref(false); |
||||
|
nextTick(() => { |
||||
|
renderChart.value = true; |
||||
|
}); |
||||
|
return { |
||||
|
renderChart, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,93 @@ |
|||||
|
import html from "html"; |
||||
|
import { ref, reactive, watch } from "vue"; |
||||
|
import { dayjs } from "element-plus"; |
||||
|
|
||||
|
export default { |
||||
|
template: html` |
||||
|
<template v-if="getDisabled()"> |
||||
|
<template v-if="model[prop]!==null"> |
||||
|
<el-switch disabled v-model="model[prop]" type="checked" v-if="schema.type==='boolean'" /> |
||||
|
<template v-else-if="schema.format==='datetime'">{{dayjs(model[prop]).format('YYYY-MM-DD HH:mm:ss')}}</template> |
||||
|
<template v-else-if="schema.format==='date'">{{dayjs(model[prop]).format('YYYY-MM-DD')}}</template> |
||||
|
<template v-else>{{model[prop]}}</template> |
||||
|
</template> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<template v-if="getInput(schema)==='select'"> |
||||
|
<el-select |
||||
|
v-model="model[prop]" |
||||
|
:placeholder="$t('select')" |
||||
|
:multiple="!!schema.multiple" |
||||
|
clearable |
||||
|
style="width:100%" |
||||
|
> |
||||
|
<el-option v-for="item in schema.options" :key="item.value" :label="item.label" :value="item.value" /> |
||||
|
</el-select> |
||||
|
</template> |
||||
|
<el-input |
||||
|
:disabled="getDisabled()" |
||||
|
:placeholder="schema.title" |
||||
|
v-model="model[prop]" |
||||
|
type="number" |
||||
|
v-else-if="schema.type==='number'" |
||||
|
/> |
||||
|
<el-input-number |
||||
|
:disabled="getDisabled()" |
||||
|
:placeholder="schema.title" |
||||
|
v-model="model[prop]" |
||||
|
:precision="0" |
||||
|
v-else-if="schema.type==='integer'" |
||||
|
/> |
||||
|
<template v-else-if="schema.type==='boolean'"> |
||||
|
<el-select :disabled="getDisabled()" v-model="model[prop]" :placeholder="schema.title" v-if="schema.nullable"> |
||||
|
<el-option prop="select" :value="null" :label="$t('select')" /> |
||||
|
<el-option prop="true" :value="true" :label="$t('true')" /> |
||||
|
<el-option prop="false" :value="false" :label="$t('false')" /> |
||||
|
</el-select> |
||||
|
<el-switch v-model="model[prop]" type="checked" v-else /> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-input |
||||
|
:disabled="getDisabled()" |
||||
|
:placeholder="schema.title" |
||||
|
v-model="model[prop]" |
||||
|
type="password" |
||||
|
show-password |
||||
|
v-if="schema.format==='password'" |
||||
|
/> |
||||
|
<el-input :disabled="getDisabled()" :placeholder="schema.title" v-model="model[prop]" type="text" v-else /> |
||||
|
</template> |
||||
|
</template> |
||||
|
`,
|
||||
|
props: ["modelValue", "schema", "prop", "isReadOnly"], |
||||
|
emit: ["update:modelValue"], |
||||
|
async setup(props, context) { |
||||
|
const model = reactive(props.modelValue); |
||||
|
watch(model, (value) => { |
||||
|
context.emit("update:modelValue", value); |
||||
|
}); |
||||
|
/*start*/ |
||||
|
const getDisabled = () => { |
||||
|
if (props.isReadOnly && props.isReadOnly === true) { |
||||
|
return true; |
||||
|
} |
||||
|
if (props.schema.displayOnly) { |
||||
|
return true; |
||||
|
} |
||||
|
if (props.mode === "update" && props.schema.addOnly) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}; |
||||
|
const getInput = (schema) => { |
||||
|
return schema.input ?? schema.type; |
||||
|
}; |
||||
|
/*end*/ |
||||
|
return { |
||||
|
model, |
||||
|
getDisabled, |
||||
|
getInput, |
||||
|
dayjs, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,94 @@ |
|||||
|
import html from "html"; |
||||
|
import { ref, reactive, watch } from "vue"; |
||||
|
import AppFormInput from "./form-input.js"; |
||||
|
|
||||
|
export default { |
||||
|
name: "formItem", |
||||
|
components: { AppFormInput }, |
||||
|
template: html` |
||||
|
<template v-if="showItem()"> |
||||
|
<template v-if="schema.type==='object'"></template> |
||||
|
<template v-if="schema.type!=='array'||(schema.items.type!=='object'&&schema.items.type!=='array')"> </template> |
||||
|
<el-form-item |
||||
|
:title="getProp(prop)" |
||||
|
:label="schema.title" |
||||
|
:prop="getProp(prop)" |
||||
|
:rules="getRules(parentSchema,schema,model)" |
||||
|
:error="mode==='query'?null:getError(prop)" |
||||
|
> |
||||
|
<app-form-input :schema="schema" :prop="prop" v-model="model" :isReadOnly="mode==='details'" /> |
||||
|
</el-form-item> |
||||
|
</template> |
||||
|
</template> |
||||
|
`,
|
||||
|
props: ["modelValue", "mode", "parentSchema", "schema", "prop", "errors"], |
||||
|
emit: ["update:modelValue"], |
||||
|
async setup(props, context) { |
||||
|
const model = reactive(props.modelValue); |
||||
|
watch(model, (value) => { |
||||
|
context.emit("update:modelValue", value); |
||||
|
}); |
||||
|
/*start*/ |
||||
|
const showItem = () => { |
||||
|
if (props.schema.hidden) { |
||||
|
return false; |
||||
|
} |
||||
|
if (props.schema.readOnly && (props.mode === "query" || props.mode === "create" || props.mode === "update")) { |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
}; |
||||
|
//
|
||||
|
const getProp = (prop) => { |
||||
|
return prop; |
||||
|
}; |
||||
|
//
|
||||
|
const getError = (prop) => { |
||||
|
return props.errors[prop]; |
||||
|
}; |
||||
|
//
|
||||
|
const getRules = (parentSchema, property, data) => { |
||||
|
if (props.mode === "query" || props.mode === "details" || !property.rules) { |
||||
|
return null; |
||||
|
} |
||||
|
const rules = [...(Array.isArray(property.rules) ? property.rules : [property.rules])].map((o) => |
||||
|
JSON.parse(JSON.stringify(o)) |
||||
|
); |
||||
|
Object.values(rules).forEach((rule) => { |
||||
|
rule.data = data; |
||||
|
rule.schema = parentSchema; |
||||
|
rule.title = rule.title ?? property.title; |
||||
|
rule.type = property.type; |
||||
|
if (rule.validator) { |
||||
|
rule.validator = validators[rule.validator]; |
||||
|
} |
||||
|
if (!rule.message) { |
||||
|
if (rule.required) { |
||||
|
rule.message = format(schema.messages.required, property.title); |
||||
|
} else if (rule.pattern) { |
||||
|
rule.message = format(schema.messages.pattern, property.title); |
||||
|
} else if (property.type === "string" || property.type === "number" || property.type === "array") { |
||||
|
if (rule.len) { |
||||
|
rule.message = format(schema.messages[property.type].len, property.title, rule.len); |
||||
|
} else if (rule.min) { |
||||
|
rule.message = format(schema.messages[property.type].min, property.title, rule.min); |
||||
|
} else if (rule.max) { |
||||
|
rule.message = format(schema.messages[property.type].max, property.title, rule.max); |
||||
|
} else if (rule.range) { |
||||
|
rule.message = format(schema.messages[property.type].range, property.title, rule.range); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
return rules; |
||||
|
}; |
||||
|
/*end*/ |
||||
|
return { |
||||
|
model, |
||||
|
showItem, |
||||
|
getProp, |
||||
|
getError, |
||||
|
getRules, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,75 @@ |
|||||
|
import html from "html"; |
||||
|
import { ref, reactive, watch } from "vue"; |
||||
|
import AppFormItem from "./form-item.js"; |
||||
|
|
||||
|
export default { |
||||
|
components: { AppFormItem }, |
||||
|
name: "AppForm", |
||||
|
template: html`<el-form ref="formRef" :model="model" label-width="auto">
|
||||
|
<template v-for="(value, prop) in schema.properties"> |
||||
|
<app-form-item |
||||
|
:parentSchema="schema" |
||||
|
:schema="value" |
||||
|
v-model="model" |
||||
|
:prop="prop" |
||||
|
:mode="mode" |
||||
|
:errors="errors" |
||||
|
/> |
||||
|
</template> |
||||
|
<slot name="items"></slot> |
||||
|
<el-form-item v-if="!hideButton"> |
||||
|
<template #label></template> |
||||
|
<el-button type="primary" @click="submit" :disabled="loading"><slot>$t('confirm')</slot></el-button> |
||||
|
</el-form-item> |
||||
|
</el-form>`, |
||||
|
props: ["modelValue", "schema", "action", "hideButton", "isQueryForm", "mode"], |
||||
|
emits: ["update:modelValue", "submit"], |
||||
|
setup(props, context) { |
||||
|
// init
|
||||
|
const model = reactive(props.modelValue); |
||||
|
watch(model, (value) => { |
||||
|
context.emit("update:modelValue", value); |
||||
|
}); |
||||
|
// ref
|
||||
|
const formRef = ref(null); |
||||
|
const loading = ref(false); |
||||
|
//
|
||||
|
const errors = ref({}); |
||||
|
// reset
|
||||
|
const reset = () => { |
||||
|
formRef.value.resetFields(); |
||||
|
}; |
||||
|
// validate
|
||||
|
const validate = async () => { |
||||
|
return formRef.value.validate(); |
||||
|
}; |
||||
|
// submit
|
||||
|
const submit = async () => { |
||||
|
try { |
||||
|
//const valid = await validate();
|
||||
|
//if (valid) {
|
||||
|
loading.value = true; |
||||
|
context.emit("submit", (serverErrors) => { |
||||
|
if (serverErrors) { |
||||
|
errors.value = serverErrors; |
||||
|
} |
||||
|
}); |
||||
|
//}
|
||||
|
} catch (error) { |
||||
|
console.error(error); |
||||
|
} finally { |
||||
|
loading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
// expose
|
||||
|
context.expose({ validate, reset }); |
||||
|
return { |
||||
|
model, |
||||
|
formRef, |
||||
|
loading, |
||||
|
errors, |
||||
|
reset, |
||||
|
submit, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,34 @@ |
|||||
|
import { onMounted, ref } from "vue"; |
||||
|
|
||||
|
const template = `<component v-if="name.indexOf('ep-')===0" :is="name" /> <v-else g v-html="svg" /> `; |
||||
|
|
||||
|
export default { |
||||
|
props: { |
||||
|
name: { |
||||
|
default: "file", |
||||
|
}, |
||||
|
}, |
||||
|
template, |
||||
|
setup(props) { |
||||
|
const svg = ref(""); |
||||
|
onMounted(async () => { |
||||
|
if (props.name.indexOf("ep-") !== 0) { |
||||
|
try { |
||||
|
const response = await fetch(`./assets/icons/${props.name}.svg`); |
||||
|
if (response.ok && response.status === 200) { |
||||
|
svg.value = await response.text(); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error(error); |
||||
|
} |
||||
|
if (!svg.value) { |
||||
|
const response = await fetch("./assets/icons/file.svg"); |
||||
|
svg.value = await response.text(); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
return { |
||||
|
svg, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,390 @@ |
|||||
|
import html, { getProp } from "html"; |
||||
|
import AppForm from "../form/index.js"; |
||||
|
import { get, post } from "../../request/index.js"; |
||||
|
import { ref, reactive } from "vue"; |
||||
|
import { useRoute } from "vue-router"; |
||||
|
import { useI18n } from "vue-i18n"; |
||||
|
import SvgIcon from "../../components/icon/index.js"; |
||||
|
import { schemaToModel } from "../../utils/index.js"; |
||||
|
import qs from "../../lib/qs/shim.js"; |
||||
|
import AppFormInput from "../form/form-input.js"; |
||||
|
import VueOfficeExcel from "@vue-office/excel"; |
||||
|
import { camelCase, capitalize } from "lodash"; |
||||
|
|
||||
|
export default { |
||||
|
components: { AppForm, SvgIcon, AppFormInput, VueOfficeExcel }, |
||||
|
template: html` |
||||
|
<el-row> |
||||
|
<el-col> |
||||
|
<app-form |
||||
|
inline |
||||
|
mode="query" |
||||
|
label-position="left" |
||||
|
:schema="queryFromSchema" |
||||
|
v-model="data.query" |
||||
|
@submit="load" |
||||
|
:hideButton="true" |
||||
|
:isQueryForm="true" |
||||
|
/> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row style="padding-bottom:20px;"> |
||||
|
<el-col> |
||||
|
<template v-for="item in $route.meta.buttons"> |
||||
|
<el-button |
||||
|
:class="item.meta.htmlClass??'el-button--primary'" |
||||
|
v-if="item.meta.isTop" |
||||
|
@click="click(item,selectedRows)" |
||||
|
> |
||||
|
<el-icon v-if="item.meta.icon"><svg-icon :name="item.meta.icon" /></el-icon> |
||||
|
<span>{{item.meta.title}}</span> |
||||
|
</el-button> |
||||
|
</template> |
||||
|
<slot name="tableButtons" :rows="selectedRows"></slot> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row> |
||||
|
<el-col> |
||||
|
<el-scrollbar> |
||||
|
<el-table |
||||
|
ref="tableRef" |
||||
|
v-loading="tableLoading" |
||||
|
row-key="id" |
||||
|
table-layout="auto" |
||||
|
border |
||||
|
fit |
||||
|
:data="data.items" |
||||
|
@selection-change="handleSelectionChange" |
||||
|
@sort-change="sortChange" |
||||
|
:header-cell-class-name="getClass" |
||||
|
v-if="data.items" |
||||
|
> |
||||
|
<el-table-column fixed="left" type="selection" /> |
||||
|
<el-table-column type="index" :label="$t('rowIndex')"> |
||||
|
<template #default="scope"> {{ (data.pageIndex - 1) * data.pageSize + scope.$index + 1 }} </template> |
||||
|
</el-table-column> |
||||
|
<template v-for="(item,key) in tableSchema.items.properties"> |
||||
|
<template v-if="key==='properties'"> |
||||
|
<el-table-column :label="subKey" v-for="(subItem,subKey) in item.properties"> |
||||
|
<template #default="scope">{{ scope.row[key][subKey] }} </template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
<template v-else-if="item.navigation"> |
||||
|
<el-table-column :prop="key" :label="item.title"> |
||||
|
<template #default="scope">{{getProp(scope.row,item.navigation)}}</template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<template v-if="showColumn(item,key)"> |
||||
|
<el-table-column :prop="key" sortable="custom" :sort-orders="['descending', 'ascending', null]"> |
||||
|
<template #header="scope">{{item.title}}</template> |
||||
|
<template #default="scope"> |
||||
|
<app-form-input :isReadOnly="true" :schema="item" :prop="key" v-model="scope.row" /> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
</template> |
||||
|
</template> |
||||
|
<slot name="columns"></slot> |
||||
|
<el-table-column fixed="right"> |
||||
|
<template #header> |
||||
|
<el-button @click="filterDrawer = true"> |
||||
|
{{$t('operations')}} |
||||
|
<el-icon class="el-icon--right"><ep-filter /></el-icon> |
||||
|
</el-button> |
||||
|
</template> |
||||
|
<template #default="scope"> |
||||
|
<div class="flex"> |
||||
|
<template v-for="item in $route.meta.buttons"> |
||||
|
<el-button |
||||
|
:class="item.meta.htmlClass??'el-button--primary'" |
||||
|
v-if="!item.meta.isTop" |
||||
|
@click="click(item,[scope.row])" |
||||
|
> |
||||
|
<el-icon v-if="item.meta.icon"><svg-icon :name="item.meta.icon" /></el-icon> |
||||
|
<span>{{item.meta.title}}</span> |
||||
|
</el-button> |
||||
|
</template> |
||||
|
<slot name="rowButtons" :rows="[scope.row]"></slot> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</el-scrollbar> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row> |
||||
|
<el-col> |
||||
|
<el-pagination |
||||
|
v-if="data.items&&data.pageSize<data.totalCount" |
||||
|
v-model:currentPage="data.pageIndex" |
||||
|
v-model:page-size="data.pageSize" |
||||
|
:total="data.totalCount" |
||||
|
:page-sizes="[20, 50, 100]" |
||||
|
class="justify-end" |
||||
|
:background="true" |
||||
|
layout="total, sizes, prev, pager, next, jumper" |
||||
|
@size-change="onPageSizeChange" |
||||
|
@current-change="onPageIndexChange" |
||||
|
style="margin-top:20px" |
||||
|
/> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-drawer v-model="filterDrawer" destroy-on-close @close="tableRef.doLayout()"> |
||||
|
<template #header> <span class="el-dialog__title"> {{$t('filter')}} </span> </template> |
||||
|
<el-scrollbar> |
||||
|
<el-row> |
||||
|
<el-col style="max-height:calc(100vh - 180px);"> |
||||
|
<el-form inline> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="columns.forEach(o=>o.checked=true)"> {{$t('selectAll')}} </el-button> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="columns.forEach(o=>o.checked=!o.checked)"> |
||||
|
{{$t('selectInverse')}} |
||||
|
</el-button> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-for="item in columns"> |
||||
|
<el-checkbox v-model="item.checked" :label="item.title" size="large" /> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-scrollbar> |
||||
|
|
||||
|
<template #footer> |
||||
|
<span class="dialog-footer"> |
||||
|
<el-button type="primary" @click="filterDrawer=false"> {{$t('confirm')}} </el-button> |
||||
|
</span> |
||||
|
</template> |
||||
|
</el-drawer> |
||||
|
<el-dialog v-model="dialogVisible" align-center destroy-on-close width="700"> |
||||
|
<template #header> <span class="el-dialog__title"> {{editFormTitle}} </span> </template> |
||||
|
<el-row> |
||||
|
<el-col style="max-height:calc(100vh - 180px );"> |
||||
|
<el-scrollbar> |
||||
|
<app-form |
||||
|
v-loading="editFormloading" |
||||
|
:disabled="editFormMode==='details'" |
||||
|
:mode="editFormMode" |
||||
|
ref="editFormRef" |
||||
|
inline |
||||
|
label-position="left" |
||||
|
:hideButton="true" |
||||
|
:schema="editFormSchema" |
||||
|
v-model="editFormModel" |
||||
|
v-if="editFormMode!=='import'" |
||||
|
/> |
||||
|
</el-scrollbar> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<template #footer> |
||||
|
<span class="dialog-footer"> |
||||
|
<el-button type="primary" @click="submit"> {{$t('confirm')}} </el-button> |
||||
|
</span> |
||||
|
</template> |
||||
|
</el-dialog> |
||||
|
`,
|
||||
|
props: ["modelValue"], |
||||
|
emits: ["command"], |
||||
|
async setup(props, context) { |
||||
|
const tableRef = ref(null); |
||||
|
const columns = ref([]); |
||||
|
const filterDrawer = ref(false); |
||||
|
const tableLoading = ref(false); |
||||
|
const selectedRows = ref([]); |
||||
|
const dialogVisible = ref(false); |
||||
|
const route = useRoute(); |
||||
|
const { t } = useI18n(); |
||||
|
const baseUrl = `${route.meta.path}`.substring(1); |
||||
|
const indexUrl = `${baseUrl}/index`; |
||||
|
const vm = (await get(indexUrl)).data; |
||||
|
const schema = vm.schema; |
||||
|
const data = reactive(vm.model ?? schemaToModel(schema)); |
||||
|
const sortColumns = ref(new Map()); |
||||
|
const getSortModel = (model) => { |
||||
|
const orderBy = model.orderBy |
||||
|
.split(",") |
||||
|
.map((o) => o.trim()) |
||||
|
.filter((o) => o) |
||||
|
.map((o) => ({ |
||||
|
prop: camelCase(o.split(" ")[0]), |
||||
|
order: (o.split(" ").filter((o) => o)[1] ?? "asc") + "ending", |
||||
|
})) |
||||
|
.forEach((o) => sortColumns.value.set(o.prop, o.order)); |
||||
|
return orderBy; |
||||
|
}; |
||||
|
const sortModel = reactive(getSortModel(data)); |
||||
|
const getClass = ({ row, column }) => { |
||||
|
if (column.property) { |
||||
|
column.order = sortColumns.value.get(column.property); |
||||
|
} |
||||
|
}; |
||||
|
const sortChange = ({ column, prop, order }) => { |
||||
|
if (order === null) { |
||||
|
sortColumns.value.delete(prop); |
||||
|
} else { |
||||
|
sortColumns.value.set(prop, order); |
||||
|
} |
||||
|
data.orderBy = Array.from(sortColumns.value) |
||||
|
.map((o) => capitalize(o[0]) + (o[1] === "ascending" ? "" : ` DESC`)) |
||||
|
.join(","); |
||||
|
load(indexUrl); |
||||
|
}; |
||||
|
const getColumns = (schema) => { |
||||
|
Object.keys(schema.properties).forEach((propertyName) => { |
||||
|
const property = schema.properties[propertyName]; |
||||
|
if (property.type !== "object" && property.type !== "array" && !property.hidden) { |
||||
|
columns.value.push({ name: propertyName, title: property.title, checked: true }); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
const showColumn = (item, prop) => { |
||||
|
return ( |
||||
|
item.type !== "object" && |
||||
|
item.type !== "array" && |
||||
|
!item.hidden && |
||||
|
columns.value.findIndex((o) => o.name === prop && o.checked) >= 0 |
||||
|
); |
||||
|
}; |
||||
|
getColumns(schema.properties.query); |
||||
|
const queryFromSchema = schema.properties.query; |
||||
|
const tableSchema = schema.properties.items; |
||||
|
const editFormRef = ref(null); |
||||
|
const editFormloading = ref(false); |
||||
|
const editFormMode = ref(null); |
||||
|
const editFormTitle = ref(""); |
||||
|
const editFormSchema = reactive({}); |
||||
|
const editFormModel = reactive({}); |
||||
|
const exportModel = reactive({ |
||||
|
includeAll: false, |
||||
|
includeDeleted: false, |
||||
|
}); |
||||
|
const handleSelectionChange = (rows) => (selectedRows.value = rows); |
||||
|
const load = async (url) => { |
||||
|
tableLoading.value = true; |
||||
|
try { |
||||
|
const postData = JSON.parse(JSON.stringify(data)); |
||||
|
delete postData["Id"]; |
||||
|
delete postData["items"]; |
||||
|
Object.assign(data, (await post(url, postData)).data); |
||||
|
} catch (error) { |
||||
|
console.log(error); |
||||
|
} finally { |
||||
|
tableLoading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
const onPageIndexChange = () => load(indexUrl); |
||||
|
const onPageSizeChange = () => load(indexUrl); |
||||
|
const click = async (item, rows) => { |
||||
|
editFormMode.value = item.path; |
||||
|
context.emit("command", item, rows); |
||||
|
if (item.path === "index") { |
||||
|
//list
|
||||
|
await load(indexUrl); |
||||
|
} else if (item.path === "details") { |
||||
|
//details
|
||||
|
const detailsUrl = `${baseUrl}/${item.path}?${qs.stringify({ id: rows[0].id })}`; |
||||
|
Object.assign(editFormSchema, schema.properties.items.items); |
||||
|
Object.assign(editFormModel, (await post(detailsUrl)).data); |
||||
|
editFormTitle.value = `${t("details")}${schema.title}`; |
||||
|
dialogVisible.value = true; |
||||
|
} else if (item.path === "create") { |
||||
|
//create
|
||||
|
const url = `${baseUrl}/${item.path}`; |
||||
|
const vm = (await get(url)).data; |
||||
|
Object.assign(editFormSchema, vm.schema); |
||||
|
Object.assign(editFormModel, vm.model); |
||||
|
editFormTitle.value = `${t("create")}${schema.title}`; |
||||
|
dialogVisible.value = true; |
||||
|
} else if (item.path === "update") { |
||||
|
//update
|
||||
|
const url = `${baseUrl}/${item.path}`; |
||||
|
const vm = (await get(url, { id: rows[0].id })).data; |
||||
|
Object.assign(editFormSchema, vm.schema); |
||||
|
Object.assign(editFormModel, vm.model); |
||||
|
editFormTitle.value = `${t("update")}${schema.title}`; |
||||
|
dialogVisible.value = true; |
||||
|
} else if (item.path === "delete") { |
||||
|
//delete
|
||||
|
if (!rows.length) { |
||||
|
return; |
||||
|
} |
||||
|
const url = `${baseUrl}/${item.path}`; |
||||
|
await post( |
||||
|
url, |
||||
|
rows.map((o) => o.id) |
||||
|
); |
||||
|
await load(indexUrl); |
||||
|
} else if (item.path === "export") { |
||||
|
//export
|
||||
|
const url = `${baseUrl}/${item.path}`; |
||||
|
const exportUrl = `${url}?${qs.stringify(exportModel)}`; |
||||
|
await load(exportUrl); |
||||
|
} else if (item.path === "import") { |
||||
|
//import
|
||||
|
const url = `${baseUrl}/${item.path}`; |
||||
|
editFormTitle.value = `${t("import")}${schema.title}`; |
||||
|
dialogVisible.value = true; |
||||
|
} |
||||
|
}; |
||||
|
const submit = async () => { |
||||
|
if (editFormMode.value === "create" || editFormMode.value === "update") { |
||||
|
try { |
||||
|
const valid = await editFormRef.value.validate(); |
||||
|
if (valid) { |
||||
|
editFormloading.value = true; |
||||
|
const url = `${baseUrl}/${editFormMode.value}`; |
||||
|
const result = await post(url, editFormModel); |
||||
|
if (result.errors) { |
||||
|
model.errors = result.errors; //??
|
||||
|
} else { |
||||
|
await load(indexUrl); |
||||
|
editFormMode.value = null; |
||||
|
dialogVisible.value = false; |
||||
|
} |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error(error); |
||||
|
} finally { |
||||
|
editFormloading.value = false; |
||||
|
} |
||||
|
} else if (editFormMode.value === "details") { |
||||
|
load(indexUrl); |
||||
|
editFormMode.value = null; |
||||
|
dialogVisible.value = false; |
||||
|
} |
||||
|
}; |
||||
|
await load(indexUrl); |
||||
|
return { |
||||
|
route, |
||||
|
tableRef, |
||||
|
tableLoading, |
||||
|
columns, |
||||
|
showColumn, |
||||
|
filterDrawer, |
||||
|
dialogVisible, |
||||
|
selectedRows, |
||||
|
schema, |
||||
|
queryFromSchema, |
||||
|
tableSchema, |
||||
|
data, |
||||
|
sortModel, |
||||
|
getClass, |
||||
|
sortChange, |
||||
|
getProp, |
||||
|
editFormRef, |
||||
|
editFormMode, |
||||
|
editFormTitle, |
||||
|
editFormSchema, |
||||
|
editFormModel, |
||||
|
exportModel, |
||||
|
onPageSizeChange, |
||||
|
onPageIndexChange, |
||||
|
handleSelectionChange, |
||||
|
load, |
||||
|
click, |
||||
|
submit, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,41 @@ |
|||||
|
import { ref, onMounted } from 'vue'; |
||||
|
import { marked, setOptions } from '../../lib/marked/marked.esm.js'; |
||||
|
import mermaid from '../../lib/mermaid/mermaid.esm.min.mjs'; |
||||
|
import hljs from '../../lib/highlightjs/highlight.min.js'; |
||||
|
|
||||
|
export default { |
||||
|
template: `<div ref="tplRef"><div class="source" style="display:none;"><slot /></div><div class="markdown-body"></div></template>`, |
||||
|
props: { |
||||
|
name: { |
||||
|
default: null |
||||
|
} |
||||
|
}, |
||||
|
setup(props) { |
||||
|
const tplRef = ref(null); |
||||
|
mermaid.initialize({ startOnLoad: false }); |
||||
|
let id = 0; |
||||
|
onMounted(async () => { |
||||
|
setOptions({ |
||||
|
highlight: function (code, lang) { |
||||
|
if (lang === 'mermaid') { |
||||
|
return mermaid.mermaidAPI.render(`mermaid${id++}`, code, undefined); |
||||
|
} else { |
||||
|
const language = hljs.getLanguage(lang) ? lang : 'plaintext'; |
||||
|
return hljs.highlight(code, { language }).value; |
||||
|
} |
||||
|
}, |
||||
|
langPrefix: 'hljs language-', |
||||
|
}); |
||||
|
let mdText = tplRef.value.querySelector('.source').innerText; |
||||
|
if (props.name !== null) { |
||||
|
const response = await fetch(`./assets/docs/${props.name}.md`); |
||||
|
mdText = await response.text(); |
||||
|
} |
||||
|
tplRef.value.querySelector('.markdown-body').innerHTML = marked(mdText); |
||||
|
tplRef.value.querySelector('.source').remove(); |
||||
|
}); |
||||
|
return { |
||||
|
tplRef |
||||
|
}; |
||||
|
} |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
export default { |
||||
|
enableLocale: false, |
||||
|
baseURL: "http://dev.ccwin-in.com:10582/api", |
||||
|
}; |
After Width: | Height: | Size: 5.3 KiB |
@ -0,0 +1,72 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
|
||||
|
<head> |
||||
|
<meta charset="utf-8" /> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
|
<base href="/" /> |
||||
|
<style> |
||||
|
@keyframes loading-rotate { |
||||
|
to { |
||||
|
transform: rotate(360deg) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#loading { |
||||
|
display: none; |
||||
|
animation: loading-rotate 2s linear infinite; |
||||
|
} |
||||
|
|
||||
|
#loading.loading { |
||||
|
display: block; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
margin: auto; |
||||
|
width: 50px; |
||||
|
height: 50px; |
||||
|
} |
||||
|
</style> |
||||
|
<link rel="stylesheet" href="./main.css" /> |
||||
|
<title></title> |
||||
|
</head> |
||||
|
|
||||
|
<body> |
||||
|
<div id="app"></div> |
||||
|
<img src="./assets/icons/loading.svg" id="loading" class="loading"> |
||||
|
<script type="importmap"> |
||||
|
{ |
||||
|
"imports": { |
||||
|
"html":"./utils/index.js", |
||||
|
"detect-it":"./lib/detect-it/detect-it.esm.js", |
||||
|
"lodash":"./lib/lodash/lodash.esm.js", |
||||
|
"vue": "./lib/vue/vue.esm-browser.js", |
||||
|
"vue-router": "./lib/vue-router/vue-router.esm-browser.js", |
||||
|
"vue-i18n":"./lib/vue-i18n/vue-i18n.esm-browser.prod.js", |
||||
|
"pinia": "./lib/pinia/pinia.esm-browser.js", |
||||
|
"pubsub-js": "./lib/pubsub-js/pubsub.esm.js", |
||||
|
"linq": "./lib/linq/linq.min.js", |
||||
|
"@microsoft/signalr": "./lib/@microsoft/signalr/signalr.esm.js", |
||||
|
"@vueuse/shared": "./lib/@vueuse/shared/index.mjs", |
||||
|
"@vueuse/core": "./lib/@vueuse/core/index.mjs", |
||||
|
"element-plus": "./lib/element-plus/index.full.min.mjs", |
||||
|
"@element-plus/icons-vue":"./lib/@element-plus/icons-vue/index.js", |
||||
|
"nprogress": "./lib/nprogress/nprogress.vite-esm.js", |
||||
|
"echarts/core": "./lib/echarts/echarts.esm.min.js", |
||||
|
"vue-echarts": "./lib/vue-echarts/index.esm.min.js", |
||||
|
"resize-detector": "./lib/resize-detector/index.js", |
||||
|
"@vue-office/excel": "./lib/@vue-office/excel/vue-office-excel.mjs", |
||||
|
"@vue/devtools-api": "./lib/@vue/devtools-api/shim.js", |
||||
|
"vue-demi": "./lib/vue-demi/shim.js" |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<script> |
||||
|
window.process = { env: { NODE_ENV: 'production' } }; |
||||
|
</script> |
||||
|
<script type="module" src="./main.js"></script> |
||||
|
</body> |
||||
|
|
||||
|
</html> |
@ -0,0 +1,12 @@ |
|||||
|
import html from "html"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
|
||||
|
export default { |
||||
|
template: html`<div class="footer flex items-center justify-center">{{$t('copyright')}}</div>`, |
||||
|
setup() { |
||||
|
const appStore = useAppStore(); |
||||
|
return { |
||||
|
appStore, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,168 @@ |
|||||
|
import html from "html"; |
||||
|
import { ref, onMounted, onUnmounted } from "vue"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import SvgIcon from "../components/icon/index.js"; |
||||
|
import LayoutLogo from "./logo.js"; |
||||
|
import { useDark, useFullscreen, useToggle } from "@vueuse/core"; |
||||
|
import { ElMessage, ElMessageBox } from "element-plus"; |
||||
|
import { useI18n } from "vue-i18n"; |
||||
|
import { logout } from "../api/user.js"; |
||||
|
import LayoutLocale from "./locale.js"; |
||||
|
import router from "../router/index.js"; |
||||
|
import { treeToList } from "../utils/index.js"; |
||||
|
|
||||
|
export default { |
||||
|
components: { SvgIcon, LayoutLogo, LayoutLocale, ElMessage, ElMessageBox }, |
||||
|
template: html` |
||||
|
<div class="flex items-center justify-between"> |
||||
|
<div class="flex items-center justify-center"> |
||||
|
<layout-logo /> |
||||
|
<el-icon @click="toggleMenuCollapse" class="cursor-pointer"> |
||||
|
<svg-icon name="unfold" v-if="appStore.isMenuCollapse" /> |
||||
|
<svg-icon name="fold" v-else /> |
||||
|
</el-icon> |
||||
|
</div> |
||||
|
<div class="flex"> |
||||
|
<el-space> |
||||
|
<el-icon class="cursor-pointer" @click="clickSearch"> |
||||
|
<ep-search /> |
||||
|
</el-icon> |
||||
|
<el-select |
||||
|
ref="searchRef" |
||||
|
placeholder="search" |
||||
|
v-show="showSearch" |
||||
|
@blur="hideSearch" |
||||
|
filterable |
||||
|
remote |
||||
|
:remote-method="searchMenu" |
||||
|
v-model="searchModel" |
||||
|
:loading="searchLoading" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in searchOptions" |
||||
|
:key="item.meta.path" |
||||
|
:value="item.meta.path" |
||||
|
:label="item.meta.fullName" |
||||
|
@click="searchChange(item)" |
||||
|
/> |
||||
|
</el-select> |
||||
|
<el-icon v-model="isDark" @click="toggleDark()" :size="18" class="cursor-pointer"> |
||||
|
<ep-sunny v-if="isDark" /> |
||||
|
<ep-moon v-else /> |
||||
|
</el-icon> |
||||
|
<el-icon @click="toggleFullscreen" :size="18" class="cursor-pointer"> |
||||
|
<svg-icon name="fullscreen-exit" v-if="isFullscreen" /> |
||||
|
<svg-icon name="fullscreen" v-else /> |
||||
|
</el-icon> |
||||
|
<el-dropdown class="cursor-pointer" v-if="appStore.token"> |
||||
|
<span class="el-dropdown-link flex"> |
||||
|
<el-icon class="el-icon--left" :size="18"> |
||||
|
<img v-if="appStore.user.avatar" /> |
||||
|
<ep-user v-else /> |
||||
|
</el-icon> |
||||
|
{{ appStore.user.name }} |
||||
|
<el-icon class="el-icon--right"> |
||||
|
<ep-arrow-down /> |
||||
|
</el-icon> |
||||
|
</span> |
||||
|
<template #dropdown> |
||||
|
<el-dropdown-menu> |
||||
|
<el-dropdown-item> |
||||
|
<router-link to="/account"> |
||||
|
<el-icon> <ep-user /> </el-icon>{{$t('userCenter')}} |
||||
|
</router-link> |
||||
|
</el-dropdown-item> |
||||
|
<el-dropdown-item divided @click="confirmLogout"> |
||||
|
<el-icon> <ep-switch-button /> </el-icon>{{$t('logout')}} |
||||
|
</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</template> |
||||
|
</el-dropdown> |
||||
|
<el-link type="info" v-else> |
||||
|
<router-link to="/register"> {{$t('register')}}</router-link> |
||||
|
</el-link> |
||||
|
<layout-locale /> |
||||
|
</el-space> |
||||
|
</div> |
||||
|
</div> |
||||
|
`,
|
||||
|
setup() { |
||||
|
const i18n = useI18n(); |
||||
|
const appStore = useAppStore(); |
||||
|
//
|
||||
|
const searchRef = ref(null); |
||||
|
const searchLoading = ref(false); |
||||
|
const searchModel = ref(""); |
||||
|
const searchOptions = ref([]); |
||||
|
const showSearch = ref(false); |
||||
|
const hideSearch = () => { |
||||
|
showSearch.value = false; |
||||
|
}; |
||||
|
const clickSearch = () => { |
||||
|
showSearch.value = !showSearch.value; |
||||
|
if (showSearch.value) { |
||||
|
searchRef.value.focus(); |
||||
|
} |
||||
|
}; |
||||
|
const searchMenu = (query) => { |
||||
|
if (query) { |
||||
|
try { |
||||
|
searchLoading.value = true; |
||||
|
const menus = treeToList(router.getRoutes().find((o) => o.path === "/").children); |
||||
|
searchOptions.value = menus |
||||
|
.filter((o) => !o.children || o.children.length === 0) |
||||
|
.filter((o) => o.meta.fullName.indexOf(query) > -1); |
||||
|
} finally { |
||||
|
searchLoading.value = false; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
const searchChange = (route) => { |
||||
|
if (!route.meta.isExternal) { |
||||
|
router.push(route.meta.path); |
||||
|
searchModel.value = ""; |
||||
|
searchOptions.value = []; |
||||
|
showSearch.value = false; |
||||
|
} else { |
||||
|
window.open(route.path); |
||||
|
} |
||||
|
}; |
||||
|
//
|
||||
|
const isDark = useDark(); |
||||
|
const toggleDark = useToggle(isDark); |
||||
|
const toggleMenuCollapse = () => (appStore.isMenuCollapse = !appStore.isMenuCollapse); |
||||
|
//
|
||||
|
const { isFullscreen, toggle: toggleFullscreen } = useFullscreen(document.documentElement); |
||||
|
const confirmLogout = async () => { |
||||
|
try { |
||||
|
await ElMessageBox.confirm(i18n.t("confirmLogout"), i18n.t("tip"), { type: "warning" }); |
||||
|
logout(); |
||||
|
} catch (error) { |
||||
|
if (error === "cancel") { |
||||
|
ElMessage({ |
||||
|
type: "info", |
||||
|
message: i18n.t("cancel"), |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
return { |
||||
|
appStore, |
||||
|
showSearch, |
||||
|
hideSearch, |
||||
|
clickSearch, |
||||
|
searchRef, |
||||
|
searchLoading, |
||||
|
searchModel, |
||||
|
searchOptions, |
||||
|
searchMenu, |
||||
|
searchChange, |
||||
|
isDark, |
||||
|
toggleDark, |
||||
|
toggleMenuCollapse, |
||||
|
isFullscreen, |
||||
|
toggleFullscreen, |
||||
|
confirmLogout, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,57 @@ |
|||||
|
import html from "html"; |
||||
|
import LayoutHeader from "./header.js"; |
||||
|
import LayoutMenu from "./menu.js"; |
||||
|
import LayoutTabs from "./tabs.js"; |
||||
|
import LayoutFooter from "./footer.js"; |
||||
|
import Icon from "../components/icon/index.js"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import { computed } from "vue"; |
||||
|
|
||||
|
export default { |
||||
|
components: { Icon, LayoutHeader, LayoutMenu, LayoutTabs, LayoutFooter }, |
||||
|
template: html`<el-container>
|
||||
|
<el-header><layout-header /></el-header> |
||||
|
<el-container> |
||||
|
<el-aside width="auto"> |
||||
|
<el-scrollbar><layout-menu /></el-scrollbar> |
||||
|
</el-aside> |
||||
|
<el-container class="backtop"> |
||||
|
<el-scrollbar> |
||||
|
<layout-tabs /> |
||||
|
<el-main> |
||||
|
<router-view v-if="!isRefreshing" v-slot="{ Component, route }"> |
||||
|
<component |
||||
|
:is="Component" |
||||
|
v-if="!appStore.isUseTabsRouter || !route.meta?.cached" |
||||
|
:key="$route.fullPath" |
||||
|
/> |
||||
|
<keep-alive> |
||||
|
<component |
||||
|
:is="Component" |
||||
|
v-if="appStore.isUseTabsRouter && route.meta?.cached" |
||||
|
:key="route.fullPath" |
||||
|
/> |
||||
|
</keep-alive> |
||||
|
</router-view> |
||||
|
</el-main> |
||||
|
<el-footer> |
||||
|
<layout-footer /> |
||||
|
</el-footer> |
||||
|
<el-backtop target=".backtop > .el-scrollbar > .el-scrollbar__wrap" /> |
||||
|
</el-scrollbar> |
||||
|
</el-container> |
||||
|
</el-container> |
||||
|
</el-container>`, |
||||
|
setup() { |
||||
|
const appStore = useAppStore(); |
||||
|
const isRefreshing = computed(() => appStore.isRefreshing); |
||||
|
const path = computed(() => useRoute().matched[0].path); |
||||
|
const items = computed(() => useRoute().matched[0].children); |
||||
|
return { |
||||
|
appStore, |
||||
|
isRefreshing, |
||||
|
path, |
||||
|
items, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,36 @@ |
|||||
|
import html from "html"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import { useI18n } from "vue-i18n"; |
||||
|
import Icon from "../components/icon/index.js"; |
||||
|
export default { |
||||
|
components: { Icon }, |
||||
|
template: html`<el-dropdown class="cursor-pointer" v-if="appStore.settings.enableLocale">
|
||||
|
<span class="el-dropdown-link flex"> |
||||
|
<el-icon :size="18"> |
||||
|
<icon name="lang" /> |
||||
|
</el-icon> |
||||
|
</span> |
||||
|
<template #dropdown> |
||||
|
<el-dropdown-menu> |
||||
|
<el-dropdown-item v-for="locale in $i18n.availableLocales" @click="changeLocale(locale)"> |
||||
|
{{appStore.localization.options.find(o=>o.value===locale).label}} |
||||
|
<el-icon class="el-icon--right" v-if="locale===$i18n.locale"> |
||||
|
<ep-select /> |
||||
|
</el-icon> |
||||
|
</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</template> |
||||
|
</el-dropdown>`, |
||||
|
setup() { |
||||
|
const appStore = useAppStore(); |
||||
|
const i18n = useI18n(); |
||||
|
const changeLocale = (locale) => { |
||||
|
appStore.localization.locale = locale; |
||||
|
i18n.locale.value = locale; |
||||
|
}; |
||||
|
return { |
||||
|
appStore, |
||||
|
changeLocale, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,17 @@ |
|||||
|
import html from "html"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
|
||||
|
export default { |
||||
|
template: html`<router-link to="/" class="logo">
|
||||
|
<div class="flex h-full items-center"> |
||||
|
<img src="/assets/logo.svg" /> |
||||
|
<h1 v-if="!appStore.isMenuCollapse">{{$t('application')}}</h1> |
||||
|
</div> |
||||
|
</router-link>`, |
||||
|
setup() { |
||||
|
const appStore = useAppStore(); |
||||
|
return { |
||||
|
appStore, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,55 @@ |
|||||
|
import html from "html"; |
||||
|
import { reactive, watch } from "vue"; |
||||
|
import Icon from "../components/icon/index.js"; |
||||
|
import { useRouter } from "vue-router"; |
||||
|
|
||||
|
export default { |
||||
|
name: "menuItem", |
||||
|
components: { Icon }, |
||||
|
template: html`<el-sub-menu :index="modelValue.meta.path" v-if="modelValue.children">
|
||||
|
<template #title> |
||||
|
<el-icon><icon :name="modelValue.meta.icon??'folder'" /></el-icon> |
||||
|
<span>{{modelValue.meta.title}}</span> |
||||
|
</template> |
||||
|
<menu-item v-for="item in modelValue.children" v-model="item" /> |
||||
|
</el-sub-menu> |
||||
|
<el-menu-item |
||||
|
v-else |
||||
|
:index="modelValue.meta.isExternal?null:modelValue.meta.path" |
||||
|
@click.native="click(modelValue)" |
||||
|
> |
||||
|
<el-icon><icon :name="modelValue.meta.icon??file" /></el-icon> |
||||
|
<template #title> |
||||
|
<span>{{modelValue.meta.title}}</span> |
||||
|
</template> |
||||
|
</el-menu-item>`, |
||||
|
props: { |
||||
|
modelValue: { |
||||
|
typeof: Object, |
||||
|
}, |
||||
|
}, |
||||
|
setup(props, context) { |
||||
|
const router = useRouter(); |
||||
|
const model = reactive(props.modelValue); |
||||
|
watch( |
||||
|
model, |
||||
|
(value) => { |
||||
|
context.emit("update:modelValue", value); |
||||
|
}, |
||||
|
{ deep: true } |
||||
|
); |
||||
|
//
|
||||
|
const click = (route) => { |
||||
|
if (!route.meta.isExternal) { |
||||
|
router.push(route.meta.path); |
||||
|
} else { |
||||
|
window.open(route.path); |
||||
|
} |
||||
|
}; |
||||
|
//
|
||||
|
return { |
||||
|
model, |
||||
|
click, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,24 @@ |
|||||
|
import html from "html"; |
||||
|
import Icon from "../components/icon/index.js"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import MenuItem from "./menu-item.js"; |
||||
|
import router from "../router/index.js"; |
||||
|
|
||||
|
export default { |
||||
|
components: { Icon, MenuItem }, |
||||
|
template: html`<el-menu
|
||||
|
:collapse="appStore.isMenuCollapse" |
||||
|
:collapse-transition="false" |
||||
|
:default-active="$route.fullPath" |
||||
|
> |
||||
|
<menu-item v-for="item in menus" v-model="item" /> |
||||
|
</el-menu>`, |
||||
|
setup() { |
||||
|
const appStore = useAppStore(); |
||||
|
const menus = router.getRoutes().find((o) => o.name === "layout").children; |
||||
|
return { |
||||
|
appStore, |
||||
|
menus, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,171 @@ |
|||||
|
import html from "html"; |
||||
|
import { ref, nextTick } from "vue"; |
||||
|
import { useRoute, onBeforeRouteUpdate, useRouter } from "vue-router"; |
||||
|
import Icon from "../components/icon/index.js"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import MenuItem from "./menu-item.js"; |
||||
|
|
||||
|
export default { |
||||
|
components: { Icon, MenuItem }, |
||||
|
template: html`<el-tabs
|
||||
|
v-model="model" |
||||
|
type="border-card" |
||||
|
class="router-tab" |
||||
|
@tab-remove="remove" |
||||
|
@tab-click="onClick" |
||||
|
> |
||||
|
<template v-for="(item, index) in appStore.routes" :key="item.fullPath"> |
||||
|
<el-tab-pane v-model="item.fullPath" :name="item.fullPath" :closable="appStore.routes.length > 1"> |
||||
|
<template #label> |
||||
|
<el-dropdown |
||||
|
:ref="(el) => setRef(index, el)" |
||||
|
class="h-full" |
||||
|
trigger="contextmenu" |
||||
|
@visible-change="showContextMenu(index, $event)" |
||||
|
> |
||||
|
<span class="inline-flex items-center"> |
||||
|
<el-icon><icon v-if="item.meta.icon" :name="item.meta.icon" /></el-icon> |
||||
|
{{ item.meta?.title ?? item.fullPath }} |
||||
|
</span> |
||||
|
<template #dropdown> |
||||
|
<el-dropdown-menu> |
||||
|
<el-dropdown-item @click="refresh(index)"><i-ep-refresh />刷新</el-dropdown-item> |
||||
|
<el-dropdown-item :disabled="index === 0" @click="removeLeft(index)"> |
||||
|
<i-ep-back />关闭左侧 |
||||
|
</el-dropdown-item> |
||||
|
<el-dropdown-item :disabled="index === appStore.routes.length - 1" @click="removeRight(index)"> |
||||
|
<i-ep-right />关闭右侧 |
||||
|
</el-dropdown-item> |
||||
|
<el-dropdown-item |
||||
|
:disabled="index === 0 && index === appStore.routes.length - 1" |
||||
|
@click="removeOthers(index)" |
||||
|
> |
||||
|
<i-ep-switch />关闭其他 |
||||
|
</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</template> |
||||
|
</el-dropdown> |
||||
|
</template> |
||||
|
</el-tab-pane> |
||||
|
</template> |
||||
|
</el-tabs>`, |
||||
|
styles: html` |
||||
|
<style> |
||||
|
.router-tab { |
||||
|
box-sizing: border-box; |
||||
|
height: 40px !important; |
||||
|
background-color: var(--el-fill-color-blank); |
||||
|
border-width: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.router-tab .el-tabs__item { |
||||
|
padding: 13px !important; |
||||
|
border-bottom-width: 0; |
||||
|
} |
||||
|
|
||||
|
.router-tab .el-tabs__content { |
||||
|
display: none; |
||||
|
} |
||||
|
</style> |
||||
|
`,
|
||||
|
setup() { |
||||
|
const appStore = useAppStore(); |
||||
|
const itemRefs = ref([]); |
||||
|
const currentRoute = useRoute(); |
||||
|
const router = useRouter(); |
||||
|
const model = ref(currentRoute.fullPath); |
||||
|
|
||||
|
onBeforeRouteUpdate((to) => { |
||||
|
model.value = to.fullPath; |
||||
|
}); |
||||
|
|
||||
|
const setRef = (index, el) => { |
||||
|
if (el) { |
||||
|
itemRefs.value[index] = el; |
||||
|
} else { |
||||
|
itemRefs.value.splice(index, 1); |
||||
|
} |
||||
|
}; |
||||
|
const showContextMenu = (index, show) => { |
||||
|
if (show) { |
||||
|
itemRefs.value.forEach((item, i) => { |
||||
|
if (i !== index) { |
||||
|
item?.handleClose(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const refresh = (index) => { |
||||
|
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
||||
|
const route = appStore.routes[index]; |
||||
|
if (index !== currentIndex) { |
||||
|
router.push({ path: route.fullPath }); |
||||
|
} |
||||
|
appStore.isRefreshing = true; |
||||
|
nextTick(() => { |
||||
|
appStore.isRefreshing = false; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const remove = (name) => { |
||||
|
if (appStore.routes.length > 1) { |
||||
|
const index = appStore.routes.findIndex((o) => o.fullPath === name); |
||||
|
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
||||
|
appStore.routes.splice(index, 1); |
||||
|
if (index === currentIndex) { |
||||
|
if (appStore.routes[index]) { |
||||
|
router.push(appStore.routes[index]); |
||||
|
} else { |
||||
|
router.push(appStore.routes[index - 1]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const removeLeft = (index) => { |
||||
|
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
||||
|
const route = appStore.routes[index]; |
||||
|
appStore.routes.splice(0, index); |
||||
|
if (currentIndex < index) { |
||||
|
router.push(route); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const removeRight = (index) => { |
||||
|
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
||||
|
appStore.routes.splice(index + 1, appStore.routes.length - index); |
||||
|
if (currentIndex > index) { |
||||
|
router.push(appStore.routes[index]); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const removeOthers = (index) => { |
||||
|
removeRight(index); |
||||
|
removeLeft(index); |
||||
|
if (appStore.routes[0].fullPath !== currentRoute.fullPath) { |
||||
|
router.push(appStore.routes[0]); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const onClick = (context) => { |
||||
|
if (!context.active) { |
||||
|
router.push(context.props.name); |
||||
|
} |
||||
|
}; |
||||
|
return { |
||||
|
model, |
||||
|
appStore, |
||||
|
itemRefs, |
||||
|
onBeforeRouteUpdate, |
||||
|
setRef, |
||||
|
showContextMenu, |
||||
|
refresh, |
||||
|
remove, |
||||
|
removeLeft, |
||||
|
removeRight, |
||||
|
removeOthers, |
||||
|
onClick, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,765 @@ |
|||||
|
body { |
||||
|
margin: 0; |
||||
|
} |
||||
|
.x-spreadsheet { |
||||
|
font-size: 13px; |
||||
|
line-height: normal; |
||||
|
user-select: none; |
||||
|
-moz-user-select: none; |
||||
|
font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif; |
||||
|
box-sizing: content-box; |
||||
|
background: #fff; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
} |
||||
|
.x-spreadsheet textarea { |
||||
|
font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif; |
||||
|
} |
||||
|
.x-spreadsheet-sheet { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.x-spreadsheet-table { |
||||
|
vertical-align: bottom; |
||||
|
} |
||||
|
.x-spreadsheet-tooltip { |
||||
|
font-family: inherit; |
||||
|
position: absolute; |
||||
|
padding: 5px 10px; |
||||
|
color: #fff; |
||||
|
border-radius: 1px; |
||||
|
background: #000000; |
||||
|
font-size: 12px; |
||||
|
z-index: 201; |
||||
|
} |
||||
|
.x-spreadsheet-tooltip:before { |
||||
|
pointer-events: none; |
||||
|
position: absolute; |
||||
|
left: calc(50% - 4px); |
||||
|
top: -4px; |
||||
|
content: ""; |
||||
|
width: 8px; |
||||
|
height: 8px; |
||||
|
background: inherit; |
||||
|
-webkit-transform: rotate(45deg); |
||||
|
transform: rotate(45deg); |
||||
|
z-index: 1; |
||||
|
box-shadow: 1px 1px 3px -1px rgba(0, 0, 0, 0.3); |
||||
|
} |
||||
|
.x-spreadsheet-color-palette { |
||||
|
padding: 5px; |
||||
|
} |
||||
|
.x-spreadsheet-color-palette table { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
border-collapse: separate; |
||||
|
border-spacing: 2; |
||||
|
background: #fff; |
||||
|
} |
||||
|
.x-spreadsheet-color-palette table td { |
||||
|
margin: 0; |
||||
|
cursor: pointer; |
||||
|
border: 1px solid transparent; |
||||
|
} |
||||
|
.x-spreadsheet-color-palette table td:hover { |
||||
|
border-color: #ddd; |
||||
|
} |
||||
|
.x-spreadsheet-color-palette table td .x-spreadsheet-color-palette-cell { |
||||
|
width: 16px; |
||||
|
height: 16px; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette { |
||||
|
padding: 6px; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette table { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
border-collapse: separate; |
||||
|
border-spacing: 0; |
||||
|
background: #fff; |
||||
|
table-layout: fixed; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette table td { |
||||
|
margin: 0; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left { |
||||
|
border-right: 1px solid #eee; |
||||
|
padding-right: 6px; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell { |
||||
|
width: 30px; |
||||
|
height: 30px; |
||||
|
cursor: pointer; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell:hover { |
||||
|
background-color: #eee; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right { |
||||
|
padding-left: 6px; |
||||
|
} |
||||
|
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-line-type { |
||||
|
position: relative; |
||||
|
left: 0; |
||||
|
top: -3px; |
||||
|
} |
||||
|
.x-spreadsheet-dropdown { |
||||
|
position: relative; |
||||
|
} |
||||
|
.x-spreadsheet-dropdown .x-spreadsheet-dropdown-content { |
||||
|
position: absolute; |
||||
|
z-index: 200; |
||||
|
background: #fff; |
||||
|
box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15); |
||||
|
} |
||||
|
.x-spreadsheet-dropdown.bottom-left .x-spreadsheet-dropdown-content { |
||||
|
top: calc(100% + 5px); |
||||
|
left: 0; |
||||
|
} |
||||
|
.x-spreadsheet-dropdown.bottom-right .x-spreadsheet-dropdown-content { |
||||
|
top: calc(100% + 5px); |
||||
|
right: 0; |
||||
|
} |
||||
|
.x-spreadsheet-dropdown.top-left .x-spreadsheet-dropdown-content { |
||||
|
bottom: calc(100% + 5px); |
||||
|
left: 0; |
||||
|
} |
||||
|
.x-spreadsheet-dropdown.top-right .x-spreadsheet-dropdown-content { |
||||
|
bottom: calc(100% + 5px); |
||||
|
right: 0; |
||||
|
} |
||||
|
.x-spreadsheet-dropdown .x-spreadsheet-dropdown-title { |
||||
|
padding: 0 5px; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
/* resizer **/ |
||||
|
.x-spreadsheet-resizer { |
||||
|
position: absolute; |
||||
|
z-index: 11; |
||||
|
} |
||||
|
.x-spreadsheet-resizer .x-spreadsheet-resizer-hover { |
||||
|
background-color: rgba(75, 137, 255, 0.25); |
||||
|
} |
||||
|
.x-spreadsheet-resizer .x-spreadsheet-resizer-line { |
||||
|
position: absolute; |
||||
|
} |
||||
|
.x-spreadsheet-resizer.horizontal { |
||||
|
cursor: row-resize; |
||||
|
} |
||||
|
.x-spreadsheet-resizer.horizontal .x-spreadsheet-resizer-line { |
||||
|
border-bottom: 2px dashed #4b89ff; |
||||
|
left: 0; |
||||
|
bottom: 0; |
||||
|
} |
||||
|
.x-spreadsheet-resizer.vertical { |
||||
|
cursor: col-resize; |
||||
|
} |
||||
|
.x-spreadsheet-resizer.vertical .x-spreadsheet-resizer-line { |
||||
|
border-right: 2px dashed #4b89ff; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
} |
||||
|
/* scrollbar */ |
||||
|
.x-spreadsheet-scrollbar { |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
right: 0; |
||||
|
background-color: #f4f5f8; |
||||
|
opacity: 0.9; |
||||
|
z-index: 12; |
||||
|
} |
||||
|
.x-spreadsheet-scrollbar.horizontal { |
||||
|
right: 15px; |
||||
|
overflow-x: scroll; |
||||
|
overflow-y: hidden; |
||||
|
} |
||||
|
.x-spreadsheet-scrollbar.horizontal > div { |
||||
|
height: 1px; |
||||
|
background: #ddd; |
||||
|
} |
||||
|
.x-spreadsheet-scrollbar.vertical { |
||||
|
bottom: 15px; |
||||
|
overflow-x: hidden; |
||||
|
overflow-y: scroll; |
||||
|
} |
||||
|
.x-spreadsheet-scrollbar.vertical > div { |
||||
|
width: 1px; |
||||
|
background: #ddd; |
||||
|
} |
||||
|
/* @{css-prefix}-overlayer */ |
||||
|
.x-spreadsheet-overlayer { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
z-index: 10; |
||||
|
} |
||||
|
.x-spreadsheet-overlayer .x-spreadsheet-overlayer-content { |
||||
|
position: absolute; |
||||
|
overflow: hidden; |
||||
|
pointer-events: none; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
.x-spreadsheet-editor, |
||||
|
.x-spreadsheet-selector { |
||||
|
box-sizing: content-box; |
||||
|
position: absolute; |
||||
|
overflow: hidden; |
||||
|
pointer-events: none; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
/* @{css-prefix}-selector */ |
||||
|
.x-spreadsheet-selector .hide-input { |
||||
|
position: absolute; |
||||
|
z-index: 0; |
||||
|
} |
||||
|
.x-spreadsheet-selector .hide-input input { |
||||
|
padding: 0; |
||||
|
width: 0; |
||||
|
border: none!important; |
||||
|
} |
||||
|
.x-spreadsheet-selector .x-spreadsheet-selector-area { |
||||
|
position: absolute; |
||||
|
border: 2px solid #4b89ff; |
||||
|
background: rgba(75, 137, 255, 0.1); |
||||
|
z-index: 5; |
||||
|
} |
||||
|
.x-spreadsheet-selector .x-spreadsheet-selector-clipboard, |
||||
|
.x-spreadsheet-selector .x-spreadsheet-selector-autofill { |
||||
|
position: absolute; |
||||
|
background: transparent; |
||||
|
z-index: 100; |
||||
|
} |
||||
|
.x-spreadsheet-selector .x-spreadsheet-selector-clipboard { |
||||
|
border: 2px dashed #4b89ff; |
||||
|
} |
||||
|
.x-spreadsheet-selector .x-spreadsheet-selector-autofill { |
||||
|
border: 1px dashed rgba(0, 0, 0, 0.45); |
||||
|
} |
||||
|
.x-spreadsheet-selector .x-spreadsheet-selector-corner { |
||||
|
pointer-events: auto; |
||||
|
position: absolute; |
||||
|
cursor: crosshair; |
||||
|
font-size: 0; |
||||
|
height: 5px; |
||||
|
width: 5px; |
||||
|
right: -5px; |
||||
|
bottom: -5px; |
||||
|
border: 2px solid #ffffff; |
||||
|
background: #4b89ff; |
||||
|
} |
||||
|
.x-spreadsheet-editor { |
||||
|
z-index: 20; |
||||
|
} |
||||
|
.x-spreadsheet-editor .x-spreadsheet-editor-area { |
||||
|
position: absolute; |
||||
|
text-align: left; |
||||
|
border: 2px solid #4b89ff; |
||||
|
line-height: 0; |
||||
|
z-index: 100; |
||||
|
pointer-events: auto; |
||||
|
} |
||||
|
.x-spreadsheet-editor .x-spreadsheet-editor-area textarea { |
||||
|
box-sizing: content-box; |
||||
|
border: none; |
||||
|
padding: 0 3px; |
||||
|
outline: none; |
||||
|
resize: none; |
||||
|
text-align: start; |
||||
|
overflow-y: hidden; |
||||
|
font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif; |
||||
|
color: inherit; |
||||
|
white-space: normal; |
||||
|
word-wrap: break-word; |
||||
|
line-height: 22px; |
||||
|
margin: 0; |
||||
|
} |
||||
|
.x-spreadsheet-editor .x-spreadsheet-editor-area .textline { |
||||
|
overflow: hidden; |
||||
|
visibility: hidden; |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
} |
||||
|
.x-spreadsheet-item { |
||||
|
user-select: none; |
||||
|
background: 0; |
||||
|
border: 1px solid transparent; |
||||
|
outline: none; |
||||
|
height: 26px; |
||||
|
color: rgba(0, 0, 0, 0.9); |
||||
|
line-height: 26px; |
||||
|
list-style: none; |
||||
|
padding: 2px 10px; |
||||
|
cursor: default; |
||||
|
text-align: left; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.x-spreadsheet-item.disabled { |
||||
|
pointer-events: none; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
.x-spreadsheet-item:hover, |
||||
|
.x-spreadsheet-item.active { |
||||
|
background: rgba(0, 0, 0, 0.05); |
||||
|
} |
||||
|
.x-spreadsheet-item.divider { |
||||
|
height: 0; |
||||
|
padding: 0; |
||||
|
margin: 5px 0; |
||||
|
border: none; |
||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1); |
||||
|
} |
||||
|
.x-spreadsheet-item .label { |
||||
|
float: right; |
||||
|
opacity: 0.65; |
||||
|
font-size: 1em; |
||||
|
} |
||||
|
.x-spreadsheet-item.state, |
||||
|
.x-spreadsheet-header.state { |
||||
|
padding-left: 35px!important; |
||||
|
position: relative; |
||||
|
} |
||||
|
.x-spreadsheet-item.state:before, |
||||
|
.x-spreadsheet-header.state:before { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
width: 10px; |
||||
|
height: 10px; |
||||
|
left: 12px; |
||||
|
top: calc(50% - 5px); |
||||
|
background: rgba(0, 0, 0, 0.08); |
||||
|
border-radius: 2px; |
||||
|
} |
||||
|
.x-spreadsheet-item.state.checked:before, |
||||
|
.x-spreadsheet-header.state.checked:before { |
||||
|
background: #4b89ff; |
||||
|
} |
||||
|
.x-spreadsheet-checkbox { |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
backface-visibility: hidden; |
||||
|
outline: 0; |
||||
|
vertical-align: baseline; |
||||
|
font-style: normal; |
||||
|
font-size: 1rem; |
||||
|
line-height: 1em; |
||||
|
} |
||||
|
.x-spreadsheet-checkbox > input { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
opacity: 0!important; |
||||
|
outline: 0; |
||||
|
z-index: -1; |
||||
|
} |
||||
|
.x-spreadsheet-suggest, |
||||
|
.x-spreadsheet-contextmenu, |
||||
|
.x-spreadsheet-sort-filter { |
||||
|
position: absolute; |
||||
|
box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15); |
||||
|
background: #fff; |
||||
|
z-index: 100; |
||||
|
width: 260px; |
||||
|
pointer-events: auto; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
.x-spreadsheet-suggest { |
||||
|
width: 200px; |
||||
|
} |
||||
|
.x-spreadsheet-filter { |
||||
|
border: 1px solid #e9e9e9; |
||||
|
font-size: 12px; |
||||
|
margin: 10px; |
||||
|
} |
||||
|
.x-spreadsheet-filter .x-spreadsheet-header { |
||||
|
padding: 0.5em 0.75em; |
||||
|
background: #f8f8f9; |
||||
|
border-bottom: 1px solid #e9e9e9; |
||||
|
border-left: 1px solid transparent; |
||||
|
} |
||||
|
.x-spreadsheet-filter .x-spreadsheet-body { |
||||
|
height: 200px; |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
.x-spreadsheet-filter .x-spreadsheet-body .x-spreadsheet-item { |
||||
|
height: 20px; |
||||
|
line-height: 20px; |
||||
|
} |
||||
|
.x-spreadsheet-sort-filter .x-spreadsheet-buttons { |
||||
|
margin: 10px; |
||||
|
} |
||||
|
.x-spreadsheet-bottombar { |
||||
|
height: 40px; |
||||
|
padding: 0 30px; |
||||
|
text-align: left; |
||||
|
background: #f5f6f7; |
||||
|
display: flex; |
||||
|
} |
||||
|
.x-spreadsheet-bottombar { |
||||
|
position: relative; |
||||
|
border-top: 1px solid #e0e2e4; |
||||
|
} |
||||
|
.x-spreadsheet-bottombar .x-spreadsheet-menu > li { |
||||
|
line-height: 40px; |
||||
|
height: 40px; |
||||
|
padding-top: 0; |
||||
|
padding-bottom: 0; |
||||
|
vertical-align: middle; |
||||
|
border-right: 1px solid #e8eaed; |
||||
|
} |
||||
|
.x-spreadsheet-menu { |
||||
|
list-style: none; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
user-select: none; |
||||
|
} |
||||
|
.x-spreadsheet-menu > li { |
||||
|
float: left; |
||||
|
line-height: 1.25em; |
||||
|
padding: 0.785em 1em; |
||||
|
margin: 0; |
||||
|
vertical-align: middle; |
||||
|
text-align: left; |
||||
|
font-weight: 400; |
||||
|
color: #80868b; |
||||
|
white-space: nowrap; |
||||
|
cursor: pointer; |
||||
|
transition: all 0.3s; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
.x-spreadsheet-menu > li.active { |
||||
|
background-color: #fff; |
||||
|
color: rgba(0, 0, 0, 0.65); |
||||
|
} |
||||
|
.x-spreadsheet-menu > li .x-spreadsheet-dropdown { |
||||
|
display: inline-block; |
||||
|
} |
||||
|
.x-spreadsheet-print { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
z-index: 100; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
.x-spreadsheet-print-bar { |
||||
|
background: #424242; |
||||
|
height: 60px; |
||||
|
line-height: 60px; |
||||
|
padding: 0 30px; |
||||
|
} |
||||
|
.x-spreadsheet-print-bar .-title { |
||||
|
color: #fff; |
||||
|
font-weight: bold; |
||||
|
font-size: 1.2em; |
||||
|
float: left; |
||||
|
} |
||||
|
.x-spreadsheet-print-bar .-right { |
||||
|
float: right; |
||||
|
margin-top: 12px; |
||||
|
} |
||||
|
.x-spreadsheet-print-content { |
||||
|
display: flex; |
||||
|
flex: auto; |
||||
|
flex-direction: row; |
||||
|
background: #d0d0d0; |
||||
|
height: calc(100% - 60px); |
||||
|
} |
||||
|
.x-spreadsheet-print-content .-sider { |
||||
|
flex: 0 0 300px; |
||||
|
width: 300px; |
||||
|
border-left: 2px solid #ccc; |
||||
|
background: #fff; |
||||
|
} |
||||
|
.x-spreadsheet-print-content .-content { |
||||
|
flex: auto; |
||||
|
overflow-x: auto; |
||||
|
overflow-y: scroll; |
||||
|
height: 100%; |
||||
|
} |
||||
|
.x-spreadsheet-canvas-card-wraper { |
||||
|
margin: 40px 20px; |
||||
|
} |
||||
|
.x-spreadsheet-canvas-card { |
||||
|
background: #fff; |
||||
|
margin: auto; |
||||
|
page-break-before: auto; |
||||
|
page-break-after: always; |
||||
|
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 3px rgba(0, 0, 0, 0.12), 0 4px 5px 0 rgba(0, 0, 0, 0.2); |
||||
|
} |
||||
|
.x-spreadsheet-calendar { |
||||
|
color: rgba(0, 0, 0, 0.65); |
||||
|
background: #ffffff; |
||||
|
user-select: none; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-header { |
||||
|
font-weight: 700; |
||||
|
line-height: 30px; |
||||
|
text-align: center; |
||||
|
width: 100%; |
||||
|
float: left; |
||||
|
background: #f9fafb; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-header .calendar-header-left { |
||||
|
padding-left: 5px; |
||||
|
float: left; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-header .calendar-header-right { |
||||
|
float: right; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-header .calendar-header-right a { |
||||
|
padding: 3px 0; |
||||
|
margin-right: 2px; |
||||
|
border-radius: 2px; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-header .calendar-header-right a:hover { |
||||
|
background: rgba(0, 0, 0, 0.08); |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-body { |
||||
|
border-collapse: collapse; |
||||
|
border-spacing: 0; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-body th, |
||||
|
.x-spreadsheet-calendar .calendar-body td { |
||||
|
width: 14.28571429%; |
||||
|
min-width: 32px; |
||||
|
text-align: center; |
||||
|
font-weight: 700; |
||||
|
line-height: 30px; |
||||
|
padding: 0; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-body td > .cell:hover { |
||||
|
background: #ecf6fd; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-body td > .cell.active, |
||||
|
.x-spreadsheet-calendar .calendar-body td > .cell.active:hover { |
||||
|
background: #ecf6fd; |
||||
|
color: #2185D0; |
||||
|
} |
||||
|
.x-spreadsheet-calendar .calendar-body td > .cell.disabled { |
||||
|
pointer-events: none; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
.x-spreadsheet-datepicker { |
||||
|
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: calc(100% + 5px); |
||||
|
z-index: 10; |
||||
|
width: auto; |
||||
|
} |
||||
|
.x-spreadsheet-buttons { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
.x-spreadsheet-buttons .x-spreadsheet-button { |
||||
|
margin-left: 8px; |
||||
|
} |
||||
|
.x-spreadsheet-button { |
||||
|
display: inline-block; |
||||
|
border-radius: 3px; |
||||
|
line-height: 1em; |
||||
|
min-height: 1em; |
||||
|
white-space: nowrap; |
||||
|
text-align: center; |
||||
|
cursor: pointer; |
||||
|
font-size: 1em; |
||||
|
font-weight: 700; |
||||
|
padding: 0.75em 1em; |
||||
|
color: rgba(0, 0, 0, 0.6); |
||||
|
background: #E0E1E2; |
||||
|
text-decoration: none; |
||||
|
font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif; |
||||
|
outline: none; |
||||
|
vertical-align: baseline; |
||||
|
zoom: 1; |
||||
|
user-select: none; |
||||
|
transition: all 0.1s linear; |
||||
|
} |
||||
|
.x-spreadsheet-button.active, |
||||
|
.x-spreadsheet-button:hover { |
||||
|
background-color: #C0C1C2; |
||||
|
color: rgba(0, 0, 0, 0.8); |
||||
|
} |
||||
|
.x-spreadsheet-button.primary { |
||||
|
color: #fff; |
||||
|
background-color: #2185D0; |
||||
|
} |
||||
|
.x-spreadsheet-button.primary:hover, |
||||
|
.x-spreadsheet-button.primary.active { |
||||
|
color: #fff; |
||||
|
background-color: #1678c2; |
||||
|
} |
||||
|
.x-spreadsheet-form-input { |
||||
|
font-size: 1em; |
||||
|
position: relative; |
||||
|
font-weight: 400; |
||||
|
display: inline-flex; |
||||
|
color: rgba(0, 0, 0, 0.87); |
||||
|
} |
||||
|
.x-spreadsheet-form-input input { |
||||
|
z-index: 1; |
||||
|
margin: 0; |
||||
|
max-width: 100%; |
||||
|
flex: 1 0 auto; |
||||
|
outline: 0; |
||||
|
-webkit-tap-highlight-color: rgba(255, 255, 255, 0); |
||||
|
text-align: left; |
||||
|
line-height: 30px; |
||||
|
height: 30px; |
||||
|
padding: 0 8px; |
||||
|
background: #fff; |
||||
|
border: 1px solid #e9e9e9; |
||||
|
border-radius: 3px; |
||||
|
transition: box-shadow 0.1s ease, border-color 0.1s ease; |
||||
|
box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06); |
||||
|
} |
||||
|
.x-spreadsheet-form-input input:focus { |
||||
|
border-color: #4b89ff; |
||||
|
box-shadow: inset 0 1px 2px rgba(75, 137, 255, 0.2); |
||||
|
} |
||||
|
.x-spreadsheet-form-select { |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
background: #fff; |
||||
|
border: 1px solid #e9e9e9; |
||||
|
border-radius: 2px; |
||||
|
cursor: pointer; |
||||
|
color: rgba(0, 0, 0, 0.87); |
||||
|
user-select: none; |
||||
|
box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06); |
||||
|
} |
||||
|
.x-spreadsheet-form-select .input-text { |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
min-width: 60px; |
||||
|
width: auto; |
||||
|
height: 30px; |
||||
|
line-height: 30px; |
||||
|
padding: 0 8px; |
||||
|
} |
||||
|
.x-spreadsheet-form-fields { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
flex-wrap: wrap; |
||||
|
} |
||||
|
.x-spreadsheet-form-fields .x-spreadsheet-form-field { |
||||
|
flex: 0 1 auto; |
||||
|
} |
||||
|
.x-spreadsheet-form-fields .x-spreadsheet-form-field .label { |
||||
|
display: inline-block; |
||||
|
margin: 0 10px 0 0; |
||||
|
} |
||||
|
.x-spreadsheet-form-field { |
||||
|
display: block; |
||||
|
vertical-align: middle; |
||||
|
margin-left: 10px; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
.x-spreadsheet-form-field:first-child { |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
.x-spreadsheet-form-field.error .x-spreadsheet-form-select, |
||||
|
.x-spreadsheet-form-field.error input { |
||||
|
border-color: #f04134; |
||||
|
} |
||||
|
.x-spreadsheet-form-field .tip { |
||||
|
color: #f04134; |
||||
|
font-size: 0.9em; |
||||
|
} |
||||
|
.x-spreadsheet-dimmer { |
||||
|
display: none; |
||||
|
position: absolute; |
||||
|
top: 0 !important; |
||||
|
left: 0 !important; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
text-align: center; |
||||
|
vertical-align: middle; |
||||
|
background-color: rgba(0, 0, 0, 0.6); |
||||
|
opacity: 0; |
||||
|
-webkit-animation-fill-mode: both; |
||||
|
animation-fill-mode: both; |
||||
|
-webkit-animation-duration: 0.5s; |
||||
|
animation-duration: 0.5s; |
||||
|
transition: background-color 0.5s linear; |
||||
|
user-select: none; |
||||
|
z-index: 1000; |
||||
|
} |
||||
|
.x-spreadsheet-dimmer.active { |
||||
|
display: block; |
||||
|
opacity: 1; |
||||
|
} |
||||
|
form fieldset { |
||||
|
border: none; |
||||
|
} |
||||
|
form fieldset label { |
||||
|
display: block; |
||||
|
margin-bottom: 0.5em; |
||||
|
font-size: 1em; |
||||
|
color: #666; |
||||
|
} |
||||
|
form fieldset select { |
||||
|
font-size: 1.1em; |
||||
|
width: 100%; |
||||
|
background-color: #fff; |
||||
|
border: none; |
||||
|
border-bottom: 2px solid #ddd; |
||||
|
padding: 0.5em 0.85em; |
||||
|
border-radius: 2px; |
||||
|
} |
||||
|
.x-spreadsheet-modal, |
||||
|
.x-spreadsheet-toast { |
||||
|
font-size: 13px; |
||||
|
position: fixed; |
||||
|
z-index: 1001; |
||||
|
text-align: left; |
||||
|
line-height: 1.25em; |
||||
|
min-width: 360px; |
||||
|
color: rgba(0, 0, 0, 0.87); |
||||
|
font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif; |
||||
|
border-radius: 4px; |
||||
|
border: 1px solid rgba(0, 0, 0, 0.1); |
||||
|
background-color: #fff; |
||||
|
background-clip: padding-box; |
||||
|
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px; |
||||
|
} |
||||
|
.x-spreadsheet-toast { |
||||
|
background-color: rgba(255, 255, 255, 0.85); |
||||
|
} |
||||
|
.x-spreadsheet-modal-header, |
||||
|
.x-spreadsheet-toast-header { |
||||
|
font-weight: 600; |
||||
|
background-clip: padding-box; |
||||
|
background-color: rgba(255, 255, 255, 0.85); |
||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05); |
||||
|
border-radius: 4px 4px 0 0; |
||||
|
} |
||||
|
|
||||
|
.x-spreadsheet-toast-header { |
||||
|
color: #F2711C; |
||||
|
} |
||||
|
.x-spreadsheet-modal-header { |
||||
|
border-bottom: 1px solid #e0e2e4; |
||||
|
background: rgba(0, 0, 0, 0.08); |
||||
|
font-size: 1.0785em; |
||||
|
} |
||||
|
.x-spreadsheet-modal-header, |
||||
|
.x-spreadsheet-modal-content, |
||||
|
.x-spreadsheet-toast-header, |
||||
|
.x-spreadsheet-toast-content { |
||||
|
padding: 0.75em 1em; |
||||
|
} |
||||
|
|
||||
|
.x-spreadsheet-menu li:first-child { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.vue-office-excel { |
||||
|
height: 100%; |
||||
|
} |
@ -0,0 +1,160 @@ |
|||||
|
// node_modules/@vue/devtools-api/lib/esm/env.js
|
||||
|
function getDevtoolsGlobalHook() { |
||||
|
return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__; |
||||
|
} |
||||
|
function getTarget() { |
||||
|
return typeof navigator !== "undefined" && typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {}; |
||||
|
} |
||||
|
var isProxyAvailable = typeof Proxy === "function"; |
||||
|
|
||||
|
// node_modules/@vue/devtools-api/lib/esm/const.js
|
||||
|
var HOOK_SETUP = "devtools-plugin:setup"; |
||||
|
var HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set"; |
||||
|
|
||||
|
// node_modules/@vue/devtools-api/lib/esm/time.js
|
||||
|
var supported; |
||||
|
var perf; |
||||
|
function isPerformanceSupported() { |
||||
|
var _a; |
||||
|
if (supported !== void 0) { |
||||
|
return supported; |
||||
|
} |
||||
|
if (typeof window !== "undefined" && window.performance) { |
||||
|
supported = true; |
||||
|
perf = window.performance; |
||||
|
} else if (typeof global !== "undefined" && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) { |
||||
|
supported = true; |
||||
|
perf = global.perf_hooks.performance; |
||||
|
} else { |
||||
|
supported = false; |
||||
|
} |
||||
|
return supported; |
||||
|
} |
||||
|
function now() { |
||||
|
return isPerformanceSupported() ? perf.now() : Date.now(); |
||||
|
} |
||||
|
|
||||
|
// node_modules/@vue/devtools-api/lib/esm/proxy.js
|
||||
|
var ApiProxy = class { |
||||
|
constructor(plugin, hook) { |
||||
|
this.target = null; |
||||
|
this.targetQueue = []; |
||||
|
this.onQueue = []; |
||||
|
this.plugin = plugin; |
||||
|
this.hook = hook; |
||||
|
const defaultSettings = {}; |
||||
|
if (plugin.settings) { |
||||
|
for (const id in plugin.settings) { |
||||
|
const item = plugin.settings[id]; |
||||
|
defaultSettings[id] = item.defaultValue; |
||||
|
} |
||||
|
} |
||||
|
const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`; |
||||
|
let currentSettings = Object.assign({}, defaultSettings); |
||||
|
try { |
||||
|
const raw = localStorage.getItem(localSettingsSaveId); |
||||
|
const data = JSON.parse(raw); |
||||
|
Object.assign(currentSettings, data); |
||||
|
} catch (e) { |
||||
|
} |
||||
|
this.fallbacks = { |
||||
|
getSettings() { |
||||
|
return currentSettings; |
||||
|
}, |
||||
|
setSettings(value) { |
||||
|
try { |
||||
|
localStorage.setItem(localSettingsSaveId, JSON.stringify(value)); |
||||
|
} catch (e) { |
||||
|
} |
||||
|
currentSettings = value; |
||||
|
}, |
||||
|
now() { |
||||
|
return now(); |
||||
|
} |
||||
|
}; |
||||
|
if (hook) { |
||||
|
hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => { |
||||
|
if (pluginId === this.plugin.id) { |
||||
|
this.fallbacks.setSettings(value); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
this.proxiedOn = new Proxy({}, { |
||||
|
get: (_target, prop) => { |
||||
|
if (this.target) { |
||||
|
return this.target.on[prop]; |
||||
|
} else { |
||||
|
return (...args) => { |
||||
|
this.onQueue.push({ |
||||
|
method: prop, |
||||
|
args |
||||
|
}); |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
this.proxiedTarget = new Proxy({}, { |
||||
|
get: (_target, prop) => { |
||||
|
if (this.target) { |
||||
|
return this.target[prop]; |
||||
|
} else if (prop === "on") { |
||||
|
return this.proxiedOn; |
||||
|
} else if (Object.keys(this.fallbacks).includes(prop)) { |
||||
|
return (...args) => { |
||||
|
this.targetQueue.push({ |
||||
|
method: prop, |
||||
|
args, |
||||
|
resolve: () => { |
||||
|
} |
||||
|
}); |
||||
|
return this.fallbacks[prop](...args); |
||||
|
}; |
||||
|
} else { |
||||
|
return (...args) => { |
||||
|
return new Promise((resolve) => { |
||||
|
this.targetQueue.push({ |
||||
|
method: prop, |
||||
|
args, |
||||
|
resolve |
||||
|
}); |
||||
|
}); |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
async setRealTarget(target) { |
||||
|
this.target = target; |
||||
|
for (const item of this.onQueue) { |
||||
|
this.target.on[item.method](...item.args); |
||||
|
} |
||||
|
for (const item of this.targetQueue) { |
||||
|
item.resolve(await this.target[item.method](...item.args)); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// node_modules/@vue/devtools-api/lib/esm/index.js
|
||||
|
function setupDevtoolsPlugin(pluginDescriptor, setupFn) { |
||||
|
const descriptor = pluginDescriptor; |
||||
|
const target = getTarget(); |
||||
|
const hook = getDevtoolsGlobalHook(); |
||||
|
const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy; |
||||
|
if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) { |
||||
|
hook.emit(HOOK_SETUP, pluginDescriptor, setupFn); |
||||
|
} else { |
||||
|
const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null; |
||||
|
const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || []; |
||||
|
list.push({ |
||||
|
pluginDescriptor: descriptor, |
||||
|
setupFn, |
||||
|
proxy |
||||
|
}); |
||||
|
if (proxy) |
||||
|
setupFn(proxy.proxiedTarget); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export { |
||||
|
setupDevtoolsPlugin |
||||
|
}; |
@ -0,0 +1,8 @@ |
|||||
|
/** |
||||
|
* Bundled by jsDelivr using Rollup v2.79.1 and Terser v5.17.1. |
||||
|
* Original file: /npm/detect-it@4.0.1/dist/detect-it.esm.js |
||||
|
* |
||||
|
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
|
||||
|
*/ |
||||
|
var e="undefined"!=typeof window?window:{screen:{},navigator:{}},n=(e.matchMedia||function(){return{matches:!1}}).bind(e),t=!1,o={get passive(){return t=!0}},i=function(){};e.addEventListener&&e.addEventListener("p",i,o),e.removeEventListener&&e.removeEventListener("p",i,!1);var r=t,a="PointerEvent"in e,s="ontouchstart"in e,c=s||"TouchEvent"in e&&n("(any-pointer: coarse)").matches,h=(e.navigator.maxTouchPoints||0)>0||c,u=e.navigator.userAgent||"",m=n("(pointer: coarse)").matches&&/iPad|Macintosh/.test(u)&&Math.min(e.screen.width||0,e.screen.height||0)>=768,v=(n("(pointer: coarse)").matches||!n("(pointer: fine)").matches&&s)&&!/Windows.*Firefox/.test(u),d=n("(any-pointer: fine)").matches||n("(any-hover: hover)").matches||m||!s,p=!h||!d&&v?h?"touchOnly":"mouseOnly":"hybrid",y="mouseOnly"===p?"mouse":"touchOnly"===p||v?"touch":"mouse";export{p as deviceType,y as primaryInput,r as supportsPassiveEvents,a as supportsPointerEvents,c as supportsTouchEvents};export default null; |
||||
|
//# sourceMappingURL=/sm/4280e12bc6c9669987adcde477eb6347c379a3a324091a23187d02e5284db1bb.map
|
@ -0,0 +1,2 @@ |
|||||
|
/*! Element Plus v2.3.6 */var e={name:"en",el:{colorpicker:{confirm:"OK",clear:"Clear",defaultLabel:"color picker",description:"current color is {color}. press enter to select a new color."},datepicker:{now:"Now",today:"Today",cancel:"Cancel",clear:"Clear",confirm:"OK",dateTablePrompt:"Use the arrow keys and enter to select the day of the month",monthTablePrompt:"Use the arrow keys and enter to select the month",yearTablePrompt:"Use the arrow keys and enter to select the year",selectedDate:"Selected date",selectDate:"Select date",selectTime:"Select time",startDate:"Start Date",startTime:"Start Time",endDate:"End Date",endTime:"End Time",prevYear:"Previous Year",nextYear:"Next Year",prevMonth:"Previous Month",nextMonth:"Next Month",year:"",month1:"January",month2:"February",month3:"March",month4:"April",month5:"May",month6:"June",month7:"July",month8:"August",month9:"September",month10:"October",month11:"November",month12:"December",week:"week",weeks:{sun:"Sun",mon:"Mon",tue:"Tue",wed:"Wed",thu:"Thu",fri:"Fri",sat:"Sat"},weeksFull:{sun:"Sunday",mon:"Monday",tue:"Tuesday",wed:"Wednesday",thu:"Thursday",fri:"Friday",sat:"Saturday"},months:{jan:"Jan",feb:"Feb",mar:"Mar",apr:"Apr",may:"May",jun:"Jun",jul:"Jul",aug:"Aug",sep:"Sep",oct:"Oct",nov:"Nov",dec:"Dec"}},inputNumber:{decrease:"decrease number",increase:"increase number"},select:{loading:"Loading",noMatch:"No matching data",noData:"No data",placeholder:"Select"},dropdown:{toggleDropdown:"Toggle Dropdown"},cascader:{noMatch:"No matching data",loading:"Loading",placeholder:"Select",noData:"No data"},pagination:{goto:"Go to",pagesize:"/page",total:"Total {total}",pageClassifier:"",page:"Page",prev:"Go to previous page",next:"Go to next page",currentPage:"page {pager}",prevPages:"Previous {pager} pages",nextPages:"Next {pager} pages",deprecationWarning:"Deprecated usages detected, please refer to the el-pagination documentation for more details"},dialog:{close:"Close this dialog"},drawer:{close:"Close this dialog"},messagebox:{title:"Message",confirm:"OK",cancel:"Cancel",error:"Illegal input",close:"Close this dialog"},upload:{deleteTip:"press delete to remove",delete:"Delete",preview:"Preview",continue:"Continue"},slider:{defaultLabel:"slider between {min} and {max}",defaultRangeStartLabel:"pick start value",defaultRangeEndLabel:"pick end value"},table:{emptyText:"No Data",confirmFilter:"Confirm",resetFilter:"Reset",clearFilter:"All",sumText:"Sum"},tree:{emptyText:"No Data"},transfer:{noMatch:"No matching data",noData:"No data",titles:["List 1","List 2"],filterPlaceholder:"Enter keyword",noCheckedFormat:"{total} items",hasCheckedFormat:"{checked}/{total} checked"},image:{error:"FAILED"},pageHeader:{title:"Back"},popconfirm:{confirmButtonText:"Yes",cancelButtonText:"No"}}};export{e as default}; |
||||
|
//# sourceMappingURL=en.min.mjs.map
|
@ -0,0 +1,2 @@ |
|||||
|
/*! Element Plus v2.3.4 */var u={name:"zh-cn",el:{colorpicker:{confirm:"\u786E\u5B9A",clear:"\u6E05\u7A7A"},datepicker:{now:"\u6B64\u523B",today:"\u4ECA\u5929",cancel:"\u53D6\u6D88",clear:"\u6E05\u7A7A",confirm:"\u786E\u5B9A",selectDate:"\u9009\u62E9\u65E5\u671F",selectTime:"\u9009\u62E9\u65F6\u95F4",startDate:"\u5F00\u59CB\u65E5\u671F",startTime:"\u5F00\u59CB\u65F6\u95F4",endDate:"\u7ED3\u675F\u65E5\u671F",endTime:"\u7ED3\u675F\u65F6\u95F4",prevYear:"\u524D\u4E00\u5E74",nextYear:"\u540E\u4E00\u5E74",prevMonth:"\u4E0A\u4E2A\u6708",nextMonth:"\u4E0B\u4E2A\u6708",year:"\u5E74",month1:"1 \u6708",month2:"2 \u6708",month3:"3 \u6708",month4:"4 \u6708",month5:"5 \u6708",month6:"6 \u6708",month7:"7 \u6708",month8:"8 \u6708",month9:"9 \u6708",month10:"10 \u6708",month11:"11 \u6708",month12:"12 \u6708",weeks:{sun:"\u65E5",mon:"\u4E00",tue:"\u4E8C",wed:"\u4E09",thu:"\u56DB",fri:"\u4E94",sat:"\u516D"},months:{jan:"\u4E00\u6708",feb:"\u4E8C\u6708",mar:"\u4E09\u6708",apr:"\u56DB\u6708",may:"\u4E94\u6708",jun:"\u516D\u6708",jul:"\u4E03\u6708",aug:"\u516B\u6708",sep:"\u4E5D\u6708",oct:"\u5341\u6708",nov:"\u5341\u4E00\u6708",dec:"\u5341\u4E8C\u6708"}},select:{loading:"\u52A0\u8F7D\u4E2D",noMatch:"\u65E0\u5339\u914D\u6570\u636E",noData:"\u65E0\u6570\u636E",placeholder:"\u8BF7\u9009\u62E9"},cascader:{noMatch:"\u65E0\u5339\u914D\u6570\u636E",loading:"\u52A0\u8F7D\u4E2D",placeholder:"\u8BF7\u9009\u62E9",noData:"\u6682\u65E0\u6570\u636E"},pagination:{goto:"\u524D\u5F80",pagesize:"\u6761/\u9875",total:"\u5171 {total} \u6761",pageClassifier:"\u9875",page:"\u9875",prev:"\u4E0A\u4E00\u9875",next:"\u4E0B\u4E00\u9875",currentPage:"\u7B2C {pager} \u9875",prevPages:"\u5411\u524D {pager} \u9875",nextPages:"\u5411\u540E {pager} \u9875",deprecationWarning:"\u4F60\u4F7F\u7528\u4E86\u4E00\u4E9B\u5DF2\u88AB\u5E9F\u5F03\u7684\u7528\u6CD5\uFF0C\u8BF7\u53C2\u8003 el-pagination \u7684\u5B98\u65B9\u6587\u6863"},messagebox:{title:"\u63D0\u793A",confirm:"\u786E\u5B9A",cancel:"\u53D6\u6D88",error:"\u8F93\u5165\u7684\u6570\u636E\u4E0D\u5408\u6CD5!"},upload:{deleteTip:"\u6309 delete \u952E\u53EF\u5220\u9664",delete:"\u5220\u9664",preview:"\u67E5\u770B\u56FE\u7247",continue:"\u7EE7\u7EED\u4E0A\u4F20"},table:{emptyText:"\u6682\u65E0\u6570\u636E",confirmFilter:"\u7B5B\u9009",resetFilter:"\u91CD\u7F6E",clearFilter:"\u5168\u90E8",sumText:"\u5408\u8BA1"},tree:{emptyText:"\u6682\u65E0\u6570\u636E"},transfer:{noMatch:"\u65E0\u5339\u914D\u6570\u636E",noData:"\u65E0\u6570\u636E",titles:["\u5217\u8868 1","\u5217\u8868 2"],filterPlaceholder:"\u8BF7\u8F93\u5165\u641C\u7D22\u5185\u5BB9",noCheckedFormat:"\u5171 {total} \u9879",hasCheckedFormat:"\u5DF2\u9009 {checked}/{total} \u9879"},image:{error:"\u52A0\u8F7D\u5931\u8D25"},pageHeader:{title:"\u8FD4\u56DE"},popconfirm:{confirmButtonText:"\u786E\u5B9A",cancelButtonText:"\u53D6\u6D88"}}};export{u as default}; |
||||
|
//# sourceMappingURL=zh-cn.min.mjs.map
|
@ -0,0 +1 @@ |
|||||
|
html.dark{color-scheme:dark;--el-color-primary:#409eff;--el-color-primary-light-3:#3375b9;--el-color-primary-light-5:#2a598a;--el-color-primary-light-7:#213d5b;--el-color-primary-light-8:#1d3043;--el-color-primary-light-9:#18222c;--el-color-primary-dark-2:#66b1ff;--el-color-success:#67c23a;--el-color-success-light-3:#4e8e2f;--el-color-success-light-5:#3e6b27;--el-color-success-light-7:#2d481f;--el-color-success-light-8:#25371c;--el-color-success-light-9:#1c2518;--el-color-success-dark-2:#85ce61;--el-color-warning:#e6a23c;--el-color-warning-light-3:#a77730;--el-color-warning-light-5:#7d5b28;--el-color-warning-light-7:#533f20;--el-color-warning-light-8:#3e301c;--el-color-warning-light-9:#292218;--el-color-warning-dark-2:#ebb563;--el-color-danger:#f56c6c;--el-color-danger-light-3:#b25252;--el-color-danger-light-5:#854040;--el-color-danger-light-7:#582e2e;--el-color-danger-light-8:#412626;--el-color-danger-light-9:#2b1d1d;--el-color-danger-dark-2:#f78989;--el-color-error:#f56c6c;--el-color-error-light-3:#b25252;--el-color-error-light-5:#854040;--el-color-error-light-7:#582e2e;--el-color-error-light-8:#412626;--el-color-error-light-9:#2b1d1d;--el-color-error-dark-2:#f78989;--el-color-info:#909399;--el-color-info-light-3:#6b6d71;--el-color-info-light-5:#525457;--el-color-info-light-7:#393a3c;--el-color-info-light-8:#2d2d2f;--el-color-info-light-9:#202121;--el-color-info-dark-2:#a6a9ad;--el-box-shadow:0px 12px 32px 4px rgba(0, 0, 0, 0.36),0px 8px 20px rgba(0, 0, 0, 0.72);--el-box-shadow-light:0px 0px 12px rgba(0, 0, 0, 0.72);--el-box-shadow-lighter:0px 0px 6px rgba(0, 0, 0, 0.72);--el-box-shadow-dark:0px 16px 48px 16px rgba(0, 0, 0, 0.72),0px 12px 32px #000000,0px 8px 16px -8px #000000;--el-bg-color-page:#0a0a0a;--el-bg-color:#141414;--el-bg-color-overlay:#1d1e1f;--el-text-color-primary:#E5EAF3;--el-text-color-regular:#CFD3DC;--el-text-color-secondary:#A3A6AD;--el-text-color-placeholder:#8D9095;--el-text-color-disabled:#6C6E72;--el-border-color-darker:#636466;--el-border-color-dark:#58585B;--el-border-color:#4C4D4F;--el-border-color-light:#414243;--el-border-color-lighter:#363637;--el-border-color-extra-light:#2B2B2C;--el-fill-color-darker:#424243;--el-fill-color-dark:#39393A;--el-fill-color:#303030;--el-fill-color-light:#262727;--el-fill-color-lighter:#1D1D1D;--el-fill-color-extra-light:#191919;--el-fill-color-blank:transparent;--el-mask-color:rgba(0, 0, 0, 0.8);--el-mask-color-extra-light:rgba(0, 0, 0, 0.3)}html.dark .el-button{--el-button-disabled-text-color:rgba(255, 255, 255, 0.5)}html.dark .el-card{--el-card-bg-color:var(--el-bg-color-overlay)}html.dark .el-empty{--el-empty-fill-color-0:var(--el-color-black);--el-empty-fill-color-1:#4b4b52;--el-empty-fill-color-2:#36383d;--el-empty-fill-color-3:#1e1e20;--el-empty-fill-color-4:#262629;--el-empty-fill-color-5:#202124;--el-empty-fill-color-6:#212224;--el-empty-fill-color-7:#1b1c1f;--el-empty-fill-color-8:#1c1d1f;--el-empty-fill-color-9:#18181a} |
@ -0,0 +1,881 @@ |
|||||
|
/** |
||||
|
* Minified by jsDelivr using clean-css v5.2.2. |
||||
|
* Original file: /npm/github-markdown-css@5.1.0/github-markdown.css |
||||
|
* |
||||
|
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files |
||||
|
*/ |
||||
|
.markdown-body { |
||||
|
color-scheme: light; |
||||
|
--color-prettylights-syntax-comment: #6e7781; |
||||
|
--color-prettylights-syntax-constant: #0550ae; |
||||
|
--color-prettylights-syntax-entity: #8250df; |
||||
|
--color-prettylights-syntax-storage-modifier-import: #24292f; |
||||
|
--color-prettylights-syntax-entity-tag: #116329; |
||||
|
--color-prettylights-syntax-keyword: #cf222e; |
||||
|
--color-prettylights-syntax-string: #0a3069; |
||||
|
--color-prettylights-syntax-variable: #953800; |
||||
|
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e; |
||||
|
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa; |
||||
|
--color-prettylights-syntax-invalid-illegal-bg: #82071e; |
||||
|
--color-prettylights-syntax-carriage-return-text: #f6f8fa; |
||||
|
--color-prettylights-syntax-carriage-return-bg: #cf222e; |
||||
|
--color-prettylights-syntax-string-regexp: #116329; |
||||
|
--color-prettylights-syntax-markup-list: #3b2300; |
||||
|
--color-prettylights-syntax-markup-heading: #0550ae; |
||||
|
--color-prettylights-syntax-markup-italic: #24292f; |
||||
|
--color-prettylights-syntax-markup-bold: #24292f; |
||||
|
--color-prettylights-syntax-markup-deleted-text: #82071e; |
||||
|
--color-prettylights-syntax-markup-deleted-bg: #ffebe9; |
||||
|
--color-prettylights-syntax-markup-inserted-text: #116329; |
||||
|
--color-prettylights-syntax-markup-inserted-bg: #dafbe1; |
||||
|
--color-prettylights-syntax-markup-changed-text: #953800; |
||||
|
--color-prettylights-syntax-markup-changed-bg: #ffd8b5; |
||||
|
--color-prettylights-syntax-markup-ignored-text: #eaeef2; |
||||
|
--color-prettylights-syntax-markup-ignored-bg: #0550ae; |
||||
|
--color-prettylights-syntax-meta-diff-range: #8250df; |
||||
|
--color-prettylights-syntax-brackethighlighter-angle: #57606a; |
||||
|
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f; |
||||
|
--color-prettylights-syntax-constant-other-reference-link: #0a3069; |
||||
|
--color-fg-default: #24292f; |
||||
|
--color-fg-muted: #57606a; |
||||
|
--color-fg-subtle: #6e7781; |
||||
|
--color-canvas-default: #ffffff; |
||||
|
--color-canvas-subtle: #f6f8fa; |
||||
|
--color-border-default: #d0d7de; |
||||
|
--color-border-muted: hsla(210, 18%, 87%, 1); |
||||
|
--color-neutral-muted: rgba(175, 184, 193, 0.2); |
||||
|
--color-accent-fg: #0969da; |
||||
|
--color-accent-emphasis: #0969da; |
||||
|
--color-attention-subtle: #fff8c5; |
||||
|
--color-danger-fg: #cf222e; |
||||
|
} |
||||
|
|
||||
|
html.dark .markdown-body { |
||||
|
color-scheme: dark; |
||||
|
--color-prettylights-syntax-comment: #8b949e; |
||||
|
--color-prettylights-syntax-constant: #79c0ff; |
||||
|
--color-prettylights-syntax-entity: #d2a8ff; |
||||
|
--color-prettylights-syntax-storage-modifier-import: #c9d1d9; |
||||
|
--color-prettylights-syntax-entity-tag: #7ee787; |
||||
|
--color-prettylights-syntax-keyword: #ff7b72; |
||||
|
--color-prettylights-syntax-string: #a5d6ff; |
||||
|
--color-prettylights-syntax-variable: #ffa657; |
||||
|
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149; |
||||
|
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc; |
||||
|
--color-prettylights-syntax-invalid-illegal-bg: #8e1519; |
||||
|
--color-prettylights-syntax-carriage-return-text: #f0f6fc; |
||||
|
--color-prettylights-syntax-carriage-return-bg: #b62324; |
||||
|
--color-prettylights-syntax-string-regexp: #7ee787; |
||||
|
--color-prettylights-syntax-markup-list: #f2cc60; |
||||
|
--color-prettylights-syntax-markup-heading: #1f6feb; |
||||
|
--color-prettylights-syntax-markup-italic: #c9d1d9; |
||||
|
--color-prettylights-syntax-markup-bold: #c9d1d9; |
||||
|
--color-prettylights-syntax-markup-deleted-text: #ffdcd7; |
||||
|
--color-prettylights-syntax-markup-deleted-bg: #67060c; |
||||
|
--color-prettylights-syntax-markup-inserted-text: #aff5b4; |
||||
|
--color-prettylights-syntax-markup-inserted-bg: #033a16; |
||||
|
--color-prettylights-syntax-markup-changed-text: #ffdfb6; |
||||
|
--color-prettylights-syntax-markup-changed-bg: #5a1e02; |
||||
|
--color-prettylights-syntax-markup-ignored-text: #c9d1d9; |
||||
|
--color-prettylights-syntax-markup-ignored-bg: #1158c7; |
||||
|
--color-prettylights-syntax-meta-diff-range: #d2a8ff; |
||||
|
--color-prettylights-syntax-brackethighlighter-angle: #8b949e; |
||||
|
--color-prettylights-syntax-sublimelinter-gutter-mark: #484f58; |
||||
|
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff; |
||||
|
--color-fg-default: #c9d1d9; |
||||
|
--color-fg-muted: #8b949e; |
||||
|
--color-fg-subtle: #484f58; |
||||
|
--color-canvas-default: #0d1117; |
||||
|
--color-canvas-subtle: #161b22; |
||||
|
--color-border-default: #30363d; |
||||
|
--color-border-muted: #21262d; |
||||
|
--color-neutral-muted: rgba(110, 118, 129, 0.4); |
||||
|
--color-accent-fg: #58a6ff; |
||||
|
--color-accent-emphasis: #1f6feb; |
||||
|
--color-attention-subtle: rgba(187, 128, 9, 0.15); |
||||
|
--color-danger-fg: #f85149; |
||||
|
} |
||||
|
|
||||
|
.markdown-body { |
||||
|
-ms-text-size-adjust: 100%; |
||||
|
-webkit-text-size-adjust: 100%; |
||||
|
margin: 0; |
||||
|
color: var(--color-fg-default); |
||||
|
background-color: var(--color-canvas-default); |
||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", |
||||
|
"Segoe UI Emoji"; |
||||
|
font-size: 16px; |
||||
|
line-height: 1.5; |
||||
|
word-wrap: break-word; |
||||
|
} |
||||
|
.markdown-body .octicon { |
||||
|
display: inline-block; |
||||
|
fill: currentColor; |
||||
|
vertical-align: text-bottom; |
||||
|
} |
||||
|
.markdown-body h1:hover .anchor .octicon-link:before, |
||||
|
.markdown-body h2:hover .anchor .octicon-link:before, |
||||
|
.markdown-body h3:hover .anchor .octicon-link:before, |
||||
|
.markdown-body h4:hover .anchor .octicon-link:before, |
||||
|
.markdown-body h5:hover .anchor .octicon-link:before, |
||||
|
.markdown-body h6:hover .anchor .octicon-link:before { |
||||
|
width: 16px; |
||||
|
height: 16px; |
||||
|
content: " "; |
||||
|
display: inline-block; |
||||
|
background-color: currentColor; |
||||
|
-webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>"); |
||||
|
mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>"); |
||||
|
} |
||||
|
.markdown-body details, |
||||
|
.markdown-body figcaption, |
||||
|
.markdown-body figure { |
||||
|
display: block; |
||||
|
} |
||||
|
.markdown-body summary { |
||||
|
display: list-item; |
||||
|
} |
||||
|
.markdown-body [hidden] { |
||||
|
display: none !important; |
||||
|
} |
||||
|
.markdown-body a { |
||||
|
background-color: transparent; |
||||
|
color: var(--color-accent-fg); |
||||
|
text-decoration: none; |
||||
|
} |
||||
|
.markdown-body a:active, |
||||
|
.markdown-body a:hover { |
||||
|
outline-width: 0; |
||||
|
} |
||||
|
.markdown-body abbr[title] { |
||||
|
border-bottom: none; |
||||
|
text-decoration: underline dotted; |
||||
|
} |
||||
|
.markdown-body b, |
||||
|
.markdown-body strong { |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
.markdown-body dfn { |
||||
|
font-style: italic; |
||||
|
} |
||||
|
.markdown-body h1 { |
||||
|
margin: 0.67em 0; |
||||
|
font-weight: 600; |
||||
|
padding-bottom: 0.3em; |
||||
|
font-size: 2em; |
||||
|
border-bottom: 1px solid var(--color-border-muted); |
||||
|
} |
||||
|
.markdown-body mark { |
||||
|
background-color: var(--color-attention-subtle); |
||||
|
color: var(--color-text-primary); |
||||
|
} |
||||
|
.markdown-body small { |
||||
|
font-size: 90%; |
||||
|
} |
||||
|
.markdown-body sub, |
||||
|
.markdown-body sup { |
||||
|
font-size: 75%; |
||||
|
line-height: 0; |
||||
|
position: relative; |
||||
|
vertical-align: baseline; |
||||
|
} |
||||
|
.markdown-body sub { |
||||
|
bottom: -0.25em; |
||||
|
} |
||||
|
.markdown-body sup { |
||||
|
top: -0.5em; |
||||
|
} |
||||
|
.markdown-body img { |
||||
|
border-style: none; |
||||
|
max-width: 100%; |
||||
|
box-sizing: content-box; |
||||
|
background-color: var(--color-canvas-default); |
||||
|
} |
||||
|
.markdown-body code, |
||||
|
.markdown-body kbd, |
||||
|
.markdown-body pre, |
||||
|
.markdown-body samp { |
||||
|
font-family: monospace, monospace; |
||||
|
font-size: 1em; |
||||
|
} |
||||
|
.markdown-body figure { |
||||
|
margin: 1em 40px; |
||||
|
} |
||||
|
.markdown-body hr { |
||||
|
box-sizing: content-box; |
||||
|
overflow: hidden; |
||||
|
background: 0 0; |
||||
|
border-bottom: 1px solid var(--color-border-muted); |
||||
|
height: 0.25em; |
||||
|
padding: 0; |
||||
|
margin: 24px 0; |
||||
|
background-color: var(--color-border-default); |
||||
|
border: 0; |
||||
|
} |
||||
|
.markdown-body input { |
||||
|
font: inherit; |
||||
|
margin: 0; |
||||
|
overflow: visible; |
||||
|
font-family: inherit; |
||||
|
font-size: inherit; |
||||
|
line-height: inherit; |
||||
|
} |
||||
|
.markdown-body [type="button"], |
||||
|
.markdown-body [type="reset"], |
||||
|
.markdown-body [type="submit"] { |
||||
|
-webkit-appearance: button; |
||||
|
} |
||||
|
.markdown-body [type="button"]::-moz-focus-inner, |
||||
|
.markdown-body [type="reset"]::-moz-focus-inner, |
||||
|
.markdown-body [type="submit"]::-moz-focus-inner { |
||||
|
border-style: none; |
||||
|
padding: 0; |
||||
|
} |
||||
|
.markdown-body [type="button"]:-moz-focusring, |
||||
|
.markdown-body [type="reset"]:-moz-focusring, |
||||
|
.markdown-body [type="submit"]:-moz-focusring { |
||||
|
outline: 1px dotted ButtonText; |
||||
|
} |
||||
|
.markdown-body [type="checkbox"], |
||||
|
.markdown-body [type="radio"] { |
||||
|
box-sizing: border-box; |
||||
|
padding: 0; |
||||
|
} |
||||
|
.markdown-body [type="number"]::-webkit-inner-spin-button, |
||||
|
.markdown-body [type="number"]::-webkit-outer-spin-button { |
||||
|
height: auto; |
||||
|
} |
||||
|
.markdown-body [type="search"] { |
||||
|
-webkit-appearance: textfield; |
||||
|
outline-offset: -2px; |
||||
|
} |
||||
|
.markdown-body [type="search"]::-webkit-search-cancel-button, |
||||
|
.markdown-body [type="search"]::-webkit-search-decoration { |
||||
|
-webkit-appearance: none; |
||||
|
} |
||||
|
.markdown-body ::-webkit-input-placeholder { |
||||
|
color: inherit; |
||||
|
opacity: 0.54; |
||||
|
} |
||||
|
.markdown-body ::-webkit-file-upload-button { |
||||
|
-webkit-appearance: button; |
||||
|
font: inherit; |
||||
|
} |
||||
|
.markdown-body a:hover { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
.markdown-body hr::before { |
||||
|
display: table; |
||||
|
content: ""; |
||||
|
} |
||||
|
.markdown-body hr::after { |
||||
|
display: table; |
||||
|
clear: both; |
||||
|
content: ""; |
||||
|
} |
||||
|
.markdown-body table { |
||||
|
border-spacing: 0; |
||||
|
border-collapse: collapse; |
||||
|
display: block; |
||||
|
width: max-content; |
||||
|
max-width: 100%; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
.markdown-body td, |
||||
|
.markdown-body th { |
||||
|
padding: 0; |
||||
|
} |
||||
|
.markdown-body details summary { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.markdown-body details:not([open]) > :not(summary) { |
||||
|
display: none !important; |
||||
|
} |
||||
|
.markdown-body kbd { |
||||
|
display: inline-block; |
||||
|
padding: 3px 5px; |
||||
|
font: 11px ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; |
||||
|
line-height: 10px; |
||||
|
color: var(--color-fg-default); |
||||
|
vertical-align: middle; |
||||
|
background-color: var(--color-canvas-subtle); |
||||
|
border: solid 1px var(--color-neutral-muted); |
||||
|
border-bottom-color: var(--color-neutral-muted); |
||||
|
border-radius: 6px; |
||||
|
box-shadow: inset 0 -1px 0 var(--color-neutral-muted); |
||||
|
} |
||||
|
.markdown-body h1, |
||||
|
.markdown-body h2, |
||||
|
.markdown-body h3, |
||||
|
.markdown-body h4, |
||||
|
.markdown-body h5, |
||||
|
.markdown-body h6 { |
||||
|
margin-top: 24px; |
||||
|
margin-bottom: 16px; |
||||
|
font-weight: 600; |
||||
|
line-height: 1.25; |
||||
|
} |
||||
|
.markdown-body h2 { |
||||
|
font-weight: 600; |
||||
|
padding-bottom: 0.3em; |
||||
|
font-size: 1.5em; |
||||
|
border-bottom: 1px solid var(--color-border-muted); |
||||
|
} |
||||
|
.markdown-body h3 { |
||||
|
font-weight: 600; |
||||
|
font-size: 1.25em; |
||||
|
} |
||||
|
.markdown-body h4 { |
||||
|
font-weight: 600; |
||||
|
font-size: 1em; |
||||
|
} |
||||
|
.markdown-body h5 { |
||||
|
font-weight: 600; |
||||
|
font-size: 0.875em; |
||||
|
} |
||||
|
.markdown-body h6 { |
||||
|
font-weight: 600; |
||||
|
font-size: 0.85em; |
||||
|
color: var(--color-fg-muted); |
||||
|
} |
||||
|
.markdown-body p { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
.markdown-body blockquote { |
||||
|
margin: 0; |
||||
|
padding: 0 1em; |
||||
|
color: var(--color-fg-muted); |
||||
|
border-left: 0.25em solid var(--color-border-default); |
||||
|
} |
||||
|
.markdown-body ol, |
||||
|
.markdown-body ul { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 0; |
||||
|
padding-left: 2em; |
||||
|
} |
||||
|
.markdown-body ol ol, |
||||
|
.markdown-body ul ol { |
||||
|
list-style-type: lower-roman; |
||||
|
} |
||||
|
.markdown-body ol ol ol, |
||||
|
.markdown-body ol ul ol, |
||||
|
.markdown-body ul ol ol, |
||||
|
.markdown-body ul ul ol { |
||||
|
list-style-type: lower-alpha; |
||||
|
} |
||||
|
.markdown-body dd { |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
.markdown-body code, |
||||
|
.markdown-body tt { |
||||
|
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
.markdown-body pre { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 0; |
||||
|
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; |
||||
|
font-size: 12px; |
||||
|
word-wrap: normal; |
||||
|
} |
||||
|
.markdown-body .octicon { |
||||
|
display: inline-block; |
||||
|
overflow: visible !important; |
||||
|
vertical-align: text-bottom; |
||||
|
fill: currentColor; |
||||
|
} |
||||
|
.markdown-body ::placeholder { |
||||
|
color: var(--color-fg-subtle); |
||||
|
opacity: 1; |
||||
|
} |
||||
|
.markdown-body input::-webkit-inner-spin-button, |
||||
|
.markdown-body input::-webkit-outer-spin-button { |
||||
|
margin: 0; |
||||
|
-webkit-appearance: none; |
||||
|
appearance: none; |
||||
|
} |
||||
|
.markdown-body .pl-c { |
||||
|
color: var(--color-prettylights-syntax-comment); |
||||
|
} |
||||
|
.markdown-body .pl-c1, |
||||
|
.markdown-body .pl-s .pl-v { |
||||
|
color: var(--color-prettylights-syntax-constant); |
||||
|
} |
||||
|
.markdown-body .pl-e, |
||||
|
.markdown-body .pl-en { |
||||
|
color: var(--color-prettylights-syntax-entity); |
||||
|
} |
||||
|
.markdown-body .pl-s .pl-s1, |
||||
|
.markdown-body .pl-smi { |
||||
|
color: var(--color-prettylights-syntax-storage-modifier-import); |
||||
|
} |
||||
|
.markdown-body .pl-ent { |
||||
|
color: var(--color-prettylights-syntax-entity-tag); |
||||
|
} |
||||
|
.markdown-body .pl-k { |
||||
|
color: var(--color-prettylights-syntax-keyword); |
||||
|
} |
||||
|
.markdown-body .pl-pds, |
||||
|
.markdown-body .pl-s, |
||||
|
.markdown-body .pl-s .pl-pse .pl-s1, |
||||
|
.markdown-body .pl-sr, |
||||
|
.markdown-body .pl-sr .pl-cce, |
||||
|
.markdown-body .pl-sr .pl-sra, |
||||
|
.markdown-body .pl-sr .pl-sre { |
||||
|
color: var(--color-prettylights-syntax-string); |
||||
|
} |
||||
|
.markdown-body .pl-smw, |
||||
|
.markdown-body .pl-v { |
||||
|
color: var(--color-prettylights-syntax-variable); |
||||
|
} |
||||
|
.markdown-body .pl-bu { |
||||
|
color: var(--color-prettylights-syntax-brackethighlighter-unmatched); |
||||
|
} |
||||
|
.markdown-body .pl-ii { |
||||
|
color: var(--color-prettylights-syntax-invalid-illegal-text); |
||||
|
background-color: var(--color-prettylights-syntax-invalid-illegal-bg); |
||||
|
} |
||||
|
.markdown-body .pl-c2 { |
||||
|
color: var(--color-prettylights-syntax-carriage-return-text); |
||||
|
background-color: var(--color-prettylights-syntax-carriage-return-bg); |
||||
|
} |
||||
|
.markdown-body .pl-sr .pl-cce { |
||||
|
font-weight: 700; |
||||
|
color: var(--color-prettylights-syntax-string-regexp); |
||||
|
} |
||||
|
.markdown-body .pl-ml { |
||||
|
color: var(--color-prettylights-syntax-markup-list); |
||||
|
} |
||||
|
.markdown-body .pl-mh, |
||||
|
.markdown-body .pl-mh .pl-en, |
||||
|
.markdown-body .pl-ms { |
||||
|
font-weight: 700; |
||||
|
color: var(--color-prettylights-syntax-markup-heading); |
||||
|
} |
||||
|
.markdown-body .pl-mi { |
||||
|
font-style: italic; |
||||
|
color: var(--color-prettylights-syntax-markup-italic); |
||||
|
} |
||||
|
.markdown-body .pl-mb { |
||||
|
font-weight: 700; |
||||
|
color: var(--color-prettylights-syntax-markup-bold); |
||||
|
} |
||||
|
.markdown-body .pl-md { |
||||
|
color: var(--color-prettylights-syntax-markup-deleted-text); |
||||
|
background-color: var(--color-prettylights-syntax-markup-deleted-bg); |
||||
|
} |
||||
|
.markdown-body .pl-mi1 { |
||||
|
color: var(--color-prettylights-syntax-markup-inserted-text); |
||||
|
background-color: var(--color-prettylights-syntax-markup-inserted-bg); |
||||
|
} |
||||
|
.markdown-body .pl-mc { |
||||
|
color: var(--color-prettylights-syntax-markup-changed-text); |
||||
|
background-color: var(--color-prettylights-syntax-markup-changed-bg); |
||||
|
} |
||||
|
.markdown-body .pl-mi2 { |
||||
|
color: var(--color-prettylights-syntax-markup-ignored-text); |
||||
|
background-color: var(--color-prettylights-syntax-markup-ignored-bg); |
||||
|
} |
||||
|
.markdown-body .pl-mdr { |
||||
|
font-weight: 700; |
||||
|
color: var(--color-prettylights-syntax-meta-diff-range); |
||||
|
} |
||||
|
.markdown-body .pl-ba { |
||||
|
color: var(--color-prettylights-syntax-brackethighlighter-angle); |
||||
|
} |
||||
|
.markdown-body .pl-sg { |
||||
|
color: var(--color-prettylights-syntax-sublimelinter-gutter-mark); |
||||
|
} |
||||
|
.markdown-body .pl-corl { |
||||
|
text-decoration: underline; |
||||
|
color: var(--color-prettylights-syntax-constant-other-reference-link); |
||||
|
} |
||||
|
.markdown-body [data-catalyst] { |
||||
|
display: block; |
||||
|
} |
||||
|
.markdown-body g-emoji { |
||||
|
font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; |
||||
|
font-size: 1em; |
||||
|
font-style: normal !important; |
||||
|
font-weight: 400; |
||||
|
line-height: 1; |
||||
|
vertical-align: -0.075em; |
||||
|
} |
||||
|
.markdown-body g-emoji img { |
||||
|
width: 1em; |
||||
|
height: 1em; |
||||
|
} |
||||
|
.markdown-body::before { |
||||
|
display: table; |
||||
|
content: ""; |
||||
|
} |
||||
|
.markdown-body::after { |
||||
|
display: table; |
||||
|
clear: both; |
||||
|
content: ""; |
||||
|
} |
||||
|
.markdown-body > :first-child { |
||||
|
margin-top: 0 !important; |
||||
|
} |
||||
|
.markdown-body > :last-child { |
||||
|
margin-bottom: 0 !important; |
||||
|
} |
||||
|
.markdown-body a:not([href]) { |
||||
|
color: inherit; |
||||
|
text-decoration: none; |
||||
|
} |
||||
|
.markdown-body .absent { |
||||
|
color: var(--color-danger-fg); |
||||
|
} |
||||
|
.markdown-body .anchor { |
||||
|
float: left; |
||||
|
padding-right: 4px; |
||||
|
margin-left: -20px; |
||||
|
line-height: 1; |
||||
|
} |
||||
|
.markdown-body .anchor:focus { |
||||
|
outline: 0; |
||||
|
} |
||||
|
.markdown-body blockquote, |
||||
|
.markdown-body details, |
||||
|
.markdown-body dl, |
||||
|
.markdown-body ol, |
||||
|
.markdown-body p, |
||||
|
.markdown-body pre, |
||||
|
.markdown-body table, |
||||
|
.markdown-body ul { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 16px; |
||||
|
} |
||||
|
.markdown-body blockquote > :first-child { |
||||
|
margin-top: 0; |
||||
|
} |
||||
|
.markdown-body blockquote > :last-child { |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
.markdown-body sup > a::before { |
||||
|
content: "["; |
||||
|
} |
||||
|
.markdown-body sup > a::after { |
||||
|
content: "]"; |
||||
|
} |
||||
|
.markdown-body h1 .octicon-link, |
||||
|
.markdown-body h2 .octicon-link, |
||||
|
.markdown-body h3 .octicon-link, |
||||
|
.markdown-body h4 .octicon-link, |
||||
|
.markdown-body h5 .octicon-link, |
||||
|
.markdown-body h6 .octicon-link { |
||||
|
color: var(--color-fg-default); |
||||
|
vertical-align: middle; |
||||
|
visibility: hidden; |
||||
|
} |
||||
|
.markdown-body h1:hover .anchor, |
||||
|
.markdown-body h2:hover .anchor, |
||||
|
.markdown-body h3:hover .anchor, |
||||
|
.markdown-body h4:hover .anchor, |
||||
|
.markdown-body h5:hover .anchor, |
||||
|
.markdown-body h6:hover .anchor { |
||||
|
text-decoration: none; |
||||
|
} |
||||
|
.markdown-body h1:hover .anchor .octicon-link, |
||||
|
.markdown-body h2:hover .anchor .octicon-link, |
||||
|
.markdown-body h3:hover .anchor .octicon-link, |
||||
|
.markdown-body h4:hover .anchor .octicon-link, |
||||
|
.markdown-body h5:hover .anchor .octicon-link, |
||||
|
.markdown-body h6:hover .anchor .octicon-link { |
||||
|
visibility: visible; |
||||
|
} |
||||
|
.markdown-body h1 code, |
||||
|
.markdown-body h1 tt, |
||||
|
.markdown-body h2 code, |
||||
|
.markdown-body h2 tt, |
||||
|
.markdown-body h3 code, |
||||
|
.markdown-body h3 tt, |
||||
|
.markdown-body h4 code, |
||||
|
.markdown-body h4 tt, |
||||
|
.markdown-body h5 code, |
||||
|
.markdown-body h5 tt, |
||||
|
.markdown-body h6 code, |
||||
|
.markdown-body h6 tt { |
||||
|
padding: 0 0.2em; |
||||
|
font-size: inherit; |
||||
|
} |
||||
|
.markdown-body ol.no-list, |
||||
|
.markdown-body ul.no-list { |
||||
|
padding: 0; |
||||
|
list-style-type: none; |
||||
|
} |
||||
|
.markdown-body ol[type="1"] { |
||||
|
list-style-type: decimal; |
||||
|
} |
||||
|
.markdown-body ol[type="a"] { |
||||
|
list-style-type: lower-alpha; |
||||
|
} |
||||
|
.markdown-body ol[type="i"] { |
||||
|
list-style-type: lower-roman; |
||||
|
} |
||||
|
.markdown-body div > ol:not([type]) { |
||||
|
list-style-type: decimal; |
||||
|
} |
||||
|
.markdown-body ol ol, |
||||
|
.markdown-body ol ul, |
||||
|
.markdown-body ul ol, |
||||
|
.markdown-body ul ul { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
.markdown-body li > p { |
||||
|
margin-top: 16px; |
||||
|
} |
||||
|
.markdown-body li + li { |
||||
|
margin-top: 0.25em; |
||||
|
} |
||||
|
.markdown-body dl { |
||||
|
padding: 0; |
||||
|
} |
||||
|
.markdown-body dl dt { |
||||
|
padding: 0; |
||||
|
margin-top: 16px; |
||||
|
font-size: 1em; |
||||
|
font-style: italic; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
.markdown-body dl dd { |
||||
|
padding: 0 16px; |
||||
|
margin-bottom: 16px; |
||||
|
} |
||||
|
.markdown-body table th { |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
.markdown-body table td, |
||||
|
.markdown-body table th { |
||||
|
padding: 6px 13px; |
||||
|
border: 1px solid var(--color-border-default); |
||||
|
} |
||||
|
.markdown-body table tr { |
||||
|
background-color: var(--color-canvas-default); |
||||
|
border-top: 1px solid var(--color-border-muted); |
||||
|
} |
||||
|
.markdown-body table tr:nth-child(2n) { |
||||
|
background-color: var(--color-canvas-subtle); |
||||
|
} |
||||
|
.markdown-body table img { |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
.markdown-body img[align="right"] { |
||||
|
padding-left: 20px; |
||||
|
} |
||||
|
.markdown-body img[align="left"] { |
||||
|
padding-right: 20px; |
||||
|
} |
||||
|
.markdown-body .emoji { |
||||
|
max-width: none; |
||||
|
vertical-align: text-top; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
.markdown-body span.frame { |
||||
|
display: block; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.markdown-body span.frame > span { |
||||
|
display: block; |
||||
|
float: left; |
||||
|
width: auto; |
||||
|
padding: 7px; |
||||
|
margin: 13px 0 0; |
||||
|
overflow: hidden; |
||||
|
border: 1px solid var(--color-border-default); |
||||
|
} |
||||
|
.markdown-body span.frame span img { |
||||
|
display: block; |
||||
|
float: left; |
||||
|
} |
||||
|
.markdown-body span.frame span span { |
||||
|
display: block; |
||||
|
padding: 5px 0 0; |
||||
|
clear: both; |
||||
|
color: var(--color-fg-default); |
||||
|
} |
||||
|
.markdown-body span.align-center { |
||||
|
display: block; |
||||
|
overflow: hidden; |
||||
|
clear: both; |
||||
|
} |
||||
|
.markdown-body span.align-center > span { |
||||
|
display: block; |
||||
|
margin: 13px auto 0; |
||||
|
overflow: hidden; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.markdown-body span.align-center span img { |
||||
|
margin: 0 auto; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.markdown-body span.align-right { |
||||
|
display: block; |
||||
|
overflow: hidden; |
||||
|
clear: both; |
||||
|
} |
||||
|
.markdown-body span.align-right > span { |
||||
|
display: block; |
||||
|
margin: 13px 0 0; |
||||
|
overflow: hidden; |
||||
|
text-align: right; |
||||
|
} |
||||
|
.markdown-body span.align-right span img { |
||||
|
margin: 0; |
||||
|
text-align: right; |
||||
|
} |
||||
|
.markdown-body span.float-left { |
||||
|
display: block; |
||||
|
float: left; |
||||
|
margin-right: 13px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.markdown-body span.float-left span { |
||||
|
margin: 13px 0 0; |
||||
|
} |
||||
|
.markdown-body span.float-right { |
||||
|
display: block; |
||||
|
float: right; |
||||
|
margin-left: 13px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.markdown-body span.float-right > span { |
||||
|
display: block; |
||||
|
margin: 13px auto 0; |
||||
|
overflow: hidden; |
||||
|
text-align: right; |
||||
|
} |
||||
|
.markdown-body code, |
||||
|
.markdown-body tt { |
||||
|
padding: 0.2em 0.4em; |
||||
|
margin: 0; |
||||
|
font-size: 85%; |
||||
|
background-color: var(--color-neutral-muted); |
||||
|
border-radius: 6px; |
||||
|
} |
||||
|
.markdown-body code br, |
||||
|
.markdown-body tt br { |
||||
|
display: none; |
||||
|
} |
||||
|
.markdown-body del code { |
||||
|
text-decoration: inherit; |
||||
|
} |
||||
|
.markdown-body pre code { |
||||
|
font-size: 100%; |
||||
|
} |
||||
|
.markdown-body pre > code { |
||||
|
padding: 0; |
||||
|
margin: 0; |
||||
|
word-break: normal; |
||||
|
white-space: pre; |
||||
|
background: 0 0; |
||||
|
border: 0; |
||||
|
} |
||||
|
.markdown-body .highlight { |
||||
|
margin-bottom: 16px; |
||||
|
} |
||||
|
.markdown-body .highlight pre { |
||||
|
margin-bottom: 0; |
||||
|
word-break: normal; |
||||
|
} |
||||
|
.markdown-body .highlight pre, |
||||
|
.markdown-body pre { |
||||
|
padding: 16px; |
||||
|
overflow: auto; |
||||
|
font-size: 85%; |
||||
|
line-height: 1.45; |
||||
|
background-color: var(--color-canvas-subtle); |
||||
|
border-radius: 6px; |
||||
|
} |
||||
|
.markdown-body pre code, |
||||
|
.markdown-body pre tt { |
||||
|
display: inline; |
||||
|
max-width: auto; |
||||
|
padding: 0; |
||||
|
margin: 0; |
||||
|
overflow: visible; |
||||
|
line-height: inherit; |
||||
|
word-wrap: normal; |
||||
|
background-color: transparent; |
||||
|
border: 0; |
||||
|
} |
||||
|
.markdown-body .csv-data td, |
||||
|
.markdown-body .csv-data th { |
||||
|
padding: 5px; |
||||
|
overflow: hidden; |
||||
|
font-size: 12px; |
||||
|
line-height: 1; |
||||
|
text-align: left; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
.markdown-body .csv-data .blob-num { |
||||
|
padding: 10px 8px 9px; |
||||
|
text-align: right; |
||||
|
background: var(--color-canvas-default); |
||||
|
border: 0; |
||||
|
} |
||||
|
.markdown-body .csv-data tr { |
||||
|
border-top: 0; |
||||
|
} |
||||
|
.markdown-body .csv-data th { |
||||
|
font-weight: 600; |
||||
|
background: var(--color-canvas-subtle); |
||||
|
border-top: 0; |
||||
|
} |
||||
|
.markdown-body .footnotes { |
||||
|
font-size: 12px; |
||||
|
color: var(--color-fg-muted); |
||||
|
border-top: 1px solid var(--color-border-default); |
||||
|
} |
||||
|
.markdown-body .footnotes ol { |
||||
|
padding-left: 16px; |
||||
|
} |
||||
|
.markdown-body .footnotes li { |
||||
|
position: relative; |
||||
|
} |
||||
|
.markdown-body .footnotes li:target::before { |
||||
|
position: absolute; |
||||
|
top: -8px; |
||||
|
right: -8px; |
||||
|
bottom: -8px; |
||||
|
left: -24px; |
||||
|
pointer-events: none; |
||||
|
content: ""; |
||||
|
border: 2px solid var(--color-accent-emphasis); |
||||
|
border-radius: 6px; |
||||
|
} |
||||
|
.markdown-body .footnotes li:target { |
||||
|
color: var(--color-fg-default); |
||||
|
} |
||||
|
.markdown-body .footnotes .data-footnote-backref g-emoji { |
||||
|
font-family: monospace; |
||||
|
} |
||||
|
.markdown-body .task-list-item { |
||||
|
list-style-type: none; |
||||
|
} |
||||
|
.markdown-body .task-list-item label { |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
.markdown-body .task-list-item.enabled label { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.markdown-body .task-list-item + .task-list-item { |
||||
|
margin-top: 3px; |
||||
|
} |
||||
|
.markdown-body .task-list-item .handle { |
||||
|
display: none; |
||||
|
} |
||||
|
.markdown-body .task-list-item-checkbox { |
||||
|
margin: 0 0.2em 0.25em -1.6em; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox { |
||||
|
margin: 0 -1.6em 0.25em 0.2em; |
||||
|
} |
||||
|
.markdown-body ::-webkit-calendar-picker-indicator { |
||||
|
filter: invert(50%); |
||||
|
} |
||||
|
/*# sourceMappingURL=/sm/64d6754651b08011e56029ac6df83bb47c5a570dab69e24e289f71fd97eb927d.map */ |
@ -0,0 +1,111 @@ |
|||||
|
/*! |
||||
|
Theme: Default |
||||
|
Description: Original highlight.js style |
||||
|
Author: (c) Ivan Sagalaev <maniac@softwaremaniacs.org> |
||||
|
Maintainer: @highlightjs/core-team |
||||
|
Website: https://highlightjs.org/ |
||||
|
License: see project LICENSE |
||||
|
Touched: 2021 |
||||
|
*/ |
||||
|
pre code.hljs { |
||||
|
display: block; |
||||
|
overflow-x: auto; |
||||
|
padding: 1em; |
||||
|
} |
||||
|
code.hljs { |
||||
|
padding: 3px 5px; |
||||
|
} |
||||
|
|
||||
|
.hljs { |
||||
|
--color: #444; |
||||
|
--background: #f3f3f3; |
||||
|
--comment: #697070; |
||||
|
--tag: #444a; |
||||
|
--tag-attr: #444; |
||||
|
--type: #800; |
||||
|
--title: #800; |
||||
|
--link: #ab5656; |
||||
|
--literal: #695; |
||||
|
--code: #397300; |
||||
|
--meta: #1f7199; |
||||
|
--meta-string: #38a; |
||||
|
} |
||||
|
|
||||
|
body.dark .hljs { |
||||
|
--color: var(--dark-text-color); |
||||
|
--background: var(--dark-bg-color); |
||||
|
--keyword: #fff; |
||||
|
--comment: #979797; |
||||
|
--tag: #fff; |
||||
|
--type: #d88; |
||||
|
} |
||||
|
|
||||
|
.hljs { |
||||
|
background: var(--background); |
||||
|
color: var(--color); |
||||
|
} |
||||
|
.hljs-comment { |
||||
|
color: var(--comment); |
||||
|
} |
||||
|
.hljs-punctuation, |
||||
|
.hljs-tag { |
||||
|
color: var(--tag); |
||||
|
} |
||||
|
.hljs-tag .hljs-attr, |
||||
|
.hljs-tag .hljs-name { |
||||
|
color: var(--tag-attr); |
||||
|
} |
||||
|
.hljs-attribute, |
||||
|
.hljs-doctag, |
||||
|
.hljs-keyword, |
||||
|
.hljs-meta .hljs-keyword, |
||||
|
.hljs-name, |
||||
|
.hljs-selector-tag { |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
.hljs-deletion, |
||||
|
.hljs-number, |
||||
|
.hljs-quote, |
||||
|
.hljs-selector-class, |
||||
|
.hljs-selector-id, |
||||
|
.hljs-string, |
||||
|
.hljs-template-tag, |
||||
|
.hljs-type { |
||||
|
color: var(--type); |
||||
|
} |
||||
|
.hljs-section, |
||||
|
.hljs-title { |
||||
|
color: var(--title); |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
.hljs-link, |
||||
|
.hljs-operator, |
||||
|
.hljs-regexp, |
||||
|
.hljs-selector-attr, |
||||
|
.hljs-selector-pseudo, |
||||
|
.hljs-symbol, |
||||
|
.hljs-template-variable, |
||||
|
.hljs-variable { |
||||
|
color: var(--link); |
||||
|
} |
||||
|
.hljs-literal { |
||||
|
color: var(--literal); |
||||
|
} |
||||
|
.hljs-addition, |
||||
|
.hljs-built_in, |
||||
|
.hljs-bullet, |
||||
|
.hljs-code { |
||||
|
color: var(--code); |
||||
|
} |
||||
|
.hljs-meta { |
||||
|
color: var(--meta); |
||||
|
} |
||||
|
.hljs-meta .hljs-string { |
||||
|
color: var(--meta-string); |
||||
|
} |
||||
|
.hljs-emphasis { |
||||
|
font-style: italic; |
||||
|
} |
||||
|
.hljs-strong { |
||||
|
font-weight: 700; |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
function e(e){this.message=e}e.prototype=new Error,e.prototype.name="InvalidCharacterError";var r="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(r){var t=String(r).replace(/=+$/,"");if(t.length%4==1)throw new e("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,o,a=0,i=0,c="";o=t.charAt(i++);~o&&(n=a%4?64*n+o:o,a++%4)?c+=String.fromCharCode(255&n>>(-2*a&6)):0)o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(o);return c};function t(e){var t=e.replace(/-/g,"+").replace(/_/g,"/");switch(t.length%4){case 0:break;case 2:t+="==";break;case 3:t+="=";break;default:throw"Illegal base64url string!"}try{return function(e){return decodeURIComponent(r(e).replace(/(.)/g,(function(e,r){var t=r.charCodeAt(0).toString(16).toUpperCase();return t.length<2&&(t="0"+t),"%"+t})))}(t)}catch(e){return r(t)}}function n(e){this.message=e}function o(e,r){if("string"!=typeof e)throw new n("Invalid token specified");var o=!0===(r=r||{}).header?0:1;try{return JSON.parse(t(e.split(".")[o]))}catch(e){throw new n("Invalid token specified: "+e.message)}}n.prototype=new Error,n.prototype.name="InvalidTokenError";export default o;export{n as InvalidTokenError}; |
||||
|
//# sourceMappingURL=jwt-decode.esm.js.map
|
@ -0,0 +1,74 @@ |
|||||
|
/* Make clicks pass-through */ |
||||
|
#nprogress { |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
#nprogress .bar { |
||||
|
background: #29d; |
||||
|
|
||||
|
position: fixed; |
||||
|
z-index: 1031; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
|
||||
|
width: 100%; |
||||
|
height: 2px; |
||||
|
} |
||||
|
|
||||
|
/* Fancy blur effect */ |
||||
|
#nprogress .peg { |
||||
|
display: block; |
||||
|
position: absolute; |
||||
|
right: 0px; |
||||
|
width: 100px; |
||||
|
height: 100%; |
||||
|
box-shadow: 0 0 10px #29d, 0 0 5px #29d; |
||||
|
opacity: 1.0; |
||||
|
|
||||
|
-webkit-transform: rotate(3deg) translate(0px, -4px); |
||||
|
-ms-transform: rotate(3deg) translate(0px, -4px); |
||||
|
transform: rotate(3deg) translate(0px, -4px); |
||||
|
} |
||||
|
|
||||
|
/* Remove these to get rid of the spinner */ |
||||
|
#nprogress .spinner { |
||||
|
display: block; |
||||
|
position: fixed; |
||||
|
z-index: 1031; |
||||
|
top: 15px; |
||||
|
right: 15px; |
||||
|
} |
||||
|
|
||||
|
#nprogress .spinner-icon { |
||||
|
width: 18px; |
||||
|
height: 18px; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
border: solid 2px transparent; |
||||
|
border-top-color: #29d; |
||||
|
border-left-color: #29d; |
||||
|
border-radius: 50%; |
||||
|
|
||||
|
-webkit-animation: nprogress-spinner 400ms linear infinite; |
||||
|
animation: nprogress-spinner 400ms linear infinite; |
||||
|
} |
||||
|
|
||||
|
.nprogress-custom-parent { |
||||
|
overflow: hidden; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.nprogress-custom-parent #nprogress .spinner, |
||||
|
.nprogress-custom-parent #nprogress .bar { |
||||
|
position: absolute; |
||||
|
} |
||||
|
|
||||
|
@-webkit-keyframes nprogress-spinner { |
||||
|
0% { -webkit-transform: rotate(0deg); } |
||||
|
100% { -webkit-transform: rotate(360deg); } |
||||
|
} |
||||
|
@keyframes nprogress-spinner { |
||||
|
0% { transform: rotate(0deg); } |
||||
|
100% { transform: rotate(360deg); } |
||||
|
} |
||||
|
|
@ -0,0 +1,288 @@ |
|||||
|
const __commonJS = (cb, mod) => function __require() { |
||||
|
return mod || (0, cb[Object.getOwnPropertyNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; |
||||
|
}; |
||||
|
|
||||
|
// node_modules/nprogress/nprogress.js
|
||||
|
var require_nprogress = __commonJS({ |
||||
|
"node_modules/nprogress/nprogress.js"(exports, module) { |
||||
|
(function (root, factory) { |
||||
|
if (typeof define === "function" && define.amd) { |
||||
|
define(factory); |
||||
|
} else if (typeof exports === "object") { |
||||
|
module.exports = factory(); |
||||
|
} else { |
||||
|
root.NProgress = factory(); |
||||
|
} |
||||
|
})(exports, function () { |
||||
|
var NProgress = {}; |
||||
|
NProgress.version = "0.2.0"; |
||||
|
var Settings = NProgress.settings = { |
||||
|
minimum: 0.08, |
||||
|
easing: "ease", |
||||
|
positionUsing: "", |
||||
|
speed: 200, |
||||
|
trickle: true, |
||||
|
trickleRate: 0.02, |
||||
|
trickleSpeed: 800, |
||||
|
showSpinner: true, |
||||
|
barSelector: '[role="bar"]', |
||||
|
spinnerSelector: '[role="spinner"]', |
||||
|
parent: "body", |
||||
|
template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>' |
||||
|
}; |
||||
|
NProgress.configure = function (options) { |
||||
|
var key, value; |
||||
|
for (key in options) { |
||||
|
value = options[key]; |
||||
|
if (value !== void 0 && options.hasOwnProperty(key)) |
||||
|
Settings[key] = value; |
||||
|
} |
||||
|
return this; |
||||
|
}; |
||||
|
NProgress.status = null; |
||||
|
NProgress.set = function (n) { |
||||
|
var started = NProgress.isStarted(); |
||||
|
n = clamp(n, Settings.minimum, 1); |
||||
|
NProgress.status = n === 1 ? null : n; |
||||
|
var progress = NProgress.render(!started), bar = progress.querySelector(Settings.barSelector), speed = Settings.speed, ease = Settings.easing; |
||||
|
progress.offsetWidth; |
||||
|
queue(function (next) { |
||||
|
if (Settings.positionUsing === "") |
||||
|
Settings.positionUsing = NProgress.getPositioningCSS(); |
||||
|
css(bar, barPositionCSS(n, speed, ease)); |
||||
|
if (n === 1) { |
||||
|
css(progress, { |
||||
|
transition: "none", |
||||
|
opacity: 1 |
||||
|
}); |
||||
|
progress.offsetWidth; |
||||
|
setTimeout(function () { |
||||
|
css(progress, { |
||||
|
transition: "all " + speed + "ms linear", |
||||
|
opacity: 0 |
||||
|
}); |
||||
|
setTimeout(function () { |
||||
|
NProgress.remove(); |
||||
|
next(); |
||||
|
}, speed); |
||||
|
}, speed); |
||||
|
} else { |
||||
|
setTimeout(next, speed); |
||||
|
} |
||||
|
}); |
||||
|
return this; |
||||
|
}; |
||||
|
NProgress.isStarted = function () { |
||||
|
return typeof NProgress.status === "number"; |
||||
|
}; |
||||
|
NProgress.start = function () { |
||||
|
if (!NProgress.status) |
||||
|
NProgress.set(0); |
||||
|
var work = function () { |
||||
|
setTimeout(function () { |
||||
|
if (!NProgress.status) |
||||
|
return; |
||||
|
NProgress.trickle(); |
||||
|
work(); |
||||
|
}, Settings.trickleSpeed); |
||||
|
}; |
||||
|
if (Settings.trickle) |
||||
|
work(); |
||||
|
return this; |
||||
|
}; |
||||
|
NProgress.done = function (force) { |
||||
|
if (!force && !NProgress.status) |
||||
|
return this; |
||||
|
return NProgress.inc(0.3 + 0.5 * Math.random()).set(1); |
||||
|
}; |
||||
|
NProgress.inc = function (amount) { |
||||
|
var n = NProgress.status; |
||||
|
if (!n) { |
||||
|
return NProgress.start(); |
||||
|
} else { |
||||
|
if (typeof amount !== "number") { |
||||
|
amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95); |
||||
|
} |
||||
|
n = clamp(n + amount, 0, 0.994); |
||||
|
return NProgress.set(n); |
||||
|
} |
||||
|
}; |
||||
|
NProgress.trickle = function () { |
||||
|
return NProgress.inc(Math.random() * Settings.trickleRate); |
||||
|
}; |
||||
|
(function () { |
||||
|
var initial = 0, current = 0; |
||||
|
NProgress.promise = function ($promise) { |
||||
|
if (!$promise || $promise.state() === "resolved") { |
||||
|
return this; |
||||
|
} |
||||
|
if (current === 0) { |
||||
|
NProgress.start(); |
||||
|
} |
||||
|
initial++; |
||||
|
current++; |
||||
|
$promise.always(function () { |
||||
|
current--; |
||||
|
if (current === 0) { |
||||
|
initial = 0; |
||||
|
NProgress.done(); |
||||
|
} else { |
||||
|
NProgress.set((initial - current) / initial); |
||||
|
} |
||||
|
}); |
||||
|
return this; |
||||
|
}; |
||||
|
})(); |
||||
|
NProgress.render = function (fromStart) { |
||||
|
if (NProgress.isRendered()) |
||||
|
return document.getElementById("nprogress"); |
||||
|
addClass(document.documentElement, "nprogress-busy"); |
||||
|
var progress = document.createElement("div"); |
||||
|
progress.id = "nprogress"; |
||||
|
progress.innerHTML = Settings.template; |
||||
|
var bar = progress.querySelector(Settings.barSelector), perc = fromStart ? "-100" : toBarPerc(NProgress.status || 0), parent = document.querySelector(Settings.parent), spinner; |
||||
|
css(bar, { |
||||
|
transition: "all 0 linear", |
||||
|
transform: "translate3d(" + perc + "%,0,0)" |
||||
|
}); |
||||
|
if (!Settings.showSpinner) { |
||||
|
spinner = progress.querySelector(Settings.spinnerSelector); |
||||
|
spinner && removeElement(spinner); |
||||
|
} |
||||
|
if (parent != document.body) { |
||||
|
addClass(parent, "nprogress-custom-parent"); |
||||
|
} |
||||
|
parent.appendChild(progress); |
||||
|
return progress; |
||||
|
}; |
||||
|
NProgress.remove = function () { |
||||
|
removeClass(document.documentElement, "nprogress-busy"); |
||||
|
removeClass(document.querySelector(Settings.parent), "nprogress-custom-parent"); |
||||
|
var progress = document.getElementById("nprogress"); |
||||
|
progress && removeElement(progress); |
||||
|
}; |
||||
|
NProgress.isRendered = function () { |
||||
|
return !!document.getElementById("nprogress"); |
||||
|
}; |
||||
|
NProgress.getPositioningCSS = function () { |
||||
|
var bodyStyle = document.body.style; |
||||
|
var vendorPrefix = "WebkitTransform" in bodyStyle ? "Webkit" : "MozTransform" in bodyStyle ? "Moz" : "msTransform" in bodyStyle ? "ms" : "OTransform" in bodyStyle ? "O" : ""; |
||||
|
if (vendorPrefix + "Perspective" in bodyStyle) { |
||||
|
return "translate3d"; |
||||
|
} else if (vendorPrefix + "Transform" in bodyStyle) { |
||||
|
return "translate"; |
||||
|
} else { |
||||
|
return "margin"; |
||||
|
} |
||||
|
}; |
||||
|
function clamp(n, min, max) { |
||||
|
if (n < min) |
||||
|
return min; |
||||
|
if (n > max) |
||||
|
return max; |
||||
|
return n; |
||||
|
} |
||||
|
function toBarPerc(n) { |
||||
|
return (-1 + n) * 100; |
||||
|
} |
||||
|
function barPositionCSS(n, speed, ease) { |
||||
|
var barCSS; |
||||
|
if (Settings.positionUsing === "translate3d") { |
||||
|
barCSS = { transform: "translate3d(" + toBarPerc(n) + "%,0,0)" }; |
||||
|
} else if (Settings.positionUsing === "translate") { |
||||
|
barCSS = { transform: "translate(" + toBarPerc(n) + "%,0)" }; |
||||
|
} else { |
||||
|
barCSS = { "margin-left": toBarPerc(n) + "%" }; |
||||
|
} |
||||
|
barCSS.transition = "all " + speed + "ms " + ease; |
||||
|
return barCSS; |
||||
|
} |
||||
|
var queue = function () { |
||||
|
var pending = []; |
||||
|
function next() { |
||||
|
var fn = pending.shift(); |
||||
|
if (fn) { |
||||
|
fn(next); |
||||
|
} |
||||
|
} |
||||
|
return function (fn) { |
||||
|
pending.push(fn); |
||||
|
if (pending.length == 1) |
||||
|
next(); |
||||
|
}; |
||||
|
}(); |
||||
|
var css = function () { |
||||
|
var cssPrefixes = ["Webkit", "O", "Moz", "ms"], cssProps = {}; |
||||
|
function camelCase(string) { |
||||
|
return string.replace(/^-ms-/, "ms-").replace(/-([\da-z])/gi, function (match, letter) { |
||||
|
return letter.toUpperCase(); |
||||
|
}); |
||||
|
} |
||||
|
function getVendorProp(name) { |
||||
|
var style = document.body.style; |
||||
|
if (name in style) |
||||
|
return name; |
||||
|
var i = cssPrefixes.length, capName = name.charAt(0).toUpperCase() + name.slice(1), vendorName; |
||||
|
while (i--) { |
||||
|
vendorName = cssPrefixes[i] + capName; |
||||
|
if (vendorName in style) |
||||
|
return vendorName; |
||||
|
} |
||||
|
return name; |
||||
|
} |
||||
|
function getStyleProp(name) { |
||||
|
name = camelCase(name); |
||||
|
return cssProps[name] || (cssProps[name] = getVendorProp(name)); |
||||
|
} |
||||
|
function applyCss(element, prop, value) { |
||||
|
prop = getStyleProp(prop); |
||||
|
element.style[prop] = value; |
||||
|
} |
||||
|
return function (element, properties) { |
||||
|
var args = arguments, prop, value; |
||||
|
if (args.length == 2) { |
||||
|
for (prop in properties) { |
||||
|
value = properties[prop]; |
||||
|
if (value !== void 0 && properties.hasOwnProperty(prop)) |
||||
|
applyCss(element, prop, value); |
||||
|
} |
||||
|
} else { |
||||
|
applyCss(element, args[1], args[2]); |
||||
|
} |
||||
|
}; |
||||
|
}(); |
||||
|
function hasClass(element, name) { |
||||
|
var list = typeof element == "string" ? element : classList(element); |
||||
|
return list.indexOf(" " + name + " ") >= 0; |
||||
|
} |
||||
|
function addClass(element, name) { |
||||
|
var oldList = classList(element), newList = oldList + name; |
||||
|
if (hasClass(oldList, name)) |
||||
|
return; |
||||
|
element.className = newList.substring(1); |
||||
|
} |
||||
|
function removeClass(element, name) { |
||||
|
var oldList = classList(element), newList; |
||||
|
if (!hasClass(element, name)) |
||||
|
return; |
||||
|
newList = oldList.replace(" " + name + " ", " "); |
||||
|
element.className = newList.substring(1, newList.length - 1); |
||||
|
} |
||||
|
function classList(element) { |
||||
|
return (" " + (element.className || "") + " ").replace(/\s+/gi, " "); |
||||
|
} |
||||
|
function removeElement(element) { |
||||
|
element && element.parentNode && element.parentNode.removeChild(element); |
||||
|
} |
||||
|
return NProgress; |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
export default require_nprogress(); |
||||
|
/*! Bundled license information: |
||||
|
|
||||
|
nprogress/nprogress.js: |
||||
|
(* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
|
||||
|
* @license MIT *) |
||||
|
*/ |
||||
|
|
@ -0,0 +1,206 @@ |
|||||
|
const __commonJS = (cb, mod) => function __require() { |
||||
|
return mod || (0, cb[Object.getOwnPropertyNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; |
||||
|
}; |
||||
|
|
||||
|
// node_modules/pubsub-js/src/pubsub.js
|
||||
|
var require_pubsub = __commonJS({ |
||||
|
"node_modules/pubsub-js/src/pubsub.js"(exports, module) { |
||||
|
(function(root, factory) { |
||||
|
"use strict"; |
||||
|
var PubSub = {}; |
||||
|
if (root.PubSub) { |
||||
|
PubSub = root.PubSub; |
||||
|
console.warn("PubSub already loaded, using existing version"); |
||||
|
} else { |
||||
|
root.PubSub = PubSub; |
||||
|
factory(PubSub); |
||||
|
} |
||||
|
if (typeof exports === "object") { |
||||
|
if (module !== void 0 && module.exports) { |
||||
|
exports = module.exports = PubSub; |
||||
|
} |
||||
|
exports.PubSub = PubSub; |
||||
|
module.exports = exports = PubSub; |
||||
|
} else if (typeof define === "function" && define.amd) { |
||||
|
define(function() { |
||||
|
return PubSub; |
||||
|
}); |
||||
|
} |
||||
|
})(typeof window === "object" && window || exports, function(PubSub) { |
||||
|
"use strict"; |
||||
|
var messages = {}, lastUid = -1, ALL_SUBSCRIBING_MSG = "*"; |
||||
|
function hasKeys(obj) { |
||||
|
var key; |
||||
|
for (key in obj) { |
||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
function throwException(ex) { |
||||
|
return function reThrowException() { |
||||
|
throw ex; |
||||
|
}; |
||||
|
} |
||||
|
function callSubscriberWithDelayedExceptions(subscriber, message, data) { |
||||
|
try { |
||||
|
subscriber(message, data); |
||||
|
} catch (ex) { |
||||
|
setTimeout(throwException(ex), 0); |
||||
|
} |
||||
|
} |
||||
|
function callSubscriberWithImmediateExceptions(subscriber, message, data) { |
||||
|
subscriber(message, data); |
||||
|
} |
||||
|
function deliverMessage(originalMessage, matchedMessage, data, immediateExceptions) { |
||||
|
var subscribers = messages[matchedMessage], callSubscriber = immediateExceptions ? callSubscriberWithImmediateExceptions : callSubscriberWithDelayedExceptions, s; |
||||
|
if (!Object.prototype.hasOwnProperty.call(messages, matchedMessage)) { |
||||
|
return; |
||||
|
} |
||||
|
for (s in subscribers) { |
||||
|
if (Object.prototype.hasOwnProperty.call(subscribers, s)) { |
||||
|
callSubscriber(subscribers[s], originalMessage, data); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
function createDeliveryFunction(message, data, immediateExceptions) { |
||||
|
return function deliverNamespaced() { |
||||
|
var topic = String(message), position = topic.lastIndexOf("."); |
||||
|
deliverMessage(message, message, data, immediateExceptions); |
||||
|
while (position !== -1) { |
||||
|
topic = topic.substr(0, position); |
||||
|
position = topic.lastIndexOf("."); |
||||
|
deliverMessage(message, topic, data, immediateExceptions); |
||||
|
} |
||||
|
deliverMessage(message, ALL_SUBSCRIBING_MSG, data, immediateExceptions); |
||||
|
}; |
||||
|
} |
||||
|
function hasDirectSubscribersFor(message) { |
||||
|
var topic = String(message), found = Boolean(Object.prototype.hasOwnProperty.call(messages, topic) && hasKeys(messages[topic])); |
||||
|
return found; |
||||
|
} |
||||
|
function messageHasSubscribers(message) { |
||||
|
var topic = String(message), found = hasDirectSubscribersFor(topic) || hasDirectSubscribersFor(ALL_SUBSCRIBING_MSG), position = topic.lastIndexOf("."); |
||||
|
while (!found && position !== -1) { |
||||
|
topic = topic.substr(0, position); |
||||
|
position = topic.lastIndexOf("."); |
||||
|
found = hasDirectSubscribersFor(topic); |
||||
|
} |
||||
|
return found; |
||||
|
} |
||||
|
function publish(message, data, sync, immediateExceptions) { |
||||
|
message = typeof message === "symbol" ? message.toString() : message; |
||||
|
var deliver = createDeliveryFunction(message, data, immediateExceptions), hasSubscribers = messageHasSubscribers(message); |
||||
|
if (!hasSubscribers) { |
||||
|
return false; |
||||
|
} |
||||
|
if (sync === true) { |
||||
|
deliver(); |
||||
|
} else { |
||||
|
setTimeout(deliver, 0); |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
PubSub.publish = function(message, data) { |
||||
|
return publish(message, data, false, PubSub.immediateExceptions); |
||||
|
}; |
||||
|
PubSub.publishSync = function(message, data) { |
||||
|
return publish(message, data, true, PubSub.immediateExceptions); |
||||
|
}; |
||||
|
PubSub.subscribe = function(message, func) { |
||||
|
if (typeof func !== "function") { |
||||
|
return false; |
||||
|
} |
||||
|
message = typeof message === "symbol" ? message.toString() : message; |
||||
|
if (!Object.prototype.hasOwnProperty.call(messages, message)) { |
||||
|
messages[message] = {}; |
||||
|
} |
||||
|
var token = "uid_" + String(++lastUid); |
||||
|
messages[message][token] = func; |
||||
|
return token; |
||||
|
}; |
||||
|
PubSub.subscribeAll = function(func) { |
||||
|
return PubSub.subscribe(ALL_SUBSCRIBING_MSG, func); |
||||
|
}; |
||||
|
PubSub.subscribeOnce = function(message, func) { |
||||
|
var token = PubSub.subscribe(message, function() { |
||||
|
PubSub.unsubscribe(token); |
||||
|
func.apply(this, arguments); |
||||
|
}); |
||||
|
return PubSub; |
||||
|
}; |
||||
|
PubSub.clearAllSubscriptions = function clearAllSubscriptions() { |
||||
|
messages = {}; |
||||
|
}; |
||||
|
PubSub.clearSubscriptions = function clearSubscriptions(topic) { |
||||
|
var m; |
||||
|
for (m in messages) { |
||||
|
if (Object.prototype.hasOwnProperty.call(messages, m) && m.indexOf(topic) === 0) { |
||||
|
delete messages[m]; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
PubSub.countSubscriptions = function countSubscriptions(topic) { |
||||
|
var m; |
||||
|
var token; |
||||
|
var count = 0; |
||||
|
for (m in messages) { |
||||
|
if (Object.prototype.hasOwnProperty.call(messages, m) && m.indexOf(topic) === 0) { |
||||
|
for (token in messages[m]) { |
||||
|
count++; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return count; |
||||
|
}; |
||||
|
PubSub.getSubscriptions = function getSubscriptions(topic) { |
||||
|
var m; |
||||
|
var list = []; |
||||
|
for (m in messages) { |
||||
|
if (Object.prototype.hasOwnProperty.call(messages, m) && m.indexOf(topic) === 0) { |
||||
|
list.push(m); |
||||
|
} |
||||
|
} |
||||
|
return list; |
||||
|
}; |
||||
|
PubSub.unsubscribe = function(value) { |
||||
|
var descendantTopicExists = function(topic) { |
||||
|
var m2; |
||||
|
for (m2 in messages) { |
||||
|
if (Object.prototype.hasOwnProperty.call(messages, m2) && m2.indexOf(topic) === 0) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, isTopic = typeof value === "string" && (Object.prototype.hasOwnProperty.call(messages, value) || descendantTopicExists(value)), isToken = !isTopic && typeof value === "string", isFunction = typeof value === "function", result = false, m, message, t; |
||||
|
if (isTopic) { |
||||
|
PubSub.clearSubscriptions(value); |
||||
|
return; |
||||
|
} |
||||
|
for (m in messages) { |
||||
|
if (Object.prototype.hasOwnProperty.call(messages, m)) { |
||||
|
message = messages[m]; |
||||
|
if (isToken && message[value]) { |
||||
|
delete message[value]; |
||||
|
result = value; |
||||
|
break; |
||||
|
} |
||||
|
if (isFunction) { |
||||
|
for (t in message) { |
||||
|
if (Object.prototype.hasOwnProperty.call(message, t) && message[t] === value) { |
||||
|
delete message[t]; |
||||
|
result = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
}; |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
export default require_pubsub(); |
||||
|
|
@ -0,0 +1,314 @@ |
|||||
|
var raf = null; |
||||
|
function requestAnimationFrame (callback) { |
||||
|
if (!raf) { |
||||
|
raf = ( |
||||
|
window.requestAnimationFrame || |
||||
|
window.webkitRequestAnimationFrame || |
||||
|
window.mozRequestAnimationFrame || |
||||
|
function (callback) { |
||||
|
return setTimeout(callback, 16) |
||||
|
} |
||||
|
).bind(window); |
||||
|
} |
||||
|
return raf(callback) |
||||
|
} |
||||
|
|
||||
|
var caf = null; |
||||
|
function cancelAnimationFrame (id) { |
||||
|
if (!caf) { |
||||
|
caf = ( |
||||
|
window.cancelAnimationFrame || |
||||
|
window.webkitCancelAnimationFrame || |
||||
|
window.mozCancelAnimationFrame || |
||||
|
function (id) { |
||||
|
clearTimeout(id); |
||||
|
} |
||||
|
).bind(window); |
||||
|
} |
||||
|
|
||||
|
caf(id); |
||||
|
} |
||||
|
|
||||
|
function createStyles (styleText) { |
||||
|
var style = document.createElement('style'); |
||||
|
|
||||
|
if (style.styleSheet) { |
||||
|
style.styleSheet.cssText = styleText; |
||||
|
} else { |
||||
|
style.appendChild(document.createTextNode(styleText)); |
||||
|
} |
||||
|
(document.querySelector('head') || document.body).appendChild(style); |
||||
|
return style |
||||
|
} |
||||
|
|
||||
|
function createElement (tagName, props) { |
||||
|
if ( props === void 0 ) props = {}; |
||||
|
|
||||
|
var elem = document.createElement(tagName); |
||||
|
Object.keys(props).forEach(function (key) { |
||||
|
elem[key] = props[key]; |
||||
|
}); |
||||
|
return elem |
||||
|
} |
||||
|
|
||||
|
function getComputedStyle (elem, prop, pseudo) { |
||||
|
// for older versions of Firefox, `getComputedStyle` required
|
||||
|
// the second argument and may return `null` for some elements
|
||||
|
// when `display: none`
|
||||
|
var computedStyle = window.getComputedStyle(elem, pseudo || null) || { |
||||
|
display: 'none' |
||||
|
}; |
||||
|
|
||||
|
return computedStyle[prop] |
||||
|
} |
||||
|
|
||||
|
function getRenderInfo (elem) { |
||||
|
if (!document.documentElement.contains(elem)) { |
||||
|
return { |
||||
|
detached: true, |
||||
|
rendered: false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var current = elem; |
||||
|
while (current !== document) { |
||||
|
if (getComputedStyle(current, 'display') === 'none') { |
||||
|
return { |
||||
|
detached: false, |
||||
|
rendered: false |
||||
|
} |
||||
|
} |
||||
|
current = current.parentNode; |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
detached: false, |
||||
|
rendered: true |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var css_248z = ".resize-triggers{visibility:hidden;opacity:0;pointer-events:none}.resize-contract-trigger,.resize-contract-trigger:before,.resize-expand-trigger,.resize-triggers{content:\"\";position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden}.resize-contract-trigger,.resize-expand-trigger{background:#eee;overflow:auto}.resize-contract-trigger:before{width:200%;height:200%}"; |
||||
|
|
||||
|
var total = 0; |
||||
|
var style = null; |
||||
|
|
||||
|
function addListener (elem, callback) { |
||||
|
if (!elem.__resize_mutation_handler__) { |
||||
|
elem.__resize_mutation_handler__ = handleMutation.bind(elem); |
||||
|
} |
||||
|
|
||||
|
var listeners = elem.__resize_listeners__; |
||||
|
|
||||
|
if (!listeners) { |
||||
|
elem.__resize_listeners__ = []; |
||||
|
if (window.ResizeObserver) { |
||||
|
var offsetWidth = elem.offsetWidth; |
||||
|
var offsetHeight = elem.offsetHeight; |
||||
|
var ro = new ResizeObserver(function () { |
||||
|
if (!elem.__resize_observer_triggered__) { |
||||
|
elem.__resize_observer_triggered__ = true; |
||||
|
if (elem.offsetWidth === offsetWidth && elem.offsetHeight === offsetHeight) { |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
runCallbacks(elem); |
||||
|
}); |
||||
|
|
||||
|
// initially display none won't trigger ResizeObserver callback
|
||||
|
var ref = getRenderInfo(elem); |
||||
|
var detached = ref.detached; |
||||
|
var rendered = ref.rendered; |
||||
|
elem.__resize_observer_triggered__ = detached === false && rendered === false; |
||||
|
elem.__resize_observer__ = ro; |
||||
|
ro.observe(elem); |
||||
|
} else if (elem.attachEvent && elem.addEventListener) { |
||||
|
// targeting IE9/10
|
||||
|
elem.__resize_legacy_resize_handler__ = function handleLegacyResize () { |
||||
|
runCallbacks(elem); |
||||
|
}; |
||||
|
elem.attachEvent('onresize', elem.__resize_legacy_resize_handler__); |
||||
|
document.addEventListener('DOMSubtreeModified', elem.__resize_mutation_handler__); |
||||
|
} else { |
||||
|
if (!total) { |
||||
|
style = createStyles(css_248z); |
||||
|
} |
||||
|
initTriggers(elem); |
||||
|
|
||||
|
elem.__resize_rendered__ = getRenderInfo(elem).rendered; |
||||
|
if (window.MutationObserver) { |
||||
|
var mo = new MutationObserver(elem.__resize_mutation_handler__); |
||||
|
mo.observe(document, { |
||||
|
attributes: true, |
||||
|
childList: true, |
||||
|
characterData: true, |
||||
|
subtree: true |
||||
|
}); |
||||
|
elem.__resize_mutation_observer__ = mo; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
elem.__resize_listeners__.push(callback); |
||||
|
total++; |
||||
|
} |
||||
|
|
||||
|
function removeListener (elem, callback) { |
||||
|
var listeners = elem.__resize_listeners__; |
||||
|
if (!listeners) { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if (callback) { |
||||
|
listeners.splice(listeners.indexOf(callback), 1); |
||||
|
} |
||||
|
|
||||
|
// no listeners exist, or removing all listeners
|
||||
|
if (!listeners.length || !callback) { |
||||
|
// targeting IE9/10
|
||||
|
if (elem.detachEvent && elem.removeEventListener) { |
||||
|
elem.detachEvent('onresize', elem.__resize_legacy_resize_handler__); |
||||
|
document.removeEventListener('DOMSubtreeModified', elem.__resize_mutation_handler__); |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if (elem.__resize_observer__) { |
||||
|
elem.__resize_observer__.unobserve(elem); |
||||
|
elem.__resize_observer__.disconnect(); |
||||
|
elem.__resize_observer__ = null; |
||||
|
} else { |
||||
|
if (elem.__resize_mutation_observer__) { |
||||
|
elem.__resize_mutation_observer__.disconnect(); |
||||
|
elem.__resize_mutation_observer__ = null; |
||||
|
} |
||||
|
elem.removeEventListener('scroll', handleScroll); |
||||
|
elem.removeChild(elem.__resize_triggers__.triggers); |
||||
|
elem.__resize_triggers__ = null; |
||||
|
} |
||||
|
elem.__resize_listeners__ = null; |
||||
|
} |
||||
|
|
||||
|
if (!--total && style) { |
||||
|
style.parentNode.removeChild(style); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function getUpdatedSize (elem) { |
||||
|
var ref = elem.__resize_last__; |
||||
|
var width = ref.width; |
||||
|
var height = ref.height; |
||||
|
var offsetWidth = elem.offsetWidth; |
||||
|
var offsetHeight = elem.offsetHeight; |
||||
|
if (offsetWidth !== width || offsetHeight !== height) { |
||||
|
return { |
||||
|
width: offsetWidth, |
||||
|
height: offsetHeight |
||||
|
} |
||||
|
} |
||||
|
return null |
||||
|
} |
||||
|
|
||||
|
function handleMutation () { |
||||
|
// `this` denotes the scrolling element
|
||||
|
var ref = getRenderInfo(this); |
||||
|
var rendered = ref.rendered; |
||||
|
var detached = ref.detached; |
||||
|
if (rendered !== this.__resize_rendered__) { |
||||
|
if (!detached && this.__resize_triggers__) { |
||||
|
resetTriggers(this); |
||||
|
this.addEventListener('scroll', handleScroll, true); |
||||
|
} |
||||
|
this.__resize_rendered__ = rendered; |
||||
|
runCallbacks(this); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function handleScroll () { |
||||
|
var this$1 = this; |
||||
|
|
||||
|
// `this` denotes the scrolling element
|
||||
|
resetTriggers(this); |
||||
|
if (this.__resize_raf__) { |
||||
|
cancelAnimationFrame(this.__resize_raf__); |
||||
|
} |
||||
|
this.__resize_raf__ = requestAnimationFrame(function () { |
||||
|
var updated = getUpdatedSize(this$1); |
||||
|
if (updated) { |
||||
|
this$1.__resize_last__ = updated; |
||||
|
runCallbacks(this$1); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function runCallbacks (elem) { |
||||
|
if (!elem || !elem.__resize_listeners__) { |
||||
|
return |
||||
|
} |
||||
|
elem.__resize_listeners__.forEach(function (callback) { |
||||
|
callback.call(elem, elem); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function initTriggers (elem) { |
||||
|
var position = getComputedStyle(elem, 'position'); |
||||
|
if (!position || position === 'static') { |
||||
|
elem.style.position = 'relative'; |
||||
|
} |
||||
|
|
||||
|
elem.__resize_old_position__ = position; |
||||
|
elem.__resize_last__ = {}; |
||||
|
|
||||
|
var triggers = createElement('div', { |
||||
|
className: 'resize-triggers' |
||||
|
}); |
||||
|
var expand = createElement('div', { |
||||
|
className: 'resize-expand-trigger' |
||||
|
}); |
||||
|
var expandChild = createElement('div'); |
||||
|
var contract = createElement('div', { |
||||
|
className: 'resize-contract-trigger' |
||||
|
}); |
||||
|
expand.appendChild(expandChild); |
||||
|
triggers.appendChild(expand); |
||||
|
triggers.appendChild(contract); |
||||
|
elem.appendChild(triggers); |
||||
|
|
||||
|
elem.__resize_triggers__ = { |
||||
|
triggers: triggers, |
||||
|
expand: expand, |
||||
|
expandChild: expandChild, |
||||
|
contract: contract |
||||
|
}; |
||||
|
|
||||
|
resetTriggers(elem); |
||||
|
elem.addEventListener('scroll', handleScroll, true); |
||||
|
|
||||
|
elem.__resize_last__ = { |
||||
|
width: elem.offsetWidth, |
||||
|
height: elem.offsetHeight |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function resetTriggers (elem) { |
||||
|
var ref = elem.__resize_triggers__; |
||||
|
var expand = ref.expand; |
||||
|
var expandChild = ref.expandChild; |
||||
|
var contract = ref.contract; |
||||
|
|
||||
|
// batch read
|
||||
|
var csw = contract.scrollWidth; |
||||
|
var csh = contract.scrollHeight; |
||||
|
var eow = expand.offsetWidth; |
||||
|
var eoh = expand.offsetHeight; |
||||
|
var esw = expand.scrollWidth; |
||||
|
var esh = expand.scrollHeight; |
||||
|
|
||||
|
// batch write
|
||||
|
contract.scrollLeft = csw; |
||||
|
contract.scrollTop = csh; |
||||
|
expandChild.style.width = eow + 1 + 'px'; |
||||
|
expandChild.style.height = eoh + 1 + 'px'; |
||||
|
expand.scrollLeft = esw; |
||||
|
expand.scrollTop = esh; |
||||
|
} |
||||
|
|
||||
|
export { addListener, removeListener }; |
@ -0,0 +1,34 @@ |
|||||
|
import * as Vue from 'vue' |
||||
|
|
||||
|
var isVue2 = false |
||||
|
var isVue3 = true |
||||
|
var Vue2 = undefined |
||||
|
|
||||
|
function install() {} |
||||
|
|
||||
|
export function set(target, key, val) { |
||||
|
if (Array.isArray(target)) { |
||||
|
target.length = Math.max(target.length, key) |
||||
|
target.splice(key, 1, val) |
||||
|
return val |
||||
|
} |
||||
|
target[key] = val |
||||
|
return val |
||||
|
} |
||||
|
|
||||
|
export function del(target, key) { |
||||
|
if (Array.isArray(target)) { |
||||
|
target.splice(key, 1) |
||||
|
return |
||||
|
} |
||||
|
delete target[key] |
||||
|
} |
||||
|
|
||||
|
export * from 'vue' |
||||
|
export { |
||||
|
Vue, |
||||
|
Vue2, |
||||
|
isVue2, |
||||
|
isVue3, |
||||
|
install, |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
import{watch as e,inject as t,computed as n,unref as o,watchEffect as r,defineComponent as i,shallowRef as a,toRefs as u,onMounted as c,onUnmounted as s,h as l,Vue2 as p,nextTick as v}from"vue-demi";import{throttle as f,init as d}from"echarts/core";import{addListener as g,removeListener as h}from"resize-detector";var O=function(){return(O=Object.assign||function(e){for(var t,n=1,o=arguments.length;n<o;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,arguments)},m=["getWidth","getHeight","getDom","getOption","resize","dispatchAction","convertToPixel","convertFromPixel","containPixel","getDataURL","getConnectedDataURL","appendData","clear","isDisposed","dispose"];function b(e){return t=Object.create(null),m.forEach((function(n){t[n]=function(t){return function(){for(var n=[],o=0;o<arguments.length;o++)n[o]=arguments[o];if(!e.value)throw new Error("ECharts is not initialized yet.");return e.value[t].apply(e.value,n)}}(n)})),t;var t}var y={autoresize:Boolean},x="ecLoadingOptions";var j={loading:Boolean,loadingOptions:Object},E=[],z=[];!function(e,t){if(e&&"undefined"!=typeof document){var n,o=!0===t.prepend?"prepend":"append",r=!0===t.singleTag,i="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(r){var a=E.indexOf(i);-1===a&&(a=E.push(i)-1,z[a]={}),n=z[a]&&z[a][o]?z[a][o]:z[a][o]=u()}else n=u();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function u(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var n=Object.keys(t.attributes),r=0;r<n.length;r++)e.setAttribute(n[r],t.attributes[n[r]]);var a="prepend"===o?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}}("x-vue-echarts{display:block;width:100%;height:100%}",{});var A=/^on[^a-z]/,L=function(e){return A.test(e)};p&&p.config.ignoredElements.push("x-vue-echarts");var w="ecTheme",C="ecInitOptions",T="ecUpdateOptions",U=i({name:"echarts",props:O(O({option:Object,theme:{type:[Object,String]},initOptions:Object,updateOptions:Object,group:String,manualUpdate:Boolean},y),j),inheritAttrs:!1,setup:function(i,l){var p=l.attrs,m=l.listeners,y=a(),x=a(),j=a(),E=t("ecTheme",null),z=t("ecInitOptions",null),A=t("ecUpdateOptions",null),w=u(i),C=w.autoresize,T=w.manualUpdate,U=w.loading,D=w.loadingOptions,S=n((function(){return j.value||i.option||null})),k=n((function(){return i.theme||o(E)||{}})),B=n((function(){return i.initOptions||o(z)||{}})),P=n((function(){return i.updateOptions||o(A)||{}})),I=n((function(){return function(e){var t={};for(var n in e)L(n)||(t[n]=e[n]);return t}(p)}));function N(e){if(y.value){var t=x.value=d(y.value,k.value,B.value);i.group&&(t.group=i.group);var n=m;n||(n={},Object.keys(p).filter((function(e){return 0===e.indexOf("on")&&e.length>2})).forEach((function(e){var t=e.charAt(2).toLowerCase()+e.slice(3);n[t]=p[e]}))),Object.keys(n).forEach((function(e){var o=n[e];o&&(0===e.indexOf("zr:")?t.getZr().on(e.slice(3).toLowerCase(),o):t.on(e.toLowerCase(),o))})),C.value?v((function(){t&&!t.isDisposed()&&t.resize(),o()})):o()}function o(){var n=e||S.value;n&&t.setOption(n,P.value)}}function R(){x.value&&(x.value.dispose(),x.value=void 0)}var q=null;e(T,(function(t){"function"==typeof q&&(q(),q=null),t||(q=e((function(){return i.option}),(function(e,t){e&&(x.value?x.value.setOption(e,O({notMerge:e.value!==(null==t?void 0:t.value)},P.value)):N())}),{deep:!0}))}),{immediate:!0}),e([k,B],(function(){R(),N()}),{deep:!0}),r((function(){i.group&&x.value&&(x.value.group=i.group)}));var F=b(x);return function(e,i,a){var u=t("ecLoadingOptions",{}),c=n((function(){return O(O({},o(u)),null==a?void 0:a.value)}));r((function(){var t=e.value;t&&(i.value?t.showLoading(c.value):t.hideLoading())}))}(x,U,D),function(t,n,o){var r=null;e([o,t,n],(function(e,t,n){var o=e[0],i=e[1],a=e[2];o&&i&&a&&(r=f((function(){i.resize()}),100),g(o,r)),n((function(){r&&o&&h(o,r)}))}))}(x,C,y),c((function(){N()})),s(R),O({chart:x,root:y,setOption:function(e,t){i.manualUpdate&&(j.value=e),x.value?x.value.setOption(e,t||{}):N(e)},nonEventAttrs:I},F)},render:function(){var e=O({},this.nonEventAttrs);return e.ref="root",e.class=e.class?["echarts"].concat(e.class):"echarts",l("x-vue-echarts",e)}});export default U;export{C as INIT_OPTIONS_KEY,x as LOADING_OPTIONS_KEY,w as THEME_KEY,T as UPDATE_OPTIONS_KEY}; |
||||
|
//# sourceMappingURL=index.esm.min.js.map
|
@ -0,0 +1,13 @@ |
|||||
|
import { createI18n } from "vue-i18n"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
|
||||
|
function useLocale() { |
||||
|
const appStore = useAppStore(); |
||||
|
const i18n = createI18n({ |
||||
|
legacy: false, |
||||
|
...appStore.localization, |
||||
|
}); |
||||
|
return i18n; |
||||
|
} |
||||
|
|
||||
|
export default useLocale; |
@ -0,0 +1,8 @@ |
|||||
|
@import url("./lib/nprogress/nprogress.css"); |
||||
|
@import url("./lib/element-plus/index.css"); |
||||
|
@import url("./lib/element-plus/theme-chalk/dark/css-vars.css"); |
||||
|
@import url("./lib/github-markdown-css/github-markdown.min.css"); |
||||
|
@import url("./lib/highlightjs/highlight.css"); |
||||
|
@import url("./lib/@vue-office/excel/index.css"); |
||||
|
@import url("./lib/tailwindcss/tailwind.min.css"); |
||||
|
@import url("./styles/site.css"); |
@ -0,0 +1,20 @@ |
|||||
|
import { createApp } from "vue"; |
||||
|
import style from './mixins/style.js'; |
||||
|
import store, { useAppStore } from "./store/index.js"; |
||||
|
import router from "./router/index.js"; |
||||
|
import ElementPlus from "element-plus"; |
||||
|
import * as ElementPlusIconsVue from "@element-plus/icons-vue"; |
||||
|
import App from "/app.js"; |
||||
|
import useLocale from "./locale/index.js"; |
||||
|
|
||||
|
const app = createApp(App); |
||||
|
app.use(store); |
||||
|
await useAppStore().init(); |
||||
|
app.use(useLocale()); |
||||
|
app.use(router); |
||||
|
app.use(ElementPlus); |
||||
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) { |
||||
|
app.component(`Ep${key}`, component); |
||||
|
} |
||||
|
app.mixin(style); |
||||
|
app.mount("#app"); |
@ -0,0 +1,60 @@ |
|||||
|
const styleCounterName = 'data-vue-component-instances'; |
||||
|
|
||||
|
function getStyleList(name) { |
||||
|
return document.querySelectorAll(`head style.${name},head link[rel='stylesheet'].${name}`); |
||||
|
} |
||||
|
|
||||
|
function append(parent, html) { |
||||
|
parent.insertAdjacentHTML('beforeend', html); |
||||
|
} |
||||
|
|
||||
|
function addStyles(name, styleSource) { |
||||
|
var styleList = getStyleList(name); |
||||
|
if (styleList.length > 0) { |
||||
|
for (let i = 0; i < styleList.length; i++) { |
||||
|
const style = styleList[i]; |
||||
|
var counter = parseInt(style.getAttribute(styleCounterName)); |
||||
|
style.setAttribute(styleCounterName, counter + 1); |
||||
|
} |
||||
|
} else { |
||||
|
const doc = new DOMParser().parseFromString(styleSource, 'text/html'); |
||||
|
const styles = doc.querySelectorAll("style,link[rel='stylesheet']"); |
||||
|
for (let i = 0; i < styles.length; i++) { |
||||
|
const style = styles[i]; |
||||
|
style.setAttribute('class', name); |
||||
|
style.setAttribute(styleCounterName, 1); |
||||
|
append(document.head, style.outerHTML); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function removeStyles(name) { |
||||
|
var styleList = getStyleList(name); |
||||
|
if (styleList.length > 0) { |
||||
|
for (var i = 0; i < styleList.length; i++) { |
||||
|
var style = styleList[i]; |
||||
|
var counter = parseInt(style.getAttribute(styleCounterName)); |
||||
|
if (counter - 1 > 0) { |
||||
|
style.setAttribute(styleCounterName, counter - 1); |
||||
|
} else { |
||||
|
document.head.removeChild(style); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
let id = 0; |
||||
|
|
||||
|
export default { |
||||
|
created() { |
||||
|
if (this._.type.styles) { |
||||
|
if (!this._.type.uid) { |
||||
|
this._.type.uid = `uid_${id++}`; |
||||
|
} |
||||
|
addStyles(this._.type.uid, this._.type.styles); |
||||
|
} |
||||
|
}, |
||||
|
unmounted() { |
||||
|
removeStyles(this._.type.uid); |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,90 @@ |
|||||
|
import qs from "../lib/qs/shim.js"; |
||||
|
import { isLogin } from "../api/user.js"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import settings from "../config/settings.js"; |
||||
|
|
||||
|
const addToken = async (options) => { |
||||
|
if (await isLogin()) { |
||||
|
const appStore = useAppStore(); |
||||
|
options.headers ??= {}; |
||||
|
options.headers.Authorization = `Bearer ${appStore.token}`; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getUrl = (url) => { |
||||
|
if (url.indexOf("/") === 0) { |
||||
|
return url; |
||||
|
} |
||||
|
let result = settings.baseURL; |
||||
|
return (result += `/${url}`); |
||||
|
}; |
||||
|
|
||||
|
const getResult = async (response) => { |
||||
|
const messages = new Map([ |
||||
|
[200, "操作成功"], |
||||
|
[201, "已创建"], |
||||
|
[204, "无返回值"], |
||||
|
[400, "请求参数错误"], |
||||
|
[401, "未登录"], |
||||
|
[403, "权限不足"], |
||||
|
[500, "服务器异常"], |
||||
|
]); |
||||
|
const result = { |
||||
|
status: response.status, |
||||
|
message: messages.get(response.status), |
||||
|
}; |
||||
|
if (response.status == 200) { |
||||
|
result.data = await response.json(); |
||||
|
} else if (response.status === 400 || response.status === 500) { |
||||
|
result.errors = await response.json(); |
||||
|
} |
||||
|
return result; |
||||
|
}; |
||||
|
|
||||
|
const get = async (url, data, options, withoutToken = false, withoutCulture = false) => { |
||||
|
url = getUrl(url, withoutCulture); |
||||
|
if (data) { |
||||
|
url = `${url}?${qs.stringify(data)}`; |
||||
|
} |
||||
|
const defaultOptions = { |
||||
|
headers: { |
||||
|
"Accept-Language": "zh-Hans", |
||||
|
}, |
||||
|
}; |
||||
|
if (options) { |
||||
|
Object.assign(defaultOptions, options); |
||||
|
} |
||||
|
if (!withoutToken) { |
||||
|
await addToken(defaultOptions); |
||||
|
} |
||||
|
const response = await fetch(url, defaultOptions); |
||||
|
return getResult(response); |
||||
|
}; |
||||
|
|
||||
|
const post = async (url, data, options, withoutToken = false, withoutCulture = false) => { |
||||
|
url = getUrl(url, withoutCulture); |
||||
|
const defaultOptions = { |
||||
|
method: "POST", |
||||
|
headers: { |
||||
|
"Accept-Language": "zh-Hans", |
||||
|
"Content-Type": "application/json", |
||||
|
}, |
||||
|
}; |
||||
|
if (options) { |
||||
|
Object.assign(defaultOptions, options); |
||||
|
} |
||||
|
if (data && !defaultOptions.body) { |
||||
|
if (defaultOptions.headers["Content-Type"] === "application/x-www-form-urlencoded") { |
||||
|
defaultOptions.body = qs.stringify(data); |
||||
|
} else { |
||||
|
defaultOptions.body = JSON.stringify(data); |
||||
|
} |
||||
|
} |
||||
|
if (!withoutToken) { |
||||
|
await addToken(defaultOptions); |
||||
|
} |
||||
|
const response = await fetch(url, defaultOptions); |
||||
|
return getResult(response); |
||||
|
}; |
||||
|
|
||||
|
export { getUrl, get, post }; |
@ -0,0 +1,314 @@ |
|||||
|
var raf = null; |
||||
|
function requestAnimationFrame (callback) { |
||||
|
if (!raf) { |
||||
|
raf = ( |
||||
|
window.requestAnimationFrame || |
||||
|
window.webkitRequestAnimationFrame || |
||||
|
window.mozRequestAnimationFrame || |
||||
|
function (callback) { |
||||
|
return setTimeout(callback, 16) |
||||
|
} |
||||
|
).bind(window); |
||||
|
} |
||||
|
return raf(callback) |
||||
|
} |
||||
|
|
||||
|
var caf = null; |
||||
|
function cancelAnimationFrame (id) { |
||||
|
if (!caf) { |
||||
|
caf = ( |
||||
|
window.cancelAnimationFrame || |
||||
|
window.webkitCancelAnimationFrame || |
||||
|
window.mozCancelAnimationFrame || |
||||
|
function (id) { |
||||
|
clearTimeout(id); |
||||
|
} |
||||
|
).bind(window); |
||||
|
} |
||||
|
|
||||
|
caf(id); |
||||
|
} |
||||
|
|
||||
|
function createStyles (styleText) { |
||||
|
var style = document.createElement('style'); |
||||
|
|
||||
|
if (style.styleSheet) { |
||||
|
style.styleSheet.cssText = styleText; |
||||
|
} else { |
||||
|
style.appendChild(document.createTextNode(styleText)); |
||||
|
} |
||||
|
(document.querySelector('head') || document.body).appendChild(style); |
||||
|
return style |
||||
|
} |
||||
|
|
||||
|
function createElement (tagName, props) { |
||||
|
if ( props === void 0 ) props = {}; |
||||
|
|
||||
|
var elem = document.createElement(tagName); |
||||
|
Object.keys(props).forEach(function (key) { |
||||
|
elem[key] = props[key]; |
||||
|
}); |
||||
|
return elem |
||||
|
} |
||||
|
|
||||
|
function getComputedStyle (elem, prop, pseudo) { |
||||
|
// for older versions of Firefox, `getComputedStyle` required
|
||||
|
// the second argument and may return `null` for some elements
|
||||
|
// when `display: none`
|
||||
|
var computedStyle = window.getComputedStyle(elem, pseudo || null) || { |
||||
|
display: 'none' |
||||
|
}; |
||||
|
|
||||
|
return computedStyle[prop] |
||||
|
} |
||||
|
|
||||
|
function getRenderInfo (elem) { |
||||
|
if (!document.documentElement.contains(elem)) { |
||||
|
return { |
||||
|
detached: true, |
||||
|
rendered: false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var current = elem; |
||||
|
while (current !== document) { |
||||
|
if (getComputedStyle(current, 'display') === 'none') { |
||||
|
return { |
||||
|
detached: false, |
||||
|
rendered: false |
||||
|
} |
||||
|
} |
||||
|
current = current.parentNode; |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
detached: false, |
||||
|
rendered: true |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var css_248z = ".resize-triggers{visibility:hidden;opacity:0;pointer-events:none}.resize-contract-trigger,.resize-contract-trigger:before,.resize-expand-trigger,.resize-triggers{content:\"\";position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden}.resize-contract-trigger,.resize-expand-trigger{background:#eee;overflow:auto}.resize-contract-trigger:before{width:200%;height:200%}"; |
||||
|
|
||||
|
var total = 0; |
||||
|
var style = null; |
||||
|
|
||||
|
function addListener (elem, callback) { |
||||
|
if (!elem.__resize_mutation_handler__) { |
||||
|
elem.__resize_mutation_handler__ = handleMutation.bind(elem); |
||||
|
} |
||||
|
|
||||
|
var listeners = elem.__resize_listeners__; |
||||
|
|
||||
|
if (!listeners) { |
||||
|
elem.__resize_listeners__ = []; |
||||
|
if (window.ResizeObserver) { |
||||
|
var offsetWidth = elem.offsetWidth; |
||||
|
var offsetHeight = elem.offsetHeight; |
||||
|
var ro = new ResizeObserver(function () { |
||||
|
if (!elem.__resize_observer_triggered__) { |
||||
|
elem.__resize_observer_triggered__ = true; |
||||
|
if (elem.offsetWidth === offsetWidth && elem.offsetHeight === offsetHeight) { |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
runCallbacks(elem); |
||||
|
}); |
||||
|
|
||||
|
// initially display none won't trigger ResizeObserver callback
|
||||
|
var ref = getRenderInfo(elem); |
||||
|
var detached = ref.detached; |
||||
|
var rendered = ref.rendered; |
||||
|
elem.__resize_observer_triggered__ = detached === false && rendered === false; |
||||
|
elem.__resize_observer__ = ro; |
||||
|
ro.observe(elem); |
||||
|
} else if (elem.attachEvent && elem.addEventListener) { |
||||
|
// targeting IE9/10
|
||||
|
elem.__resize_legacy_resize_handler__ = function handleLegacyResize () { |
||||
|
runCallbacks(elem); |
||||
|
}; |
||||
|
elem.attachEvent('onresize', elem.__resize_legacy_resize_handler__); |
||||
|
document.addEventListener('DOMSubtreeModified', elem.__resize_mutation_handler__); |
||||
|
} else { |
||||
|
if (!total) { |
||||
|
style = createStyles(css_248z); |
||||
|
} |
||||
|
initTriggers(elem); |
||||
|
|
||||
|
elem.__resize_rendered__ = getRenderInfo(elem).rendered; |
||||
|
if (window.MutationObserver) { |
||||
|
var mo = new MutationObserver(elem.__resize_mutation_handler__); |
||||
|
mo.observe(document, { |
||||
|
attributes: true, |
||||
|
childList: true, |
||||
|
characterData: true, |
||||
|
subtree: true |
||||
|
}); |
||||
|
elem.__resize_mutation_observer__ = mo; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
elem.__resize_listeners__.push(callback); |
||||
|
total++; |
||||
|
} |
||||
|
|
||||
|
function removeListener (elem, callback) { |
||||
|
var listeners = elem.__resize_listeners__; |
||||
|
if (!listeners) { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if (callback) { |
||||
|
listeners.splice(listeners.indexOf(callback), 1); |
||||
|
} |
||||
|
|
||||
|
// no listeners exist, or removing all listeners
|
||||
|
if (!listeners.length || !callback) { |
||||
|
// targeting IE9/10
|
||||
|
if (elem.detachEvent && elem.removeEventListener) { |
||||
|
elem.detachEvent('onresize', elem.__resize_legacy_resize_handler__); |
||||
|
document.removeEventListener('DOMSubtreeModified', elem.__resize_mutation_handler__); |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if (elem.__resize_observer__) { |
||||
|
elem.__resize_observer__.unobserve(elem); |
||||
|
elem.__resize_observer__.disconnect(); |
||||
|
elem.__resize_observer__ = null; |
||||
|
} else { |
||||
|
if (elem.__resize_mutation_observer__) { |
||||
|
elem.__resize_mutation_observer__.disconnect(); |
||||
|
elem.__resize_mutation_observer__ = null; |
||||
|
} |
||||
|
elem.removeEventListener('scroll', handleScroll); |
||||
|
elem.removeChild(elem.__resize_triggers__.triggers); |
||||
|
elem.__resize_triggers__ = null; |
||||
|
} |
||||
|
elem.__resize_listeners__ = null; |
||||
|
} |
||||
|
|
||||
|
if (!--total && style) { |
||||
|
style.parentNode.removeChild(style); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function getUpdatedSize (elem) { |
||||
|
var ref = elem.__resize_last__; |
||||
|
var width = ref.width; |
||||
|
var height = ref.height; |
||||
|
var offsetWidth = elem.offsetWidth; |
||||
|
var offsetHeight = elem.offsetHeight; |
||||
|
if (offsetWidth !== width || offsetHeight !== height) { |
||||
|
return { |
||||
|
width: offsetWidth, |
||||
|
height: offsetHeight |
||||
|
} |
||||
|
} |
||||
|
return null |
||||
|
} |
||||
|
|
||||
|
function handleMutation () { |
||||
|
// `this` denotes the scrolling element
|
||||
|
var ref = getRenderInfo(this); |
||||
|
var rendered = ref.rendered; |
||||
|
var detached = ref.detached; |
||||
|
if (rendered !== this.__resize_rendered__) { |
||||
|
if (!detached && this.__resize_triggers__) { |
||||
|
resetTriggers(this); |
||||
|
this.addEventListener('scroll', handleScroll, true); |
||||
|
} |
||||
|
this.__resize_rendered__ = rendered; |
||||
|
runCallbacks(this); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function handleScroll () { |
||||
|
var this$1 = this; |
||||
|
|
||||
|
// `this` denotes the scrolling element
|
||||
|
resetTriggers(this); |
||||
|
if (this.__resize_raf__) { |
||||
|
cancelAnimationFrame(this.__resize_raf__); |
||||
|
} |
||||
|
this.__resize_raf__ = requestAnimationFrame(function () { |
||||
|
var updated = getUpdatedSize(this$1); |
||||
|
if (updated) { |
||||
|
this$1.__resize_last__ = updated; |
||||
|
runCallbacks(this$1); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function runCallbacks (elem) { |
||||
|
if (!elem || !elem.__resize_listeners__) { |
||||
|
return |
||||
|
} |
||||
|
elem.__resize_listeners__.forEach(function (callback) { |
||||
|
callback.call(elem, elem); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function initTriggers (elem) { |
||||
|
var position = getComputedStyle(elem, 'position'); |
||||
|
if (!position || position === 'static') { |
||||
|
elem.style.position = 'relative'; |
||||
|
} |
||||
|
|
||||
|
elem.__resize_old_position__ = position; |
||||
|
elem.__resize_last__ = {}; |
||||
|
|
||||
|
var triggers = createElement('div', { |
||||
|
className: 'resize-triggers' |
||||
|
}); |
||||
|
var expand = createElement('div', { |
||||
|
className: 'resize-expand-trigger' |
||||
|
}); |
||||
|
var expandChild = createElement('div'); |
||||
|
var contract = createElement('div', { |
||||
|
className: 'resize-contract-trigger' |
||||
|
}); |
||||
|
expand.appendChild(expandChild); |
||||
|
triggers.appendChild(expand); |
||||
|
triggers.appendChild(contract); |
||||
|
elem.appendChild(triggers); |
||||
|
|
||||
|
elem.__resize_triggers__ = { |
||||
|
triggers: triggers, |
||||
|
expand: expand, |
||||
|
expandChild: expandChild, |
||||
|
contract: contract |
||||
|
}; |
||||
|
|
||||
|
resetTriggers(elem); |
||||
|
elem.addEventListener('scroll', handleScroll, true); |
||||
|
|
||||
|
elem.__resize_last__ = { |
||||
|
width: elem.offsetWidth, |
||||
|
height: elem.offsetHeight |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function resetTriggers (elem) { |
||||
|
var ref = elem.__resize_triggers__; |
||||
|
var expand = ref.expand; |
||||
|
var expandChild = ref.expandChild; |
||||
|
var contract = ref.contract; |
||||
|
|
||||
|
// batch read
|
||||
|
var csw = contract.scrollWidth; |
||||
|
var csh = contract.scrollHeight; |
||||
|
var eow = expand.offsetWidth; |
||||
|
var eoh = expand.offsetHeight; |
||||
|
var esw = expand.scrollWidth; |
||||
|
var esh = expand.scrollHeight; |
||||
|
|
||||
|
// batch write
|
||||
|
contract.scrollLeft = csw; |
||||
|
contract.scrollTop = csh; |
||||
|
expandChild.style.width = eow + 1 + 'px'; |
||||
|
expandChild.style.height = eoh + 1 + 'px'; |
||||
|
expand.scrollLeft = esw; |
||||
|
expand.scrollTop = esh; |
||||
|
} |
||||
|
|
||||
|
export { addListener, removeListener }; |
@ -0,0 +1,133 @@ |
|||||
|
import { createRouter, createWebHashHistory } from "vue-router"; |
||||
|
import { useTitle } from "@vueuse/core"; |
||||
|
import NProgress from "../lib/nprogress/nprogress.vite-esm.js"; |
||||
|
import { isLogin, hasPermission } from "../api/user.js"; |
||||
|
import { useAppStore } from "../store/index.js"; |
||||
|
import { listToTree } from "../utils/index.js"; |
||||
|
import { connection, connect } from "../signalr/index.js"; |
||||
|
|
||||
|
NProgress.configure({ showSpinner: false }); |
||||
|
|
||||
|
const routes = [ |
||||
|
{ |
||||
|
path: "/", |
||||
|
redirect: "/home", |
||||
|
component: () => import("../layouts/index.js"), |
||||
|
children: [ |
||||
|
{ |
||||
|
path: "home", |
||||
|
component: () => import("../views/home.js"), |
||||
|
meta: { |
||||
|
title: "首页", |
||||
|
icon: "home", |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
{ |
||||
|
path: "/login", |
||||
|
component: () => import("../views/login.js"), |
||||
|
meta: { |
||||
|
title: "登录", |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: "/403", |
||||
|
component: () => import("../views/403.js"), |
||||
|
meta: { |
||||
|
title: "权限不足", |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: "/:pathMatch(.*)*", |
||||
|
component: () => import("../views/404.js"), |
||||
|
meta: { |
||||
|
title: "无法找到", |
||||
|
}, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
const router = createRouter({ |
||||
|
history: createWebHashHistory(), |
||||
|
routes, |
||||
|
}); |
||||
|
|
||||
|
router.beforeEach(async (to, from, next) => { |
||||
|
console.log(`before: ${from.path} -> ${to.path}`); |
||||
|
NProgress.start(); |
||||
|
try { |
||||
|
if (to.path !== "/login") { |
||||
|
if (!(await isLogin())) { |
||||
|
next({ path: "/login", query: { redirect: to.fullPath } }); |
||||
|
} else { |
||||
|
if (!hasPermission(to)) { |
||||
|
next({ path: "/403", query: { redirect: to.fullPath } }); |
||||
|
} else { |
||||
|
next(); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
next(); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
NProgress.done(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
router.afterEach((to, from) => { |
||||
|
console.log(`after: ${from.path} -> ${to.path}`); |
||||
|
try { |
||||
|
if (to.meta.title) { |
||||
|
useTitle().value = `${to.meta.title}`; |
||||
|
} |
||||
|
if (to.fullPath.startsWith("/")) { |
||||
|
const appStore = useAppStore(); |
||||
|
appStore.add(to); |
||||
|
} |
||||
|
} finally { |
||||
|
NProgress.done(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const reset = (list, parent = null) => { |
||||
|
return list.map((o) => { |
||||
|
const item = { |
||||
|
path: o.path, |
||||
|
meta: o.meta, |
||||
|
}; |
||||
|
if (item.component && item.component !== "Layout") { |
||||
|
item.component = import(`../views/${o.component ? o.component : "list"}.js`); |
||||
|
} |
||||
|
item.meta.path = `${parent === null ? "" : parent.meta.path + "/"}${item.path}`; |
||||
|
item.meta.fullName = `${parent === null ? "" : parent.meta.title + " > "}${item.meta.title}`; |
||||
|
if (o.type === "Resource") { |
||||
|
if (o.children.length) { |
||||
|
item.meta.buttons = o.children.map((b) => { |
||||
|
return { |
||||
|
path: b.path, |
||||
|
meta: b.meta, |
||||
|
}; |
||||
|
}); |
||||
|
} |
||||
|
} else if (o.type !== "Operation" && o.children?.length) { |
||||
|
item.children = reset(o.children, item); |
||||
|
} |
||||
|
return item; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const refreshRouter = async () => { |
||||
|
await connect(); |
||||
|
const appStore = useAppStore(); |
||||
|
const permissions = appStore.user.permissions.filter((o) => !o.isHidden); |
||||
|
const serverRoutes = reset(permissions); |
||||
|
const route = { |
||||
|
name: "layout", |
||||
|
path: "", |
||||
|
children: serverRoutes, |
||||
|
}; |
||||
|
router.removeRoute("layout"); |
||||
|
router.addRoute("/", route); |
||||
|
}; |
||||
|
export default router; |
||||
|
export { refreshRouter }; |
@ -0,0 +1,42 @@ |
|||||
|
import * as signalR from "@microsoft/signalr"; |
||||
|
import PubSub from "pubsub-js"; |
||||
|
import useAppStore from "../store/app.js"; |
||||
|
import { isLogin } from "../api/user.js"; |
||||
|
|
||||
|
let connectionId = null; |
||||
|
const connection = new signalR.HubConnectionBuilder() |
||||
|
.withUrl("./api/hub", { |
||||
|
accessTokenFactory: () => { |
||||
|
const appStore = useAppStore(); |
||||
|
return appStore.token; |
||||
|
}, |
||||
|
}) |
||||
|
.withAutomaticReconnect() |
||||
|
.build(); |
||||
|
const connect = async () => { |
||||
|
return; |
||||
|
if (await isLogin()) { |
||||
|
if (connection.state === signalR.HubConnectionState.Disconnected) { |
||||
|
connection |
||||
|
.start() |
||||
|
.then(function () { |
||||
|
console.log("signalr connected"); |
||||
|
}) |
||||
|
.catch(function (error) { |
||||
|
console.error(error); |
||||
|
//setTimeout(connect, 5000);
|
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
connection.onclose(async () => { |
||||
|
await connect(); |
||||
|
}); |
||||
|
connection.on("connected", (id) => { |
||||
|
connectionId = id; |
||||
|
}); |
||||
|
connection.on("ServerToClient", (method, data) => { |
||||
|
PubSub.publish(method, data); |
||||
|
}); |
||||
|
|
||||
|
export { connection, connect }; |
@ -0,0 +1,41 @@ |
|||||
|
import { defineStore } from "pinia"; |
||||
|
import settings from "../config/settings.js"; |
||||
|
import { getUser, isLogin } from "../api/user.js"; |
||||
|
import { get, post } from "../request/index.js"; |
||||
|
import { refreshRouter } from "../router/index.js"; |
||||
|
import { getLocalizationAsync } from "../api/site.js"; |
||||
|
|
||||
|
const useAppStore = defineStore("app", { |
||||
|
state: () => { |
||||
|
const state = { |
||||
|
settings: { ...settings }, |
||||
|
isMenuCollapse: false, |
||||
|
isRefreshing: false, |
||||
|
routes: [], |
||||
|
}; |
||||
|
const localSettings = JSON.parse(localStorage.getItem("settings") ?? "{}"); |
||||
|
Object.assign(state.settings, localSettings); |
||||
|
return state; |
||||
|
}, |
||||
|
actions: { |
||||
|
async init() { |
||||
|
// 获取站点信息
|
||||
|
this.localization = await getLocalizationAsync(); |
||||
|
// 获取用户信息
|
||||
|
if (await isLogin()) { |
||||
|
this.user = await getUser(); |
||||
|
await refreshRouter(); |
||||
|
} |
||||
|
}, |
||||
|
add(route) { |
||||
|
if (!this.routes.find((o) => o.fullPath === route.fullPath)) { |
||||
|
this.routes.push(route); |
||||
|
} else { |
||||
|
const index = this.routes.findIndex((o) => o.fullPath === route.fullPath); |
||||
|
this.routes[index] = route; |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
export default useAppStore; |
@ -0,0 +1,7 @@ |
|||||
|
import { createPinia } from 'pinia'; |
||||
|
import useAppStore from './app.js'; |
||||
|
|
||||
|
const store = createPinia(); |
||||
|
|
||||
|
export { useAppStore }; |
||||
|
export default store; |
@ -0,0 +1,137 @@ |
|||||
|
html * { |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
html, |
||||
|
body { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
text-rendering: optimizeLegibility; |
||||
|
} |
||||
|
|
||||
|
a { |
||||
|
color: inherit; |
||||
|
text-decoration: none; |
||||
|
} |
||||
|
|
||||
|
#app { |
||||
|
width: 100vw; |
||||
|
height: 100vh; |
||||
|
--header: 60px; |
||||
|
} |
||||
|
|
||||
|
#app > .el-container { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
#app > .el-container > .el-container { |
||||
|
margin-top: var(--header); |
||||
|
height: calc(100% - var(--header)); |
||||
|
overflow: auto; |
||||
|
} |
||||
|
|
||||
|
.el-scrollbar, |
||||
|
.el-scrollbar__view { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.el-aside { |
||||
|
min-height: 100%; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
|
||||
|
.el-menu--vertical { |
||||
|
min-height: 100%; |
||||
|
} |
||||
|
|
||||
|
.el-main { |
||||
|
min-height: calc(100% - 100px); |
||||
|
overflow: auto; |
||||
|
} |
||||
|
|
||||
|
.el-header { |
||||
|
width: 100%; |
||||
|
position: fixed; |
||||
|
border-bottom: 1px solid var(--el-border-color); |
||||
|
background-color: var(--el-menu-bg-color); |
||||
|
z-index: 10; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.el-footer { |
||||
|
width: 100%; |
||||
|
border-top: 1px solid var(--el-border-color); |
||||
|
background-color: var(--el-menu-bg-color); |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
a.logo { |
||||
|
display: block; |
||||
|
height: var(--header); |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
height: var(--header); |
||||
|
} |
||||
|
|
||||
|
.logo img { |
||||
|
min-width: 28px; |
||||
|
height: 28px; |
||||
|
margin-right: 16px; |
||||
|
} |
||||
|
|
||||
|
.logo h1 { |
||||
|
height: 32px; |
||||
|
line-height: 32px; |
||||
|
padding-right: 20px; |
||||
|
} |
||||
|
|
||||
|
.el-dropdown-link:focus-visible { |
||||
|
outline: unset; |
||||
|
} |
||||
|
|
||||
|
.el-form--inline .el-form-item__content { |
||||
|
width: 192px; |
||||
|
} |
||||
|
|
||||
|
.el-table .cell { |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.el-icon { |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
|
||||
|
.el-dialog__header, |
||||
|
.el-dialog__footer, |
||||
|
.el-drawer__header, |
||||
|
.el-drawer__footer { |
||||
|
height: var(--header); |
||||
|
padding: 15px; |
||||
|
} |
||||
|
|
||||
|
.el-dialog__header, |
||||
|
.el-drawer__header { |
||||
|
border-bottom: 1px solid var(--el-border-color); |
||||
|
} |
||||
|
|
||||
|
.el-dialog__footer, |
||||
|
.el-drawer__footer { |
||||
|
border-top: 1px solid var(--el-border-color); |
||||
|
} |
||||
|
|
||||
|
.el-select, |
||||
|
.el-input-number { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
/* markdown component */ |
||||
|
.markdown-body { |
||||
|
box-sizing: border-box; |
||||
|
margin: 0 auto; |
||||
|
} |
@ -0,0 +1,120 @@ |
|||||
|
import { get } from "lodash"; |
||||
|
|
||||
|
// format html`...` by vscode lit-html
|
||||
|
function html(strings, ...values) { |
||||
|
let output = ""; |
||||
|
let index; |
||||
|
for (index = 0; index < values.length; index += 1) { |
||||
|
output += strings[index] + values[index]; |
||||
|
} |
||||
|
output += strings[index]; |
||||
|
return output; |
||||
|
} |
||||
|
|
||||
|
// format %
|
||||
|
function persentFormat(number) { |
||||
|
return `${parseFloat(number * 100).toFixed(2)} %`; |
||||
|
} |
||||
|
// format bytes
|
||||
|
function bytesFormat(bytes) { |
||||
|
if (isNaN(bytes)) { |
||||
|
return ""; |
||||
|
} |
||||
|
var symbols = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; |
||||
|
var exp = Math.floor(Math.log(bytes) / Math.log(2)); |
||||
|
if (exp < 1) { |
||||
|
exp = 0; |
||||
|
} |
||||
|
var i = Math.floor(exp / 10); |
||||
|
bytes = bytes / Math.pow(2, 10 * i); |
||||
|
|
||||
|
if (bytes.toString().length > bytes.toFixed(2).toString().length) { |
||||
|
bytes = bytes.toFixed(2); |
||||
|
} |
||||
|
return bytes + " " + symbols[i]; |
||||
|
} |
||||
|
|
||||
|
// string format
|
||||
|
function format(template, ...args) { |
||||
|
const formatRegExp = /%[sdj%]/g; |
||||
|
let counter = 0; |
||||
|
return template.replace(formatRegExp, (match) => { |
||||
|
const index = counter; |
||||
|
counter += 1; |
||||
|
if (match === "%%") { |
||||
|
return "%"; |
||||
|
} |
||||
|
if (index > args.length - 1) { |
||||
|
return match; |
||||
|
} |
||||
|
if (match === "%s") { |
||||
|
return String(args[index]); |
||||
|
} |
||||
|
if (match === "%d") { |
||||
|
return Number(args[index]); |
||||
|
} |
||||
|
if (match === "%j") { |
||||
|
return JSON.stringify(args[index]); |
||||
|
} |
||||
|
return match; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function schemaToModel(schema) { |
||||
|
const entity = {}; |
||||
|
Object.keys(schema.properties).forEach((propertyName) => { |
||||
|
const property = schema.properties[propertyName]; |
||||
|
if (property.type === "object") { |
||||
|
entity[propertyName] = schemaToModel(property); |
||||
|
} else if ("default" in property) { |
||||
|
entity[propertyName] = property.default; |
||||
|
} else if (property.type === "array") { |
||||
|
entity[propertyName] = []; |
||||
|
} else if (property.type === "boolean") { |
||||
|
entity[propertyName] = property.nullable ? null : false; |
||||
|
} else if (property.type === "number" || property.type === "integer") { |
||||
|
entity[propertyName] = property.nullable ? null : 0; |
||||
|
} else if (property.type === "string") { |
||||
|
entity[propertyName] = null; |
||||
|
} else { |
||||
|
entity[propertyName] = null; |
||||
|
} |
||||
|
}); |
||||
|
return entity; |
||||
|
} |
||||
|
|
||||
|
function listToTree(list, func) { |
||||
|
const tree = []; |
||||
|
list.forEach((item) => { |
||||
|
if (!item.parentId) { |
||||
|
tree.push(item); |
||||
|
} else { |
||||
|
const parent = list.find((node) => node.id === item.parentId); |
||||
|
if (parent) { |
||||
|
parent.children = parent.children || []; |
||||
|
parent.children.push(item); |
||||
|
} |
||||
|
} |
||||
|
if (func) { |
||||
|
func(item); |
||||
|
} |
||||
|
}); |
||||
|
return tree; |
||||
|
} |
||||
|
|
||||
|
function treeToList(tree, list = []) { |
||||
|
tree.forEach((o) => { |
||||
|
list.push(o); |
||||
|
if (o.children?.length) { |
||||
|
treeToList(o.children, list); |
||||
|
} |
||||
|
}); |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
function getProp(instance, propPath) { |
||||
|
return get(instance, propPath); |
||||
|
} |
||||
|
|
||||
|
export default html; |
||||
|
export { persentFormat, bytesFormat, format, schemaToModel, listToTree, treeToList, getProp }; |
@ -0,0 +1,3 @@ |
|||||
|
export default { |
||||
|
template: `403`, |
||||
|
}; |
@ -0,0 +1,3 @@ |
|||||
|
export default { |
||||
|
template: `404:{{$route}}`, |
||||
|
}; |
@ -0,0 +1,7 @@ |
|||||
|
import html from 'html'; |
||||
|
import Md from '../components/markdown/index.js' |
||||
|
|
||||
|
export default { |
||||
|
components: { Md }, |
||||
|
template: html`Home <md name="test"></md>` |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
import AppList from "../components/list/index.js"; |
||||
|
import html from "html"; |
||||
|
import router from "../router/index.js"; |
||||
|
|
||||
|
export default { |
||||
|
components: { AppList }, |
||||
|
template: html`<el-scrollbar>
|
||||
|
<app-list @command="onCommand"> |
||||
|
<template #columns="scope"> |
||||
|
<el-table-column label="自定义列测试1" prop="id"> |
||||
|
<template #default="scope"> {{scope.row.id}} </template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="自定义列测试2"> |
||||
|
<template #default="scope"> {{scope.row.parent?.id}} </template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
<template #tableButtons="{rows}"> |
||||
|
<el-button class="el-button--primary" @click="()=>(console.log(rows))">{{$t('test')}}</el-button> |
||||
|
</template> |
||||
|
<template #rowButtons="{rows}"> |
||||
|
<el-button class="el-button--primary" @click="()=>(console.log(rows))">{{$t('test')}}</el-button> |
||||
|
</template> |
||||
|
</app-list> |
||||
|
</el-scrollbar>`, |
||||
|
setup() { |
||||
|
console.log(router.currentRoute.value.fullPath); |
||||
|
const onCommand = (item, rows) => { |
||||
|
console.log(item.path, item, rows); |
||||
|
}; |
||||
|
return { onCommand }; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,90 @@ |
|||||
|
import html, { schemaToModel } from "html"; |
||||
|
import { ref, reactive } from "vue"; |
||||
|
import AppForm from "../components/form/index.js"; |
||||
|
import { login } from "../api/user.js"; |
||||
|
import { get } from "../request/index.js"; |
||||
|
import LayoutLogo from "../layouts/logo.js"; |
||||
|
import LayoutLocale from "../layouts/locale.js"; |
||||
|
import LayoutFooter from "../layouts/footer.js"; |
||||
|
|
||||
|
export default { |
||||
|
components: { AppForm, LayoutLogo, LayoutLocale, LayoutFooter }, |
||||
|
template: html`<el-container>
|
||||
|
<el-main class="flex justify-center"> |
||||
|
<div> |
||||
|
<div class="flex items-center justify-center"> |
||||
|
<layout-logo /> |
||||
|
<layout-locale /> |
||||
|
</div> |
||||
|
<el-card class="box-card" style="width:400px;"> |
||||
|
<app-form :schema="schema" v-model="model" :action="action" @submit="submit">{{$t('login')}}</app-form> |
||||
|
</el-card> |
||||
|
<layout-footer /> |
||||
|
</div> |
||||
|
</el-main> |
||||
|
</el-container>`, |
||||
|
async setup() { |
||||
|
const schema = reactive({ |
||||
|
title: "LoginRequestModel", |
||||
|
type: "object", |
||||
|
properties: { |
||||
|
username: { |
||||
|
title: "用户名", |
||||
|
type: "string", |
||||
|
rules: [ |
||||
|
{ |
||||
|
required: true, |
||||
|
message: "用户名不能为空", |
||||
|
}, |
||||
|
{ |
||||
|
max: 64, |
||||
|
message: "用户名的最大长度为 64", |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
password: { |
||||
|
title: "密码", |
||||
|
type: "string", |
||||
|
format: "password", |
||||
|
rules: [ |
||||
|
{ |
||||
|
required: true, |
||||
|
message: "密码不能为空", |
||||
|
}, |
||||
|
{ |
||||
|
max: 64, |
||||
|
message: "密码的最大长度为 64", |
||||
|
}, |
||||
|
{ |
||||
|
message: "DataTypeAttribute", |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
client_id: { |
||||
|
default: "basic-web", |
||||
|
hidden: true, |
||||
|
}, |
||||
|
grant_type: { |
||||
|
default: "password", |
||||
|
hidden: true, |
||||
|
}, |
||||
|
scope: { |
||||
|
default: "WebAppGateway BaseService", |
||||
|
hidden: true, |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
const model = reactive(schemaToModel(schema)); |
||||
|
const submit = async (callback) => { |
||||
|
const result = await login(model); |
||||
|
if (result.errors) { |
||||
|
callback(result.errors); |
||||
|
} |
||||
|
}; |
||||
|
return { |
||||
|
schema, |
||||
|
model, |
||||
|
submit, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,216 @@ |
|||||
|
import html from "html"; |
||||
|
import { ref, reactive, onMounted, onUnmounted } from "vue"; |
||||
|
import { useRoute } from "vue-router"; |
||||
|
import Chart from "../components/chart/index.js"; |
||||
|
import { get, post } from "../request/index.js"; |
||||
|
import { ElMessage, dayjs } from "element-plus"; |
||||
|
import { bytesFormat, persentFormat } from "../utils/index.js"; |
||||
|
import PubSub from "pubsub-js"; |
||||
|
|
||||
|
export default { |
||||
|
components: { Chart }, |
||||
|
template: html` <template v-if="model">
|
||||
|
<el-row :gutter="20" style="margin-bottom:20px;"> |
||||
|
<el-col :span="24"> |
||||
|
<el-card class="box-card"> |
||||
|
<template #header> |
||||
|
<div class="card-header"> |
||||
|
<span>操作系统</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<el-descriptions border direction="vertical" :column="4"> |
||||
|
<el-descriptions-item label="架构">{{model.osArchitecture}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="名称">{{model.osDescription}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="主机">{{model.hostName}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="用户">{{model.userName}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="时间">{{dayjs(model.serverTime).format()}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="地址">{{model.hostAddresses}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="进程">{{model.processCount}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="线程">{{model.threadCount}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="名称">{{model.driveName}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="大小">{{bytesFormat(model.drivieTotalSize)}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="剩余">{{bytesFormat(model.driveAvailableFreeSpace)}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="占用">{{persentFormat(1-model.driveAvailableFreeSpace/model.drivieTotalSize)}}</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row :gutter="20" style="margin-bottom:20px;"> |
||||
|
<el-col :span="12"> |
||||
|
<el-card class="box-card"> |
||||
|
<template #header> |
||||
|
<div class="card-header"> |
||||
|
<span>处理器 {{model.processorCount}} </span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<chart :option="cpuModel" height="300px" /> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-card class="box-card"> |
||||
|
<template #header> |
||||
|
<div class="card-header"> |
||||
|
<span>内存 {{bytesFormat(model.totalMemory)}}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<chart :option="memoryModel" height="300px" /> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row :gutter="20" style="margin-bottom:20px;"> |
||||
|
<el-col :span="12"> |
||||
|
<el-card class="box-card"> |
||||
|
<template #header> |
||||
|
<div class="card-header"> |
||||
|
<span>磁盘</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<el-descriptions border direction="vertical"> |
||||
|
<el-descriptions-item label="读取">{{bytesFormat(model.diskRead)}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="写入">{{bytesFormat(model.diskWrite)}}</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-card class="box-card"> |
||||
|
<template #header> |
||||
|
<div class="card-header"> |
||||
|
<span>网络</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<el-descriptions border direction="vertical"> |
||||
|
<el-descriptions-item label="下载">{{bytesFormat(model.netReceived)}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="上传">{{bytesFormat(model.netSent)}}</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row :gutter="20" style="margin-bottom:20px;"> |
||||
|
<el-col :span="24"> |
||||
|
<el-card class="box-card"> |
||||
|
<template #header> |
||||
|
<div class="card-header"> |
||||
|
<span>.NET</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<el-descriptions border direction="vertical" :column="4"> |
||||
|
<el-descriptions-item label="名称">{{model.frameworkDescription}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="已分配内存">{{bytesFormat(model.gcTotalMemory)}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="可回收对象">{{model.finalizationPendingCount}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="堆大小">{{bytesFormat(model.heapSizeBytes)}}</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row :gutter="20" style="margin-bottom:20px;"> |
||||
|
<el-col :span="24"> |
||||
|
<el-card class="box-card"> |
||||
|
<template #header> |
||||
|
<div class="card-header"> |
||||
|
<span>应用</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<el-descriptions border direction="vertical" :column="5"> |
||||
|
<el-descriptions-item label="架构">{{model.processArchitecture}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="启动时间">{{dayjs(model.processStartTime).format()}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="启动位置">{{model.processFileName}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="参数">{{model.processArguments}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="进程Id">{{model.processId}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="进程名称">{{model.processName}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="CPU">{{persentFormat(model.processCpuUsage)}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="内存">{{bytesFormat(model.processMemory)}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="磁盘读写" |
||||
|
>{{bytesFormat(model.processDiskRead)}} / {{bytesFormat(model.processDiskWrite)}}</el-descriptions-item |
||||
|
> |
||||
|
<el-descriptions-item label="线程">{{model.processThreadCount}}</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</template>`, |
||||
|
setup(props) { |
||||
|
const route = useRoute(); |
||||
|
const baseUrl = `${route.meta.path}`.substring(1); |
||||
|
const url = `${baseUrl}/index`; |
||||
|
const schema = reactive({}); |
||||
|
const model = reactive({}); |
||||
|
//
|
||||
|
const cpuModel = reactive({ |
||||
|
title: { |
||||
|
text: "处理器", |
||||
|
}, |
||||
|
xAxis: { |
||||
|
type: "category", |
||||
|
data: Object.keys(Array(30).fill()), |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: "value", |
||||
|
min: 0, |
||||
|
max: 100, |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
data: [], |
||||
|
type: "line", |
||||
|
smooth: true, |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
|
||||
|
const memoryModel = reactive({ |
||||
|
title: { |
||||
|
text: "内存", |
||||
|
}, |
||||
|
xAxis: { |
||||
|
type: "category", |
||||
|
data: Object.keys(Array(30).fill()), |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: "value", |
||||
|
min: 0, |
||||
|
max: 100, |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
data: [], |
||||
|
type: "bar", |
||||
|
smooth: true, |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
//
|
||||
|
const onMonitor = (method, data) => { |
||||
|
Object.assign(model, data); |
||||
|
// cpu
|
||||
|
if (cpuModel.series[0].data.length > 30) { |
||||
|
cpuModel.series[0].data.shift(); |
||||
|
} |
||||
|
cpuModel.title.text = `处理器 ${persentFormat(model.cpuUsage)}`; |
||||
|
cpuModel.series[0].data.push(model.cpuUsage * 100); |
||||
|
// memory
|
||||
|
if (memoryModel.series[0].data.length > 30) { |
||||
|
memoryModel.series[0].data.shift(); |
||||
|
} |
||||
|
memoryModel.title.text = `内存 ${persentFormat(model.memoryUsage)}`; |
||||
|
memoryModel.series[0].data.push(model.memoryUsage * 100); |
||||
|
}; |
||||
|
onMounted(async () => { |
||||
|
Object.assign(schema, (await get(url)).data); |
||||
|
Object.assign(model, (await post(url)).data); |
||||
|
PubSub.subscribe("monitor", onMonitor); |
||||
|
}); |
||||
|
onUnmounted(() => { |
||||
|
PubSub.unsubscribe(onMonitor); |
||||
|
}); |
||||
|
//
|
||||
|
return { |
||||
|
schema, |
||||
|
model, |
||||
|
cpuModel, |
||||
|
memoryModel, |
||||
|
dayjs, |
||||
|
bytesFormat, |
||||
|
persentFormat, |
||||
|
}; |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,14 @@ |
|||||
|
# https://editorconfig.org |
||||
|
root = true |
||||
|
|
||||
|
[*] |
||||
|
charset = utf-8 |
||||
|
indent_style = space |
||||
|
indent_size = 2 |
||||
|
end_of_line = lf |
||||
|
insert_final_newline = true |
||||
|
trim_trailing_whitespace = true |
||||
|
|
||||
|
[*.md] |
||||
|
insert_final_newline = false |
||||
|
trim_trailing_whitespace = false |
@ -0,0 +1,15 @@ |
|||||
|
# just a flag |
||||
|
ENV = 'development' |
||||
|
|
||||
|
# base api |
||||
|
VUE_APP_BASE_API = '/dev-api' |
||||
|
VUE_APP_BASE_API_ADMIN = 'http://114.116.225.148:8002' |
||||
|
port='9528' |
||||
|
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, |
||||
|
# to control whether the babel-plugin-dynamic-import-node plugin is enabled. |
||||
|
# It only does one thing by converting all import() to require(). |
||||
|
# This configuration can significantly increase the speed of hot updates, |
||||
|
# when you have a large number of pages. |
||||
|
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js |
||||
|
|
||||
|
VUE_CLI_BABEL_TRANSPILE_MODULES = true |
@ -0,0 +1,6 @@ |
|||||
|
# just a flag |
||||
|
ENV = 'production' |
||||
|
|
||||
|
# base api |
||||
|
VUE_APP_BASE_API = '/prod-api' |
||||
|
|