Compare commits
61 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dd2e3a65af | ||
|
7adc37990a | ||
|
8a75c11182 | ||
|
7fd7366e32 | ||
|
1354ea21e4 | ||
|
2d6108be44 | ||
|
ef5c73b468 | ||
|
afe3b042d9 | ||
|
5af56e956c | ||
|
1cc3fb0c3b | ||
|
39194d51c0 | ||
|
8d582b482c | ||
|
13e124c02a | ||
|
10ea077735 | ||
|
e191f76809 | ||
|
e91dca078b | ||
|
e1d388dbfc | ||
|
39cd05fb44 | ||
|
8364ef731e | ||
|
cff85f09d5 | ||
|
eff099877e | ||
|
303777910c | ||
|
76bd8ed3fe | ||
|
53c12a787e | ||
|
2970fe16da | ||
|
4229620d8d | ||
|
9c148dbb6b | ||
|
74c0b0a484 | ||
|
974322a2b8 | ||
|
7ca8bd3244 | ||
|
332e728ca3 | ||
|
bc5fa85ba6 | ||
|
aafcb6527f | ||
|
03d8bd2eb4 | ||
|
7a33c4d4f7 | ||
|
bc5f239cb7 | ||
|
53a694be36 | ||
|
9f635dc5f4 | ||
|
b3b427edef | ||
|
adc7b21fc2 | ||
|
61f39a7c64 | ||
|
13bfb7d7b8 | ||
|
8265cbc6d0 | ||
|
4d240c24d2 | ||
|
2c39c91108 | ||
|
df611901c6 | ||
|
ae44370f78 | ||
|
149812914e | ||
|
b08cd1ca42 | ||
|
1e7dbec10b | ||
|
9bb0d17fb8 | ||
|
953cdda006 | ||
|
3ccbc2c4b2 | ||
|
057915375a | ||
|
64f221fb3f | ||
|
0189fa867a | ||
|
c5cfe3ffcb | ||
|
5053d59f62 | ||
|
f8c748a15a | ||
|
7036c1fc02 | ||
|
20a425ed8c |
21
.gitignore
vendored
@ -1,22 +1 @@
|
||||
# Build and Release Folders
|
||||
bin-debug/
|
||||
bin-release/
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
|
||||
# Other files and folders
|
||||
.settings/
|
||||
|
||||
# Executables
|
||||
*.swf
|
||||
*.air
|
||||
*.ipa
|
||||
*.apk
|
||||
|
||||
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
|
||||
# should NOT be excluded as they contain compiler settings and other important
|
||||
# information for Eclipse / Flash Builder.
|
||||
docker_env/mysql/data/
|
||||
docker_env/redis/data/
|
||||
*/.idea
|
||||
dvadmin-doc/docs/.vuepress/dist
|
27
README.md
@ -47,14 +47,23 @@ Kinit 是一套全部开源的快速开发平台,毫无保留给个人及企
|
||||
|
||||
提供一个技术交流群,现在还没什么人哈哈哈哈哈,真心希望大家能够加入,积极讨论,因为本项目中还没有详细使用文档(一直在欠着,我也挺不好意思的),所以大家加入后,也可以很方便的一起讨论在使用中遇到各种问题,也可以提一些你想加入的功能,让我们更近一点,欢迎大家的加入。
|
||||
|
||||
|
||||
|
||||
2024-4-25 目前群聊已经达到 200 人,只能通过邀请进群,不能再直接扫描群二维码进群,需要进群的可以先加我,备注进群,我就拉你进群。
|
||||
|
||||
<div align="center">
|
||||
<p align="center">
|
||||
<img src="https://ktianc.oss-cn-beijing.aliyuncs.com/resource/images/1708272000/1708353174EhXbRf5M.jpg" height="500" alt="logo"/>
|
||||
<img src="https://ktianc.oss-cn-beijing.aliyuncs.com/kinit/public/images/WechatIMG285.jpg" height="500" alt="logo"/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 在线体验
|
||||
|
||||
PC端演示地址:https://kinit.ktianc.top
|
||||
@ -248,10 +257,14 @@ git clone https://gitee.com/ktianc/kinit.git
|
||||
### 准备工作
|
||||
|
||||
```
|
||||
Python == 3.10 (其他版本均未测试)
|
||||
nodejs >= 14.0 (推荐使用最新稳定版)
|
||||
Mysql >= 8.0
|
||||
MongoDB (推荐使用最新稳定版)
|
||||
后端依赖版本:
|
||||
Python == 3.10.x (其他版本均未测试)
|
||||
前端依赖版本:
|
||||
nodejs >= 18.0 < 19
|
||||
pnpm >= 8.1.0 < 9
|
||||
数据库版本:
|
||||
Mysql >= 8.0 (8 以上未测试,以下版本未测试,postgresql 未测试,更换可能会涉及调整)
|
||||
MongoDB >= 7.0.12 < 8 (7 以上或以下版本均未测试)
|
||||
Redis (推荐使用最新稳定版)
|
||||
```
|
||||
|
||||
@ -330,13 +343,13 @@ Redis (推荐使用最新稳定版)
|
||||
[dev]
|
||||
# 开发环境
|
||||
version_locations = %(here)s/alembic/versions_dev
|
||||
sqlalchemy.url = sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1/kinit
|
||||
sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1/kinit
|
||||
|
||||
|
||||
[pro]
|
||||
# 生产环境
|
||||
version_locations = %(here)s/alembic/versions_pro
|
||||
sqlalchemy.url = sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1/kinit
|
||||
sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1/kinit
|
||||
```
|
||||
|
||||
5. 创建数据库
|
||||
|
2
kinit-admin/.gitignore
vendored
@ -5,3 +5,5 @@ dist-ssr
|
||||
*-lock.*
|
||||
pnpm-debug
|
||||
stats.html
|
||||
dist-pro
|
||||
.vscode
|
||||
|
3
kinit-admin/.vscode/extensions.json
vendored
@ -1,3 +0,0 @@
|
||||
{
|
||||
"recommendations": ["vue.volar", "lokalise.i18n-ally"]
|
||||
}
|
19
kinit-admin/.vscode/settings.json
vendored
@ -1,19 +0,0 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"prettier.enable": false,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
},
|
||||
"i18n-ally.localesPaths": ["src/locales"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.sortKeys": true,
|
||||
"i18n-ally.namespace": false,
|
||||
"i18n-ally.enabledParsers": ["ts"],
|
||||
"i18n-ally.sourceLanguage": "zh-CN",
|
||||
"i18n-ally.displayLanguage": "zh-CN",
|
||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||
"god.tsconfig": "./tsconfig.json"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-element-plus-admin",
|
||||
"version": "2.5.6",
|
||||
"version": "2.7.0",
|
||||
"description": "一套基于vue3、element-plus、typesScript、vite4的后台集成方案。",
|
||||
"author": "Archer <502431556@qq.com>",
|
||||
"private": false,
|
||||
@ -24,18 +24,18 @@
|
||||
"dependencies": {
|
||||
"@iconify/iconify": "3.1.1",
|
||||
"@iconify/vue": "4.1.1",
|
||||
"@vueuse/core": "10.7.1",
|
||||
"@vueuse/core": "10.9.0",
|
||||
"@wangeditor/editor": "5.1.23",
|
||||
"@wangeditor/editor-for-vue": "5.1.10",
|
||||
"@zxcvbn-ts/core": "3.0.4",
|
||||
"animate.css": "4.1.1",
|
||||
"axios": "1.6.5",
|
||||
"axios": "1.6.7",
|
||||
"cropperjs": "1.6.1",
|
||||
"dayjs": "1.11.10",
|
||||
"driver.js": "1.3.1",
|
||||
"echarts": "5.4.3",
|
||||
"echarts": "5.5.0",
|
||||
"echarts-wordcloud": "2.1.0",
|
||||
"element-plus": "2.4.4",
|
||||
"element-plus": "2.5.6",
|
||||
"lodash-es": "4.17.21",
|
||||
"mitt": "3.0.1",
|
||||
"nprogress": "0.2.0",
|
||||
@ -44,68 +44,68 @@
|
||||
"qrcode": "1.5.3",
|
||||
"qs": "6.11.2",
|
||||
"url": "0.11.3",
|
||||
"vue": "3.4.7",
|
||||
"vue-draggable-plus": "0.3.4",
|
||||
"vue-i18n": "9.9.0",
|
||||
"vue": "3.4.20",
|
||||
"vue-draggable-plus": "0.3.5",
|
||||
"vue-i18n": "9.9.1",
|
||||
"vue-json-pretty": "2.3.0",
|
||||
"vue-router": "4.2.5",
|
||||
"vue-router": "4.3.0",
|
||||
"vue-types": "5.1.1",
|
||||
"xgplayer": "3.0.11"
|
||||
"xgplayer": "3.0.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@amap/amap-jsapi-loader": "1.0.1",
|
||||
"@commitlint/cli": "18.4.4",
|
||||
"@commitlint/config-conventional": "18.4.4",
|
||||
"@iconify/json": "2.2.166",
|
||||
"@commitlint/cli": "19.0.1",
|
||||
"@commitlint/config-conventional": "19.0.0",
|
||||
"@iconify/json": "2.2.187",
|
||||
"@intlify/unplugin-vue-i18n": "2.0.0",
|
||||
"@kjgl77/datav-vue3": "1.6.1",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/inquirer": "9.0.7",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/node": "20.10.8",
|
||||
"@types/node": "20.11.21",
|
||||
"@types/nprogress": "0.2.3",
|
||||
"@types/qrcode": "1.5.5",
|
||||
"@types/qs": "6.9.11",
|
||||
"@types/sortablejs": "1.15.7",
|
||||
"@typescript-eslint/eslint-plugin": "6.18.1",
|
||||
"@typescript-eslint/parser": "6.18.1",
|
||||
"@unocss/transformer-variant-group": "0.58.3",
|
||||
"@vitejs/plugin-legacy": "5.2.0",
|
||||
"@vitejs/plugin-vue": "5.0.2",
|
||||
"@types/qs": "6.9.12",
|
||||
"@types/sortablejs": "1.15.8",
|
||||
"@typescript-eslint/eslint-plugin": "7.1.0",
|
||||
"@typescript-eslint/parser": "7.1.0",
|
||||
"@unocss/transformer-variant-group": "0.58.5",
|
||||
"@vitejs/plugin-legacy": "5.3.1",
|
||||
"@vitejs/plugin-vue": "5.0.4",
|
||||
"@vitejs/plugin-vue-jsx": "3.1.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"autoprefixer": "10.4.17",
|
||||
"chalk": "5.3.0",
|
||||
"consola": "3.2.3",
|
||||
"cron-validate": "1.4.5",
|
||||
"eslint": "8.56.0",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-define-config": "2.1.0",
|
||||
"eslint-plugin-prettier": "5.1.2",
|
||||
"eslint-plugin-vue": "9.19.2",
|
||||
"eslint-plugin-prettier": "5.1.3",
|
||||
"eslint-plugin-vue": "9.22.0",
|
||||
"esno": "4.0.0",
|
||||
"fs-extra": "11.2.0",
|
||||
"inquirer": "9.2.12",
|
||||
"inquirer": "9.2.15",
|
||||
"less": "4.2.0",
|
||||
"lint-staged": "15.2.0",
|
||||
"lint-staged": "15.2.2",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.30.1",
|
||||
"plop": "4.0.1",
|
||||
"postcss": "8.4.33",
|
||||
"postcss-html": "1.5.0",
|
||||
"postcss": "8.4.35",
|
||||
"postcss-html": "1.6.0",
|
||||
"postcss-less": "6.0.0",
|
||||
"prettier": "3.1.1",
|
||||
"prettier": "3.2.5",
|
||||
"rimraf": "5.0.5",
|
||||
"rollup": "4.9.4",
|
||||
"rollup": "4.12.0",
|
||||
"rollup-plugin-visualizer": "5.12.0",
|
||||
"stylelint": "16.1.0",
|
||||
"stylelint": "16.2.1",
|
||||
"stylelint-config-html": "1.1.0",
|
||||
"stylelint-config-recommended": "14.0.0",
|
||||
"stylelint-config-standard": "36.0.0",
|
||||
"stylelint-order": "6.0.4",
|
||||
"terser": "5.26.0",
|
||||
"terser": "5.28.1",
|
||||
"typescript": "5.3.3",
|
||||
"unocss": "0.58.3",
|
||||
"vite": "5.0.11",
|
||||
"unocss": "0.58.5",
|
||||
"vite": "5.1.4",
|
||||
"vite-plugin-ejs": "1.7.0",
|
||||
"vite-plugin-eslint": "1.8.1",
|
||||
"vite-plugin-progress": "0.0.7",
|
||||
@ -113,14 +113,15 @@
|
||||
"vite-plugin-style-import": "2.0.0",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vue-draggable-plus": "0.2.6",
|
||||
"vite-plugin-url-copy": "1.1.3",
|
||||
"vue-tsc": "1.8.27",
|
||||
"vue3-json-viewer": "2.2.2",
|
||||
"zipson": "^0.2.12"
|
||||
"zipson": "0.2.12"
|
||||
},
|
||||
"packageManager": "pnpm@8.1.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"pnpm": ">=8.1.0"
|
||||
"node": ">=18 <19",
|
||||
"pnpm": ">=8.1.0 <10.0.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
@ -9,7 +9,7 @@ const prefixCls = getPrefixCls('footer')
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const title = computed(() => appStore.getTitle)
|
||||
const footerContent = computed(() => appStore.getFooterContent)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -17,6 +17,6 @@ const title = computed(() => appStore.getTitle)
|
||||
:class="prefixCls"
|
||||
class="shrink-0 text-center text-[var(--el-text-color-placeholder)] bg-[var(--app-content-bg-color)] h-[var(--app-footer-height)] leading-[var(--app-footer-height)] dark:bg-[var(--el-bg-color)]"
|
||||
>
|
||||
Copyright ©2021-present {{ title }}
|
||||
{{ footerContent }}
|
||||
</div>
|
||||
</template>
|
||||
|
@ -484,7 +484,15 @@ export default defineComponent({
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.@{elNamespace}-form--inline .@{elNamespace}-input {
|
||||
width: 245px;
|
||||
.@{elNamespace}-form--inline {
|
||||
:deep(.el-form-item__content) {
|
||||
& > :first-child {
|
||||
min-width: 229.5px;
|
||||
}
|
||||
}
|
||||
.@{elNamespace}-input-number {
|
||||
// 229.5px是兼容el-input-number的最小宽度,
|
||||
min-width: 229.5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -93,7 +93,7 @@ export default defineComponent({
|
||||
>
|
||||
{{
|
||||
default: () => {
|
||||
const { renderMenuItem } = useRenderMenuItem(unref(menuMode))
|
||||
const { renderMenuItem } = useRenderMenuItem()
|
||||
return renderMenuItem(unref(routers))
|
||||
}
|
||||
}}
|
||||
|
@ -2,57 +2,49 @@ import { ElSubMenu, ElMenuItem } from 'element-plus'
|
||||
import { hasOneShowingChild } from '../helper'
|
||||
import { isUrl } from '@/utils/is'
|
||||
import { useRenderMenuTitle } from './useRenderMenuTitle'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
import { pathResolve } from '@/utils/routerHelper'
|
||||
|
||||
const { renderMenuTitle } = useRenderMenuTitle()
|
||||
|
||||
export const useRenderMenuItem = (
|
||||
export const useRenderMenuItem = () =>
|
||||
// allRouters: AppRouteRecordRaw[] = [],
|
||||
menuMode: 'vertical' | 'horizontal'
|
||||
) => {
|
||||
const renderMenuItem = (routers: AppRouteRecordRaw[], parentPath = '/') => {
|
||||
return routers
|
||||
.filter((v) => !v.meta?.hidden)
|
||||
.map((v) => {
|
||||
const meta = v.meta ?? {}
|
||||
const { oneShowingChild, onlyOneChild } = hasOneShowingChild(v.children, v)
|
||||
const fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path) // getAllParentPath<AppRouteRecordRaw>(allRouters, v.path).join('/')
|
||||
{
|
||||
const renderMenuItem = (routers: AppRouteRecordRaw[], parentPath = '/') => {
|
||||
return routers
|
||||
.filter((v) => !v.meta?.hidden)
|
||||
.map((v) => {
|
||||
const meta = v.meta ?? {}
|
||||
const { oneShowingChild, onlyOneChild } = hasOneShowingChild(v.children, v)
|
||||
const fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path) // getAllParentPath<AppRouteRecordRaw>(allRouters, v.path).join('/')
|
||||
|
||||
if (
|
||||
oneShowingChild &&
|
||||
(!onlyOneChild?.children || onlyOneChild?.noShowingChildren) &&
|
||||
!meta?.alwaysShow
|
||||
) {
|
||||
return (
|
||||
<ElMenuItem index={onlyOneChild ? pathResolve(fullPath, onlyOneChild.path) : fullPath}>
|
||||
{{
|
||||
default: () => renderMenuTitle(onlyOneChild ? onlyOneChild?.meta : meta)
|
||||
}}
|
||||
</ElMenuItem>
|
||||
)
|
||||
} else {
|
||||
const { getPrefixCls } = useDesign()
|
||||
if (
|
||||
oneShowingChild &&
|
||||
(!(onlyOneChild?.children?.length !== 0) || onlyOneChild?.noShowingChildren) &&
|
||||
!meta?.alwaysShow
|
||||
) {
|
||||
return (
|
||||
<ElMenuItem
|
||||
index={onlyOneChild ? pathResolve(fullPath, onlyOneChild.path) : fullPath}
|
||||
>
|
||||
{{
|
||||
default: () => renderMenuTitle(onlyOneChild ? onlyOneChild?.meta : meta)
|
||||
}}
|
||||
</ElMenuItem>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<ElSubMenu index={fullPath}>
|
||||
{{
|
||||
title: () => renderMenuTitle(meta),
|
||||
default: () => renderMenuItem(v.children!, fullPath)
|
||||
}}
|
||||
</ElSubMenu>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const preFixCls = getPrefixCls('menu-popper')
|
||||
return (
|
||||
<ElSubMenu
|
||||
index={fullPath}
|
||||
popperClass={
|
||||
menuMode === 'vertical' ? `${preFixCls}--vertical` : `${preFixCls}--horizontal`
|
||||
}
|
||||
>
|
||||
{{
|
||||
title: () => renderMenuTitle(meta),
|
||||
default: () => renderMenuItem(v.children!, fullPath)
|
||||
}}
|
||||
</ElSubMenu>
|
||||
)
|
||||
}
|
||||
})
|
||||
return {
|
||||
renderMenuItem
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
renderMenuItem
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,9 @@ export default defineComponent({
|
||||
} else {
|
||||
showTitle.value = !collapse
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
|
||||
@ -202,11 +205,12 @@ export default defineComponent({
|
||||
</div>
|
||||
<Menu
|
||||
class={[
|
||||
'!absolute top-0 z-1000',
|
||||
'!absolute top-0 z-3000',
|
||||
{
|
||||
'!left-[var(--tab-menu-min-width)]': unref(collapse),
|
||||
'!left-[var(--tab-menu-max-width)]': !unref(collapse),
|
||||
'!w-[var(--left-menu-max-width)]': unref(showMenu) || unref(fixedMenu),
|
||||
'!w-[var(--left-menu-max-width)] border-r-1 border-r-solid border-[var(--el-border-color)]':
|
||||
unref(showMenu) || unref(fixedMenu),
|
||||
'!w-0': !unref(showMenu) && !unref(fixedMenu)
|
||||
}
|
||||
]}
|
||||
|
@ -80,7 +80,7 @@ export default defineComponent({
|
||||
border: propTypes.bool.def(true),
|
||||
size: {
|
||||
type: String as PropType<ComponentSize>,
|
||||
validator: (v: ComponentSize) => ['medium', 'small', 'mini'].includes(v)
|
||||
validator: (v: ComponentSize) => ['default', 'small', 'large'].includes(v)
|
||||
},
|
||||
fit: propTypes.bool.def(true),
|
||||
showHeader: propTypes.bool.def(true),
|
||||
@ -349,6 +349,7 @@ export default defineComponent({
|
||||
const bindValue: Recordable = { ...attrs, ...unref(getProps) }
|
||||
delete bindValue.columns
|
||||
delete bindValue.data
|
||||
delete bindValue.align
|
||||
return bindValue
|
||||
})
|
||||
|
||||
|
@ -24,13 +24,8 @@ import { propTypes } from '@/utils/propTypes'
|
||||
import { moveElementToIndex } from '@/utils/index'
|
||||
import { BaseButton } from '@/components/Button'
|
||||
|
||||
const appStore = useAppStore()
|
||||
const sizeMap = computed(() => appStore.sizeMap)
|
||||
|
||||
const { setStorage, getStorage, removeStorage } = useStorage()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TableActions',
|
||||
props: {
|
||||
@ -47,6 +42,10 @@ export default defineComponent({
|
||||
},
|
||||
emits: ['refresh', 'changSize'],
|
||||
setup(props, { emit }) {
|
||||
const appStore = useAppStore()
|
||||
const sizeMap = computed(() => appStore.sizeMap)
|
||||
const { t } = useI18n()
|
||||
|
||||
const refresh = () => {
|
||||
emit('refresh')
|
||||
}
|
||||
|
@ -210,13 +210,14 @@ const isActive = (route: RouteLocationNormalizedLoaded): boolean => {
|
||||
// 所有右键菜单组件的元素
|
||||
const itemRefs = useTemplateRefsList<ComponentRef<typeof ContextMenu & ContextMenuExpose>>()
|
||||
|
||||
// 右键菜单装填改变的时候
|
||||
// 右键菜单状态改变的时候
|
||||
const visibleChange = (visible: boolean, tagItem: RouteLocationNormalizedLoaded) => {
|
||||
if (visible) {
|
||||
for (const v of unref(itemRefs)) {
|
||||
const elDropdownMenuRef = v.elDropdownMenuRef
|
||||
if (tagItem.fullPath !== v.tagItem.fullPath) {
|
||||
elDropdownMenuRef?.handleClose()
|
||||
setSelectTag(tagItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -582,4 +583,3 @@ watch(
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@/hooks/web/useTagsView
|
||||
|
@ -113,7 +113,7 @@ service.interceptors.response.use(
|
||||
case 401:
|
||||
// 强制要求重新登录,因账号已冻结,账号已过期,手机号码错误,刷新token无效等问题导致
|
||||
authStore.logout()
|
||||
message = '认证已过期,请重新登录'
|
||||
message = '认证已失效,请重新登录'
|
||||
break
|
||||
case 403:
|
||||
// 强制要求重新登录,因无系统权限,而进入到系统访问等问题导致
|
||||
|
@ -12,7 +12,7 @@ const { start, done } = useNProgress()
|
||||
|
||||
const { loadStart, loadDone } = usePageLoading()
|
||||
|
||||
const whiteList = ['/login'] // 不重定向白名单
|
||||
const whiteList = ['/login', '/docs/privacy', '/docs/agreement'] // 不重定向白名单
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
start()
|
||||
|
@ -70,6 +70,37 @@ export const constantRouterMap: AppRouteRecordRaw[] = [
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/docs',
|
||||
name: 'Docs',
|
||||
meta: {
|
||||
hidden: true,
|
||||
title: '在线文档',
|
||||
noTagsView: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'privacy',
|
||||
name: 'Privacy',
|
||||
component: () => import('@/views/Vadmin/Docs/Privacy.vue'),
|
||||
meta: {
|
||||
hidden: true,
|
||||
title: '隐私政策',
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'agreement',
|
||||
name: 'Agreement',
|
||||
component: () => import('@/views/Vadmin/Docs/Agreement.vue'),
|
||||
meta: {
|
||||
hidden: true,
|
||||
title: '用户协议',
|
||||
noTagsView: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
component: () => import('@/views/Error/404.vue'),
|
||||
@ -115,7 +146,17 @@ const router = createRouter({
|
||||
})
|
||||
|
||||
export const resetRouter = (): void => {
|
||||
const resetWhiteNameList = ['Login', 'NoFind', 'Root', 'ResetPassword', 'Redirect', 'Home']
|
||||
const resetWhiteNameList = [
|
||||
'Login',
|
||||
'NoFind',
|
||||
'Root',
|
||||
'ResetPassword',
|
||||
'Redirect',
|
||||
'Home',
|
||||
'Docs',
|
||||
'Privacy',
|
||||
'Agreement'
|
||||
]
|
||||
router.getRoutes().forEach((route) => {
|
||||
const { name } = route
|
||||
if (name && !resetWhiteNameList.includes(name as string)) {
|
||||
|
@ -102,7 +102,8 @@ const save = async () => {
|
||||
const res = await postCurrentUserResetPassword(formData)
|
||||
if (res) {
|
||||
elForm?.resetFields()
|
||||
ElMessage.success('保存成功')
|
||||
authStore.logout()
|
||||
ElMessage.warning('请重新登录')
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
|
@ -9,6 +9,7 @@ import { useDesign } from '@/hooks/web/useDesign'
|
||||
import { ref } from 'vue'
|
||||
import { ElScrollbar } from 'element-plus'
|
||||
import { computed } from 'vue'
|
||||
import { ElButton } from 'element-plus'
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
@ -28,6 +29,11 @@ const toTelephoneLogin = () => {
|
||||
const toPasswordLogin = () => {
|
||||
isPasswordLogin.value = true
|
||||
}
|
||||
|
||||
const icpNumber = computed(() => appStore.getIcpNumber)
|
||||
const toICO = () => {
|
||||
window.open('https://beian.miit.gov.cn/#/Integrated/index')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -88,6 +94,9 @@ const toPasswordLogin = () => {
|
||||
/>
|
||||
</div>
|
||||
</Transition>
|
||||
<div class="text-14px text-white font-normal absolute bottom-5 right-10">
|
||||
<ElButton type="info" link @click="toICO">{{ icpNumber }}</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ElScrollbar>
|
||||
|
29
kinit-admin/src/views/Vadmin/Docs/Agreement.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { getSystemAgreementApi } from '@/api/vadmin/system/settings'
|
||||
|
||||
const content = ref(null)
|
||||
|
||||
// 获取隐私协议内容
|
||||
const getSystemConfig = async () => {
|
||||
const res = await getSystemAgreementApi()
|
||||
if (res) {
|
||||
content.value = res.data
|
||||
}
|
||||
}
|
||||
|
||||
getSystemConfig()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="content-view" v-html="content"></div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.content-view {
|
||||
padding: 20px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
29
kinit-admin/src/views/Vadmin/Docs/Privacy.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { getSystemPrivacyApi } from '@/api/vadmin/system/settings'
|
||||
|
||||
const content = ref(null)
|
||||
|
||||
// 获取隐私协议内容
|
||||
const getSystemConfig = async () => {
|
||||
const res = await getSystemPrivacyApi()
|
||||
if (res) {
|
||||
content.value = res.data
|
||||
}
|
||||
}
|
||||
|
||||
getSystemConfig()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="content-view" v-html="content"></div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.content-view {
|
||||
padding: 20px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -149,7 +149,7 @@ const formSchema = reactive<FormSchema[]>([
|
||||
show-file-list={false}
|
||||
before-upload={beforeImageUpload}
|
||||
on-success={handleUploadSuccess}
|
||||
accept="image/jpeg,image/gif,image/png"
|
||||
accept="image/x-icon"
|
||||
name="file"
|
||||
headers={{ Authorization: token }}
|
||||
>
|
||||
@ -259,10 +259,10 @@ const save = async () => {
|
||||
try {
|
||||
const res = await putSystemSettingsApi(formData)
|
||||
if (res) {
|
||||
appStore.setTitle(res.data.web_title || import.meta.env.VITE_APP_TITLE)
|
||||
appStore.setLogoImage(res.data.web_logo || '/static/system/logo.png')
|
||||
appStore.setFooterContent(res.data.web_copyright || 'Copyright ©2022-present K')
|
||||
appStore.setIcpNumber(res.data.web_icp_number || '')
|
||||
appStore.setTitle(formData.web_title || import.meta.env.VITE_APP_TITLE)
|
||||
appStore.setLogoImage(formData.web_logo || '/media/system/logo.png')
|
||||
appStore.setFooterContent(formData.web_copyright || 'Copyright ©2022-present K')
|
||||
appStore.setIcpNumber(formData.web_icp_number || '')
|
||||
return ElMessage.success('更新成功')
|
||||
}
|
||||
} finally {
|
||||
|
@ -1,16 +1,33 @@
|
||||
import { defineConfig, toEscapedSelector as e, presetUno, presetIcons } from 'unocss'
|
||||
import transformerVariantGroup from '@unocss/transformer-variant-group'
|
||||
import { loadEnv } from 'vite'
|
||||
|
||||
const root = process.cwd()
|
||||
|
||||
const createPresetIcons = () => {
|
||||
const isBuild = !!process.argv[4]
|
||||
let env = {} as any
|
||||
if (!isBuild) {
|
||||
env = loadEnv(process.argv[3], root)
|
||||
} else {
|
||||
env = loadEnv(process.argv[4], root)
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
if (import.meta.env.VITE_USE_ONLINE_ICON === 'true') {
|
||||
if (env.VITE_USE_ONLINE_ICON === 'true') {
|
||||
return []
|
||||
} else {
|
||||
return [
|
||||
presetIcons({
|
||||
prefix: ''
|
||||
// 由于默认加载的是所有的图标,启动会非常慢,可以在这里去加载需要的图标,确保启动速度
|
||||
// collections: {
|
||||
// carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default),
|
||||
// mdi: () => import('@iconify-json/mdi/icons.json').then(i => i.default),
|
||||
// logos: () => import('@iconify-json/logos/icons.json').then(i => i.default),
|
||||
// }
|
||||
})
|
||||
]
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import progress from 'vite-plugin-progress'
|
||||
import EslintPlugin from 'vite-plugin-eslint'
|
||||
import { ViteEjsPlugin } from 'vite-plugin-ejs'
|
||||
import PurgeIcons from 'vite-plugin-purge-icons'
|
||||
import ServerUrlCopy from 'vite-plugin-url-copy'
|
||||
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
||||
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
|
||||
@ -38,6 +39,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
||||
}
|
||||
}),
|
||||
VueJsx(),
|
||||
ServerUrlCopy(),
|
||||
progress(),
|
||||
env.VITE_USE_ALL_ELEMENT_PLUS_STYLE === 'false'
|
||||
? createStyleImportPlugin({
|
||||
|
1
kinit-api/.gitignore
vendored
@ -10,7 +10,6 @@ logs/*
|
||||
!logs/.gitkeep
|
||||
temp/*
|
||||
!temp/.gitkeep
|
||||
!static/.gitkeep
|
||||
!alembic/versions/.gitkeep
|
||||
|
||||
# dotenv
|
||||
|
@ -146,22 +146,91 @@ git add .
|
||||
git commit -m "clear cached"
|
||||
```
|
||||
|
||||
执行数据库迁移命令(终端执行)
|
||||
## 新的数据迁移
|
||||
|
||||
```shell
|
||||
# 执行命令(生产环境):
|
||||
python main.py migrate
|
||||
- 新建模型:
|
||||
- 在你的app目录下新建一个models目录,`__init__.py`导入你需要迁移的models
|
||||
```python
|
||||
# app/.../your_app/models/__init__.py
|
||||
from .your_model import YourModel,YourModel2
|
||||
|
||||
# 执行命令(开发环境):
|
||||
python main.py migrate --env dev
|
||||
```
|
||||
```python
|
||||
# app/.../your_app/models/your_model.py
|
||||
from db.db_base import BaseModel
|
||||
|
||||
# 开发环境的原命令
|
||||
alembic --name dev revision --autogenerate -m 2.0
|
||||
alembic --name dev upgrade head
|
||||
```
|
||||
class YourModel(BaseModel):
|
||||
# 定义你的model
|
||||
...
|
||||
|
||||
class YourModel2(BaseModel):
|
||||
# 定义你的model
|
||||
...
|
||||
```
|
||||
- 根据模型配置你的alembic:
|
||||
```
|
||||
# alembic.ini
|
||||
[dev]
|
||||
...
|
||||
sqlalchemy.url = mysql+pymysql://your_username:password@ip:port/kinit
|
||||
...
|
||||
```
|
||||
```python
|
||||
# alembic/env.py
|
||||
# 导入项目中的基本映射类,与 需要迁移的 ORM 模型
|
||||
from apps.vadmin.auth.models import *
|
||||
...
|
||||
from apps.xxx.your_app.models import *
|
||||
```
|
||||
- 执行数据库迁移命令(终端执行执行脚本):
|
||||
```shell
|
||||
# 执行命令(生产环境):
|
||||
python main.py migrate
|
||||
|
||||
# 执行命令(开发环境):
|
||||
python main.py migrate --env dev
|
||||
|
||||
# 开发环境的原命令
|
||||
alembic --name dev revision --autogenerate -m 2.0
|
||||
alembic --name dev upgrade head
|
||||
```
|
||||
|
||||
生成迁移文件后,会在alembic迁移目录中的version目录中多个迁移文件
|
||||
|
||||
## 新的CRUD
|
||||
|
||||
- 新的模型文件已经建好(上一步迁移时必须)
|
||||
- 在 scripts/crud_generate/main.py 添加执行命令
|
||||
|
||||
```python
|
||||
# scripts/crud_generate/main.py
|
||||
if __name__ == '__main__':
|
||||
from apps.xxx.your_app.models import YourModel
|
||||
|
||||
crud = CrudGenerate(YourModel, "中文名", "en_name")
|
||||
# 只打印代码,不执行创建写入
|
||||
crud.generate_codes()
|
||||
# 创建并写入代码
|
||||
crud.main()
|
||||
```
|
||||
|
||||
- 生成后会自动创建crud, params,schema, views
|
||||
|
||||
## 新的路由配置
|
||||
|
||||
```python
|
||||
# application/urls.py
|
||||
|
||||
from apps.xxx.your_app.views import app as your_app
|
||||
|
||||
urlpatterns = [
|
||||
...,
|
||||
{"ApiRouter": your_app, "prefix": "/your_router", "tags": ["your_tag"]},
|
||||
]
|
||||
```
|
||||
|
||||
完成后在 http://127.0.0.1:9000/docs 验证生成的接口
|
||||
|
||||
## 查询数据
|
||||
|
||||
### 自定义的一些查询过滤
|
||||
|
@ -11,13 +11,13 @@ from fastapi.security import OAuth2PasswordBearer
|
||||
"""
|
||||
系统版本
|
||||
"""
|
||||
VERSION = "3.7.0"
|
||||
VERSION = "3.10.1"
|
||||
|
||||
"""安全警告: 不要在生产中打开调试运行!"""
|
||||
DEBUG = False
|
||||
|
||||
"""是否开启演示功能:取消所有POST,DELETE,PUT操作权限"""
|
||||
DEMO = False
|
||||
DEMO = True
|
||||
"""演示功能白名单"""
|
||||
DEMO_WHITE_LIST_PATH = [
|
||||
"/auth/login",
|
||||
@ -28,6 +28,10 @@ DEMO_WHITE_LIST_PATH = [
|
||||
"/vadmin/resource/images",
|
||||
"/vadmin/auth/user/export/query/list/to/excel"
|
||||
]
|
||||
"""演示功能黑名单(触发异常 status_code=403),黑名单优先级更高"""
|
||||
DEMO_BLACK_LIST_PATH = [
|
||||
"/auth/api/login"
|
||||
]
|
||||
|
||||
"""
|
||||
引入数据库配置
|
||||
|
@ -1,4 +1,4 @@
|
||||
from .user import UserOut, UserUpdate, User, UserIn, UserSimpleOut, ResetPwd, UserUpdateBaseInfo
|
||||
from .user import UserOut, UserUpdate, User, UserIn, UserSimpleOut, ResetPwd, UserUpdateBaseInfo, UserPasswordOut
|
||||
from .role import Role, RoleOut, RoleIn, RoleOptionsOut, RoleSimpleOut
|
||||
from .menu import Menu, MenuSimpleOut, RouterOut, Meta, MenuTreeListOut
|
||||
from .dept import Dept, DeptSimpleOut, DeptTreeListOut
|
||||
|
@ -74,6 +74,12 @@ class UserSimpleOut(User):
|
||||
last_ip: str | None = None
|
||||
|
||||
|
||||
class UserPasswordOut(UserSimpleOut):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
password: str
|
||||
|
||||
|
||||
class UserOut(UserSimpleOut):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
@ -27,10 +27,10 @@ class OpenAuth(AuthValidation):
|
||||
"""
|
||||
|
||||
async def __call__(
|
||||
self,
|
||||
request: Request,
|
||||
token: Annotated[str, Depends(settings.oauth2_scheme)],
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
self,
|
||||
request: Request,
|
||||
token: Annotated[str, Depends(settings.oauth2_scheme)],
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
):
|
||||
"""
|
||||
每次调用依赖此类的接口会执行该方法
|
||||
@ -38,8 +38,8 @@ class OpenAuth(AuthValidation):
|
||||
if not settings.OAUTH_ENABLE:
|
||||
return Auth(db=db)
|
||||
try:
|
||||
telephone = self.validate_token(request, token)
|
||||
user = await UserDal(db).get_data(telephone=telephone, v_return_none=True)
|
||||
telephone, password = self.validate_token(request, token)
|
||||
user = await UserDal(db).get_data(telephone=telephone, password=password, v_return_none=True)
|
||||
return await self.validate_user(request, user, db, is_all=True)
|
||||
except CustomException:
|
||||
return Auth(db=db)
|
||||
@ -53,18 +53,18 @@ class AllUserAuth(AuthValidation):
|
||||
"""
|
||||
|
||||
async def __call__(
|
||||
self,
|
||||
request: Request,
|
||||
token: str = Depends(settings.oauth2_scheme),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
self,
|
||||
request: Request,
|
||||
token: str = Depends(settings.oauth2_scheme),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
):
|
||||
"""
|
||||
每次调用依赖此类的接口会执行该方法
|
||||
"""
|
||||
if not settings.OAUTH_ENABLE:
|
||||
return Auth(db=db)
|
||||
telephone = self.validate_token(request, token)
|
||||
user = await UserDal(db).get_data(telephone=telephone, v_return_none=True)
|
||||
telephone, password = self.validate_token(request, token)
|
||||
user = await UserDal(db).get_data(telephone=telephone, password=password, v_return_none=True)
|
||||
return await self.validate_user(request, user, db, is_all=True)
|
||||
|
||||
|
||||
@ -83,23 +83,32 @@ class FullAdminAuth(AuthValidation):
|
||||
self.permissions = None
|
||||
|
||||
async def __call__(
|
||||
self,
|
||||
request: Request,
|
||||
token: str = Depends(settings.oauth2_scheme),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
self,
|
||||
request: Request,
|
||||
token: str = Depends(settings.oauth2_scheme),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
) -> Auth:
|
||||
"""
|
||||
每次调用依赖此类的接口会执行该方法
|
||||
"""
|
||||
if not settings.OAUTH_ENABLE:
|
||||
return Auth(db=db)
|
||||
telephone = self.validate_token(request, token)
|
||||
options = [joinedload(VadminUser.roles).subqueryload(VadminRole.menus), joinedload(VadminUser.depts)]
|
||||
user = await UserDal(db).get_data(telephone=telephone, v_return_none=True, v_options=options, is_staff=True)
|
||||
telephone, password = self.validate_token(request, token)
|
||||
options = [
|
||||
joinedload(VadminUser.roles).subqueryload(VadminRole.menus),
|
||||
joinedload(VadminUser.roles).subqueryload(VadminRole.depts),
|
||||
joinedload(VadminUser.depts)
|
||||
]
|
||||
user = await UserDal(db).get_data(
|
||||
telephone=telephone,
|
||||
password=password,
|
||||
v_return_none=True,
|
||||
v_options=options,
|
||||
is_staff=True
|
||||
)
|
||||
result = await self.validate_user(request, user, db, is_all=False)
|
||||
permissions = self.get_user_permissions(user)
|
||||
if permissions != {'*.*.*'} and self.permissions:
|
||||
if not (self.permissions & permissions):
|
||||
raise CustomException(msg="无权限操作", code=status.HTTP_403_FORBIDDEN)
|
||||
return result
|
||||
|
||||
|
@ -39,27 +39,27 @@ from .validation.auth import Auth
|
||||
from utils.wx.oauth import WXOAuth
|
||||
import jwt
|
||||
|
||||
|
||||
app = APIRouter()
|
||||
|
||||
|
||||
@app.post("/api/login", summary="API 手机号密码登录", description="Swagger API 文档登录认证")
|
||||
async def api_login_for_access_token(
|
||||
request: Request,
|
||||
data: OAuth2PasswordRequestForm = Depends(),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
request: Request,
|
||||
data: OAuth2PasswordRequestForm = Depends(),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
):
|
||||
user = await UserDal(db).get_data(telephone=data.username, v_return_none=True)
|
||||
error_code = status.HTTP_401_UNAUTHORIZED
|
||||
if not user:
|
||||
raise CustomException(status_code=401, code=401, msg="该手机号不存在")
|
||||
raise CustomException(status_code=error_code, code=error_code, msg="该手机号不存在")
|
||||
result = VadminUser.verify_password(data.password, user.password)
|
||||
if not result:
|
||||
raise CustomException(status_code=401, code=401, msg="手机号或密码错误")
|
||||
raise CustomException(status_code=error_code, code=error_code, msg="手机号或密码错误")
|
||||
if not user.is_active:
|
||||
raise CustomException(status_code=401, code=401, msg="此手机号已被冻结")
|
||||
raise CustomException(status_code=error_code, code=error_code, msg="此手机号已被冻结")
|
||||
elif not user.is_staff:
|
||||
raise CustomException(status_code=401, code=401, msg="此手机号无权限")
|
||||
access_token = LoginManage.create_token({"sub": user.telephone})
|
||||
raise CustomException(status_code=error_code, code=error_code, msg="此手机号无权限")
|
||||
access_token = LoginManage.create_token({"sub": user.telephone, "password": user.password})
|
||||
record = LoginForm(platform='2', method='0', telephone=data.username, password=data.password)
|
||||
resp = {"access_token": access_token, "token_type": "bearer"}
|
||||
await VadminLoginRecord.create_login_record(db, record, True, request, resp)
|
||||
@ -68,10 +68,10 @@ async def api_login_for_access_token(
|
||||
|
||||
@app.post("/login", summary="手机号密码登录", description="员工登录通道,限制最多输错次数,达到最大值后将is_active=False")
|
||||
async def login_for_access_token(
|
||||
request: Request,
|
||||
data: LoginForm,
|
||||
manage: LoginManage = Depends(),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
request: Request,
|
||||
data: LoginForm,
|
||||
manage: LoginManage = Depends(),
|
||||
db: AsyncSession = Depends(db_getter)
|
||||
):
|
||||
try:
|
||||
if data.method == "0":
|
||||
@ -84,9 +84,14 @@ async def login_for_access_token(
|
||||
if not result.status:
|
||||
raise ValueError(result.msg)
|
||||
|
||||
access_token = LoginManage.create_token({"sub": result.user.telephone, "is_refresh": False})
|
||||
access_token = LoginManage.create_token(
|
||||
{"sub": result.user.telephone, "is_refresh": False, "password": result.user.password}
|
||||
)
|
||||
expires = timedelta(minutes=settings.REFRESH_TOKEN_EXPIRE_MINUTES)
|
||||
refresh_token = LoginManage.create_token({"sub": result.user.telephone, "is_refresh": True}, expires=expires)
|
||||
refresh_token = LoginManage.create_token(
|
||||
payload={"sub": result.user.telephone, "is_refresh": True, "password": result.user.password},
|
||||
expires=expires
|
||||
)
|
||||
resp = {
|
||||
"access_token": access_token,
|
||||
"refresh_token": refresh_token,
|
||||
@ -103,10 +108,10 @@ async def login_for_access_token(
|
||||
|
||||
@app.post("/wx/login", summary="微信服务端一键登录", description="员工登录通道")
|
||||
async def wx_login_for_access_token(
|
||||
request: Request,
|
||||
data: WXLoginForm,
|
||||
db: AsyncSession = Depends(db_getter),
|
||||
rd: Redis = Depends(redis_getter)
|
||||
request: Request,
|
||||
data: WXLoginForm,
|
||||
db: AsyncSession = Depends(db_getter),
|
||||
rd: Redis = Depends(redis_getter)
|
||||
):
|
||||
try:
|
||||
if data.platform != "1" or data.method != "2":
|
||||
@ -129,9 +134,12 @@ async def wx_login_for_access_token(
|
||||
await UserDal(db).update_login_info(user, request.client.host)
|
||||
|
||||
# 登录成功创建 token
|
||||
access_token = LoginManage.create_token({"sub": user.telephone, "is_refresh": False})
|
||||
access_token = LoginManage.create_token({"sub": user.telephone, "is_refresh": False, "password": user.password})
|
||||
expires = timedelta(minutes=settings.REFRESH_TOKEN_EXPIRE_MINUTES)
|
||||
refresh_token = LoginManage.create_token({"sub": user.telephone, "is_refresh": True}, expires=expires)
|
||||
refresh_token = LoginManage.create_token(
|
||||
payload={"sub": user.telephone, "is_refresh": True, "password": user.password},
|
||||
expires=expires
|
||||
)
|
||||
resp = {
|
||||
"access_token": access_token,
|
||||
"refresh_token": refresh_token,
|
||||
@ -155,16 +163,20 @@ async def token_refresh(refresh: str = Body(..., title="刷新Token")):
|
||||
payload = jwt.decode(refresh, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
|
||||
telephone: str = payload.get("sub")
|
||||
is_refresh: bool = payload.get("is_refresh")
|
||||
if telephone is None or not is_refresh:
|
||||
password: str = payload.get("password")
|
||||
if not telephone or not is_refresh or not password:
|
||||
return ErrorResponse("未认证,请您重新登录", code=error_code, status=error_code)
|
||||
except jwt.exceptions.InvalidSignatureError:
|
||||
return ErrorResponse("无效认证,请您重新登录", code=error_code, status=error_code)
|
||||
except jwt.exceptions.ExpiredSignatureError:
|
||||
return ErrorResponse("登录已超时,请您重新登录", code=error_code, status=error_code)
|
||||
|
||||
access_token = LoginManage.create_token({"sub": telephone, "is_refresh": False})
|
||||
access_token = LoginManage.create_token({"sub": telephone, "is_refresh": False, "password": password})
|
||||
expires = timedelta(minutes=settings.REFRESH_TOKEN_EXPIRE_MINUTES)
|
||||
refresh_token = LoginManage.create_token({"sub": telephone, "is_refresh": True}, expires=expires)
|
||||
refresh_token = LoginManage.create_token(
|
||||
payload={"sub": telephone, "is_refresh": True, "password": password},
|
||||
expires=expires
|
||||
)
|
||||
resp = {
|
||||
"access_token": access_token,
|
||||
"refresh_token": refresh_token,
|
||||
|
@ -42,7 +42,7 @@ class AuthValidation:
|
||||
# status_code = 403 时,表示强制要求重新登录,因无系统权限,而进入到系统访问等问题导致
|
||||
|
||||
@classmethod
|
||||
def validate_token(cls, request: Request, token: str | None) -> str:
|
||||
def validate_token(cls, request: Request, token: str | None) -> tuple[str, bool]:
|
||||
"""
|
||||
验证用户 token
|
||||
"""
|
||||
@ -57,7 +57,8 @@ class AuthValidation:
|
||||
telephone: str = payload.get("sub")
|
||||
exp: int = payload.get("exp")
|
||||
is_refresh: bool = payload.get("is_refresh")
|
||||
if telephone is None or is_refresh:
|
||||
password: bool = payload.get("password")
|
||||
if not telephone or is_refresh or not password:
|
||||
raise CustomException(
|
||||
msg="未认证,请您重新登录",
|
||||
code=status.HTTP_403_FORBIDDEN,
|
||||
@ -79,8 +80,8 @@ class AuthValidation:
|
||||
status_code=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
except jwt.exceptions.ExpiredSignatureError:
|
||||
raise CustomException(msg="认证已过期,请您重新登录", code=cls.error_code, status_code=cls.error_code)
|
||||
return telephone
|
||||
raise CustomException(msg="认证已失效,请您重新登录", code=cls.error_code, status_code=cls.error_code)
|
||||
return telephone, password
|
||||
|
||||
@classmethod
|
||||
async def validate_user(cls, request: Request, user: VadminUser, db: AsyncSession, is_all: bool = True) -> Auth:
|
||||
|
@ -35,7 +35,7 @@ class WXLoginForm(BaseModel):
|
||||
|
||||
class LoginResult(BaseModel):
|
||||
status: bool | None = False
|
||||
user: schemas.UserOut | None = None
|
||||
user: schemas.UserPasswordOut | None = None
|
||||
msg: str | None = None
|
||||
|
||||
class Config:
|
||||
@ -87,6 +87,6 @@ class LoginValidation:
|
||||
await count.delete()
|
||||
self.result.msg = "OK"
|
||||
self.result.status = True
|
||||
self.result.user = schemas.UserSimpleOut.model_validate(user)
|
||||
self.result.user = schemas.UserPasswordOut.model_validate(user)
|
||||
await crud.UserDal(db).update_login_info(user, request.client.host)
|
||||
return self.result
|
||||
|
@ -246,7 +246,7 @@ async def put_menus(
|
||||
|
||||
|
||||
@app.get("/menus/{data_id}", summary="获取菜单信息")
|
||||
async def put_menus(
|
||||
async def get_menus(
|
||||
data_id: int,
|
||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.view", "auth.menu.update"]))
|
||||
):
|
||||
|
@ -32,3 +32,4 @@ class LoginParams(QueryParams):
|
||||
self.address = ("like", address)
|
||||
self.status = status
|
||||
self.platform = platform
|
||||
self.v_order = "desc"
|
||||
|
@ -170,12 +170,12 @@ async def get_setting_base_config(db: AsyncSession = Depends(db_getter)):
|
||||
|
||||
|
||||
@app.get("/settings/privacy", summary="获取隐私协议")
|
||||
async def get_settings_privacy(auth: Auth = Depends(FullAdminAuth())):
|
||||
async def get_settings_privacy(auth: Auth = Depends(OpenAuth())):
|
||||
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_privacy")).config_value)
|
||||
|
||||
|
||||
@app.get("/settings/agreement", summary="获取用户协议")
|
||||
async def get_settings_agreement(auth: Auth = Depends(FullAdminAuth())):
|
||||
async def get_settings_agreement(auth: Auth = Depends(OpenAuth())):
|
||||
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_agreement")).config_value)
|
||||
|
||||
|
||||
|
@ -123,6 +123,14 @@ async def get_team():
|
||||
@app.get("/shortcuts", summary="获取快捷操作")
|
||||
async def get_shortcuts():
|
||||
data = [
|
||||
{
|
||||
"name": "Gitee 项目仓库",
|
||||
"link": "https://gitee.com/ktianc/kinit"
|
||||
},
|
||||
{
|
||||
"name": "GitHub 项目仓库",
|
||||
"link": "https://github.com/vvandk/kinit"
|
||||
},
|
||||
{
|
||||
"name": "前端文档",
|
||||
"link": "https://element-plus-admin-doc.cn/"
|
||||
@ -136,8 +144,8 @@ async def get_shortcuts():
|
||||
"link": "http://kinit.ktianc.top/api/redoc"
|
||||
},
|
||||
{
|
||||
"name": "Windi CSS 文档",
|
||||
"link": "https://cn.windicss.org/guide/"
|
||||
"name": "UnoCSS 中文文档",
|
||||
"link": "https://unocss.nodejs.cn/guide/"
|
||||
},
|
||||
{
|
||||
"name": "Iconify 文档",
|
||||
|
@ -65,9 +65,9 @@ def register_exception(app: FastAPI):
|
||||
# 打印栈信息,方便追踪排查异常
|
||||
logger.exception(exc)
|
||||
return JSONResponse(
|
||||
status_code=200,
|
||||
status_code=exc.status_code,
|
||||
content={
|
||||
"code": status.HTTP_400_BAD_REQUEST,
|
||||
"code": exc.status_code,
|
||||
"message": exc.detail,
|
||||
}
|
||||
)
|
||||
|
@ -17,11 +17,12 @@ from core.logger import logger
|
||||
from fastapi import FastAPI
|
||||
from fastapi.routing import APIRoute
|
||||
from user_agents import parse
|
||||
from application.settings import OPERATION_RECORD_METHOD, MONGO_DB_ENABLE, IGNORE_OPERATION_FUNCTION,\
|
||||
DEMO_WHITE_LIST_PATH, DEMO
|
||||
from application.settings import OPERATION_RECORD_METHOD, MONGO_DB_ENABLE, IGNORE_OPERATION_FUNCTION, \
|
||||
DEMO_WHITE_LIST_PATH, DEMO, DEMO_BLACK_LIST_PATH
|
||||
from utils.response import ErrorResponse
|
||||
from apps.vadmin.record.crud import OperationRecordDal
|
||||
from core.database import mongo_getter
|
||||
from utils import status
|
||||
|
||||
|
||||
def write_request_log(request: Request, response: Response):
|
||||
@ -129,8 +130,15 @@ def register_demo_env_middleware(app: FastAPI):
|
||||
path = request.scope.get("path")
|
||||
if request.method != "GET":
|
||||
print("路由:", path, request.method)
|
||||
if DEMO and request.method != "GET" and path not in DEMO_WHITE_LIST_PATH:
|
||||
return ErrorResponse(msg="演示环境,禁止操作")
|
||||
if DEMO and request.method != "GET":
|
||||
if path in DEMO_BLACK_LIST_PATH:
|
||||
return ErrorResponse(
|
||||
status=status.HTTP_403_FORBIDDEN,
|
||||
code=status.HTTP_403_FORBIDDEN,
|
||||
msg="演示环境,禁止操作"
|
||||
)
|
||||
elif path not in DEMO_WHITE_LIST_PATH:
|
||||
return ErrorResponse(msg="演示环境,禁止操作")
|
||||
return await call_next(request)
|
||||
|
||||
|
||||
|
74
kinit-api/utils/compute.py
Normal file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @version : 1.0
|
||||
# @Creaet Time : 2022/5/12 17:09
|
||||
# @File : compute.py
|
||||
# @IDE : PyCharm
|
||||
# @desc : 精准计算
|
||||
from decimal import Decimal
|
||||
from typing import Union
|
||||
|
||||
|
||||
class Compute:
|
||||
|
||||
@staticmethod
|
||||
def add(precision: int, *args: Union[float, Decimal]) -> float:
|
||||
"""
|
||||
相加
|
||||
:param precision: 精度
|
||||
"""
|
||||
result = 0
|
||||
for i in args:
|
||||
if i is None:
|
||||
i = 0
|
||||
result += Decimal(str(i))
|
||||
if precision == -1:
|
||||
return float(result)
|
||||
return round(float(result), precision)
|
||||
|
||||
@staticmethod
|
||||
def subtract(precision: int, *args: Union[float, Decimal]) -> float:
|
||||
"""
|
||||
相减
|
||||
:param precision: 精度
|
||||
"""
|
||||
if args[0] is None:
|
||||
start = 0
|
||||
else:
|
||||
start = args[0]
|
||||
result = Decimal(str(start))
|
||||
for i in args[1:]:
|
||||
if i is None:
|
||||
i = 0
|
||||
result -= Decimal(str(i))
|
||||
if precision == -1:
|
||||
return float(result)
|
||||
return round(float(result), precision)
|
||||
|
||||
@staticmethod
|
||||
def divide(precision: int, *args: Union[float, Decimal]) -> float:
|
||||
"""
|
||||
除法
|
||||
:param precision: 精度
|
||||
"""
|
||||
result = Decimal(str(args[0]))
|
||||
for i in args[1:]:
|
||||
result = result / Decimal(str(i))
|
||||
if precision == -1:
|
||||
return float(result)
|
||||
return round(float(result), precision)
|
||||
|
||||
@staticmethod
|
||||
def multiply(precision: int, *args: Union[float, Decimal]) -> float:
|
||||
"""
|
||||
乘法
|
||||
:param precision: 精度
|
||||
"""
|
||||
result = Decimal(str(1))
|
||||
for i in args:
|
||||
if i is None:
|
||||
i = 1
|
||||
result = result * Decimal(str(i))
|
||||
if precision == -1:
|
||||
return float(result)
|
||||
return round(float(result), precision)
|
@ -58,7 +58,7 @@ class AliyunOSS(FileBase):
|
||||
# 验证图片类型
|
||||
await self.validate_file(file, max_size, self.IMAGE_ACCEPT)
|
||||
# 生成文件路径
|
||||
path = self.generate_static_file_path(path, file.filename)
|
||||
path = self.generate_relative_path(path, file.filename)
|
||||
file_data = await file.read()
|
||||
return await self.__upload_file_to_oss(path, file_data)
|
||||
|
||||
@ -74,7 +74,7 @@ class AliyunOSS(FileBase):
|
||||
# 验证图片类型
|
||||
await self.validate_file(file, max_size, self.VIDEO_ACCEPT)
|
||||
# 生成文件路径
|
||||
path = self.generate_static_file_path(path, file.filename)
|
||||
path = self.generate_relative_path(path, file.filename)
|
||||
file_data = await file.read()
|
||||
return await self.__upload_file_to_oss(path, file_data)
|
||||
|
||||
@ -86,7 +86,7 @@ class AliyunOSS(FileBase):
|
||||
:param file: 文件对象
|
||||
:return: 上传后的文件oss链接
|
||||
"""
|
||||
path = self.generate_static_file_path(path, file.filename)
|
||||
path = self.generate_relative_path(path, file.filename)
|
||||
file_data = await file.read()
|
||||
return await self.__upload_file_to_oss(path, file_data)
|
||||
|
||||
|
@ -44,15 +44,14 @@ class FileBase:
|
||||
return str(int((datetime.datetime.now().replace(hour=0, minute=0, second=0)).timestamp()))
|
||||
|
||||
@classmethod
|
||||
def generate_static_file_path(cls, path: str, filename: str = None, suffix: str = None) -> str:
|
||||
def generate_relative_path(cls, path: str, filename: str = None, suffix: str = None) -> str:
|
||||
"""
|
||||
生成 static 静态文件路径,生成规则:自定义目录/当天日期时间戳/随机文件名称
|
||||
生成相对路径,生成规则:自定义目录/当天日期时间戳/随机文件名称
|
||||
1. filename 参数或者 suffix 参数必须填写一个
|
||||
2. filename 参数和 suffix 参数都存在则优先取 suffix 参数为后缀
|
||||
:param path: static 指定目录类别
|
||||
:param filename: 文件名称,只用户获取后缀,不做真实文件名称,避免文件重复问题
|
||||
:param suffix: 文件后缀
|
||||
:return:
|
||||
"""
|
||||
if not filename and not suffix:
|
||||
raise ValueError("filename 参数或者 suffix 参数必须填写一个")
|
||||
@ -64,7 +63,20 @@ class FileBase:
|
||||
if path[-1] == "/":
|
||||
path = path[:-1]
|
||||
today = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d")
|
||||
return f"{STATIC_ROOT}/{path}/{today}/{cls.get_random_filename(suffix)}"
|
||||
return f"{path}/{today}/{cls.get_random_filename(suffix)}"
|
||||
|
||||
@classmethod
|
||||
def generate_static_file_path(cls, path: str, filename: str = None, suffix: str = None) -> str:
|
||||
"""
|
||||
生成 static 静态文件路径,生成规则:自定义目录/当天日期时间戳/随机文件名称
|
||||
1. filename 参数或者 suffix 参数必须填写一个
|
||||
2. filename 参数和 suffix 参数都存在则优先取 suffix 参数为后缀
|
||||
:param path: static 指定目录类别
|
||||
:param filename: 文件名称,只用户获取后缀,不做真实文件名称,避免文件重复问题
|
||||
:param suffix: 文件后缀
|
||||
:return:
|
||||
"""
|
||||
return f"{STATIC_ROOT}/{cls.generate_relative_path(path, filename, suffix)}"
|
||||
|
||||
@classmethod
|
||||
def generate_temp_file_path(cls, filename: str = None, suffix: str = None) -> str:
|
||||
|
@ -63,19 +63,21 @@ class FileManage(FileBase):
|
||||
async def async_save_local(self) -> dict:
|
||||
"""
|
||||
保存文件到本地
|
||||
:return:
|
||||
:return: 示例:
|
||||
{
|
||||
'local_path': 'D:\\project\\kinit_dev\\kinit-api\\static\\system\\20240301\\1709303205HuYB3mrC.png',
|
||||
'remote_path': '/media/system/20240301/1709303205HuYB3mrC.png'
|
||||
}
|
||||
"""
|
||||
path = self.path
|
||||
path = AsyncPath(self.path)
|
||||
if sys.platform == "win32":
|
||||
path = self.path.replace("/", "\\")
|
||||
save_path = AsyncPath(STATIC_ROOT) / path
|
||||
if not await save_path.parent.exists():
|
||||
await save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
await save_path.write_bytes(await self.file.read())
|
||||
remote_path = path.replace(STATIC_ROOT, '').replace("\\", '/')
|
||||
path = AsyncPath(self.path.replace("/", "\\"))
|
||||
if not await path.parent.exists():
|
||||
await path.parent.mkdir(parents=True, exist_ok=True)
|
||||
await path.write_bytes(await self.file.read())
|
||||
return {
|
||||
"local_path": path,
|
||||
"remote_path": f"{STATIC_URL}/{remote_path}"
|
||||
"local_path": str(path),
|
||||
"remote_path": STATIC_URL + str(path).replace(STATIC_ROOT, '').replace("\\", '/')
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
@ -8,8 +8,7 @@ class SuccessResponse(Response):
|
||||
"""
|
||||
成功响应
|
||||
"""
|
||||
def __init__(self, data=None, msg="success", code=http.HTTP_SUCCESS, status=http_status.HTTP_200_OK
|
||||
, **kwargs):
|
||||
def __init__(self, data=None, msg="success", code=http.HTTP_SUCCESS, status=http_status.HTTP_200_OK, **kwargs):
|
||||
self.data = {
|
||||
"code": code,
|
||||
"message": msg,
|
||||
|
3
kinit-uni/.gitignore
vendored
@ -11,4 +11,7 @@
|
||||
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
kinit-uni.code-workspace
|
||||
|
||||
/unpackage/*
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"editor.formatOnSave": true,
|
||||
"prettier.configPath": "./prettier.config.js",
|
||||
"files.autoSave": "off",
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"vue-html",
|
||||
"vue"
|
||||
],
|
||||
"eslint.enable": true,
|
||||
"eslint.run": "onType",
|
||||
"editor.tabSize": 2,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,11 @@ uni.$u.setConfig({
|
||||
size: 33,
|
||||
labelSize: 30
|
||||
},
|
||||
checkbox: {
|
||||
size: 33,
|
||||
labelSize: 30,
|
||||
iconSize: 20
|
||||
},
|
||||
button: {
|
||||
loadingSize: 28
|
||||
},
|
||||
|
@ -30,23 +30,42 @@
|
||||
<!-- <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button> -->
|
||||
<u-button type="primary" text="登录" shape="circle" @click="handleLogin"></u-button>
|
||||
</view>
|
||||
|
||||
<view class="xieyi flex justify-start">
|
||||
<zb-tooltip :visible.sync="tooltipVisible" content="请阅读并同意" placement="top" ref="tooltip" >
|
||||
<view>
|
||||
<!-- <text class="text-grey1">等内容</text> -->
|
||||
<u-checkbox-group v-model="isAgrement" shape="circle" @change="checkboxChange">
|
||||
<u-checkbox></u-checkbox>
|
||||
</u-checkbox-group>
|
||||
</view>
|
||||
</zb-tooltip>
|
||||
<view>
|
||||
<text class="text-grey1">允许我们在必要场景下,合理使用您的个人信息,且阅读并同意</text>
|
||||
<text class="text-blue" @click="handleUserAgrement">《用户协议》、</text>
|
||||
<text class="text-blue" @click="handlePrivacy">《隐私协议》、</text>
|
||||
<text class="text-grey1">等内容</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="xieyi text-center">
|
||||
<text class="text-grey1">登录即代表同意</text>
|
||||
<text class="text-blue" @click="handleUserAgrement">《用户协议》</text>
|
||||
<text class="text-blue" @click="handlePrivacy">《隐私协议》</text>
|
||||
</view>
|
||||
|
||||
<view class="footer text-center">
|
||||
<!-- <view class="footer text-center">
|
||||
<u-button
|
||||
v-if="isAgrement"
|
||||
type="primary"
|
||||
text="微信一键登录"
|
||||
shape="circle"
|
||||
open-type="getPhoneNumber"
|
||||
@getphonenumber="wxLogin"
|
||||
></u-button>
|
||||
</view>
|
||||
<u-button
|
||||
v-else
|
||||
type="primary"
|
||||
text="微信一键登录"
|
||||
shape="circle"
|
||||
@click="wxLogin"
|
||||
></u-button>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -60,7 +79,9 @@ export default {
|
||||
loginForm: {
|
||||
telephone: '15020221010',
|
||||
password: 'kinit2022'
|
||||
}
|
||||
},
|
||||
isAgrement: false,
|
||||
tooltipVisible: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -96,14 +117,18 @@ export default {
|
||||
},
|
||||
// 登录方法
|
||||
async handleLogin() {
|
||||
if (this.loginForm.telephone === '') {
|
||||
this.$modal.msgError('请输入您的手机号')
|
||||
} else if (this.loginForm.password === '') {
|
||||
this.$modal.msgError('请输入您的密码')
|
||||
} else {
|
||||
this.$modal.loading('正在登录中...')
|
||||
this.pwdLogin()
|
||||
}
|
||||
if (this.isAgrement) {
|
||||
if (this.loginForm.telephone === '') {
|
||||
this.$modal.msgError('请输入您的手机号')
|
||||
} else if (this.loginForm.password === '') {
|
||||
this.$modal.msgError('请输入您的密码')
|
||||
} else {
|
||||
this.$modal.loading('正在登录中...')
|
||||
this.pwdLogin()
|
||||
}
|
||||
} else {
|
||||
this.tooltipVisible = true
|
||||
}
|
||||
},
|
||||
// 密码登录
|
||||
async pwdLogin() {
|
||||
@ -122,10 +147,23 @@ export default {
|
||||
},
|
||||
// 微信一键登录
|
||||
wxLogin(detail) {
|
||||
this.onGetPhoneNumber(detail).then((res) => {
|
||||
this.loginSuccess()
|
||||
})
|
||||
}
|
||||
if (this.isAgrement) {
|
||||
this.onGetPhoneNumber(detail).then((res) => {
|
||||
this.loginSuccess()
|
||||
})
|
||||
} else {
|
||||
this.tooltipVisible = true
|
||||
}
|
||||
},
|
||||
// 用户协议事件监听
|
||||
checkboxChange() {
|
||||
this.isAgrement = !this.isAgrement
|
||||
this.tooltipClose()
|
||||
},
|
||||
// 关闭提示
|
||||
tooltipClose() {
|
||||
this.tooltipVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -156,7 +194,7 @@ page {
|
||||
}
|
||||
|
||||
.login-form-content {
|
||||
text-align: center;
|
||||
// text-align: center;
|
||||
margin: 20px auto;
|
||||
margin-top: 15%;
|
||||
width: 80%;
|
||||
|
24
kinit-uni/uni_modules/zb-tooltip/changelog.md
Normal file
@ -0,0 +1,24 @@
|
||||
## 1.0.11(2023-01-29)
|
||||
优化点击,加入点击自己再次点击也会关闭
|
||||
## 1.0.10(2023-01-17)
|
||||
优化
|
||||
## 1.0.9(2023-01-17)
|
||||
增加注释
|
||||
## 1.0.8(2022-08-18)
|
||||
优化细节
|
||||
## 1.0.67(2022-05-09)
|
||||
修复安卓报错
|
||||
## 1.0.6(2022-05-07)
|
||||
修改默认展示
|
||||
## 1.0.5(2022-04-28)
|
||||
进行优化
|
||||
## 1.0.4(2022-04-27)
|
||||
进行优化
|
||||
## 1.0.3(2022-04-25)
|
||||
去掉多余得注释
|
||||
## 1.0.2(2022-04-25)
|
||||
增加自定义主题颜色
|
||||
## 1.0.1(2022-04-25)
|
||||
进行优化显示
|
||||
## 1.0.0(2022-04-24)
|
||||
初始化
|
@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<view class="zb-tooltip" :style="{
|
||||
'--theme-bg-color':color
|
||||
}">
|
||||
<view class="zb_tooltip_content" @click.stop="handleClick">
|
||||
<slot></slot>
|
||||
<view class="zb_tooltip__popper"
|
||||
@click.stop="()=>{}"
|
||||
:style="[style,{
|
||||
visibility:isShow?'visible':'hidden',
|
||||
color:color==='white'?'':'#fff',
|
||||
boxShadow: color==='white'?'0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d':''
|
||||
}]" >
|
||||
<slot name="content">{{content}}</slot>
|
||||
<view class="zb_popper__icon" :style="[arrowStyle]" :class="[{
|
||||
'zb_popper__up':placement.indexOf('bottom')===0,
|
||||
'zb_popper__arrow':placement.indexOf('top')===0,
|
||||
'zb_popper__right':placement.indexOf('right')===0,
|
||||
'zb_popper__left':placement.indexOf('left')===0,
|
||||
}]">
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
visible:Boolean,
|
||||
color:{
|
||||
type:String,
|
||||
default:'#303133',
|
||||
},
|
||||
placement:{
|
||||
type:String,
|
||||
default:'top',
|
||||
},
|
||||
content:{
|
||||
type:String,
|
||||
default:''
|
||||
},
|
||||
show:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isShow :this.visible,
|
||||
title: 'Hello',
|
||||
arrowLeft:0,
|
||||
query:null,
|
||||
style:{
|
||||
|
||||
},
|
||||
arrowStyle:{}
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
watch:{
|
||||
isShow:{
|
||||
handler(val){
|
||||
this.$emit('update:visible', val)
|
||||
},
|
||||
immediate:true,
|
||||
},
|
||||
visible:{
|
||||
handler(val){
|
||||
if(val){
|
||||
this.$nextTick(()=>{
|
||||
this.getPosition()
|
||||
})
|
||||
}
|
||||
this.isShow = val
|
||||
},
|
||||
immediate:true,
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
// #ifdef H5
|
||||
window.addEventListener('click',()=>{
|
||||
this.isShow = false
|
||||
})
|
||||
// #endif
|
||||
this.getPosition()
|
||||
},
|
||||
methods: {
|
||||
close(){
|
||||
this.isShow = false
|
||||
},
|
||||
fixedWrap(){
|
||||
this.isShow = false
|
||||
},
|
||||
async handleClick(){
|
||||
if(this.isShow){
|
||||
return this.isShow = false
|
||||
}
|
||||
await this.getPosition()
|
||||
this.isShow = true
|
||||
},
|
||||
getPosition(){
|
||||
return new Promise((resolve) => {
|
||||
uni.createSelectorQuery().in(this).selectAll('.zb_tooltip_content,.zb_tooltip__popper').boundingClientRect(async (data)=>{
|
||||
let {left,bottom,right,top,width,height} = data[0]
|
||||
let obj1 = data[1]
|
||||
let objStyle = {}
|
||||
let objStyle1 = {}
|
||||
switch(this.placement){
|
||||
case 'top':
|
||||
if(obj1.width > width){
|
||||
objStyle.left = `-${(obj1.width - width)/2}px`
|
||||
}else{
|
||||
objStyle.left = `${Math.abs(obj1.width - width)/2}px`
|
||||
}
|
||||
|
||||
objStyle.bottom =`${height+8}px`
|
||||
objStyle1.left = (obj1.width/2-6)+'px'
|
||||
break;
|
||||
case 'top-start':
|
||||
objStyle.left = `0px`
|
||||
objStyle.bottom =`${height+8}px`
|
||||
break;
|
||||
case 'top-end':
|
||||
objStyle.right = `0px`
|
||||
objStyle.bottom =`${height+8}px`
|
||||
objStyle1.right=`8px`
|
||||
break;
|
||||
case 'bottom':
|
||||
if(obj1.width>width){
|
||||
objStyle.left = `-${(obj1.width - width)/2}px`
|
||||
}else{
|
||||
objStyle.left = `${Math.abs(obj1.width - width)/2}px`
|
||||
}
|
||||
objStyle.top =`${height+8}px`
|
||||
objStyle1.left = (obj1.width/2-6)+'px'
|
||||
break;
|
||||
case 'bottom-start':
|
||||
objStyle.left = `0px`
|
||||
objStyle.top =`${height+8}px`
|
||||
objStyle1.left = `8px`
|
||||
break;
|
||||
|
||||
case 'bottom-end':
|
||||
objStyle.right = `0px`
|
||||
objStyle.top =`${height+8}px`
|
||||
objStyle1.right = `8px`
|
||||
break;
|
||||
|
||||
case 'right':
|
||||
objStyle.left = `${width+8}px`
|
||||
if(obj1.height>height){
|
||||
objStyle.top =`-${(obj1.height - height)/2}px`
|
||||
}else{
|
||||
objStyle.top =`${Math.abs((obj1.height - height)/2)}px`
|
||||
}
|
||||
|
||||
objStyle1.top = `${obj1.height/2-6}px`
|
||||
break;
|
||||
case 'right-start':
|
||||
objStyle.left = `${width+8}px`
|
||||
objStyle.top =`0px`
|
||||
objStyle1.top = `8px`
|
||||
break;
|
||||
|
||||
case 'right-end':
|
||||
objStyle.left = `${width+8}px`
|
||||
objStyle.bottom =`0px`
|
||||
objStyle1.bottom = `8px`
|
||||
break;
|
||||
|
||||
case 'left':
|
||||
objStyle.right = `${width+8}px`
|
||||
|
||||
if(obj1.height>height){
|
||||
objStyle.top =`-${(obj1.height - height)/2}px`
|
||||
}else{
|
||||
objStyle.top =`${Math.abs((obj1.height - height)/2)}px`
|
||||
}
|
||||
|
||||
objStyle1.top = `${obj1.height/2-6}px`
|
||||
break;
|
||||
|
||||
case 'left-start':
|
||||
objStyle.right = `${width+8}px`
|
||||
objStyle.top =`0px`
|
||||
objStyle1.top = `8px`
|
||||
break;
|
||||
|
||||
case 'left-end':
|
||||
objStyle.right = `${width+8}px`
|
||||
objStyle.bottom =`0px`
|
||||
objStyle1.bottom = `8px`
|
||||
break;
|
||||
}
|
||||
this.style = objStyle
|
||||
// 三角形箭头
|
||||
this.arrowStyle = objStyle1
|
||||
resolve()
|
||||
}).exec()
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$theme-bg-color: var(--theme-bg-color);
|
||||
|
||||
.zb-tooltip{
|
||||
position: relative;
|
||||
|
||||
}
|
||||
.zb_tooltip_content{
|
||||
height: 100%;
|
||||
/* float: left; */
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
// display: flex;
|
||||
// flex-direction: row;
|
||||
// align-items: center;
|
||||
/* overflow: hidden; */
|
||||
}
|
||||
.zb_tooltip__popper{
|
||||
/* transform-origin: center top; */
|
||||
background: $theme-bg-color;
|
||||
|
||||
visibility: hidden;
|
||||
// color:'#fff';
|
||||
position: absolute;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
padding: 10px;
|
||||
min-width: 10px;
|
||||
word-wrap: break-word;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
z-index:9;
|
||||
}
|
||||
.zb_popper__icon{
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index:9;
|
||||
position: absolute;
|
||||
}
|
||||
.zb_popper__arrow{
|
||||
bottom: -5px;
|
||||
/* transform-origin: center top; */
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid $theme-bg-color;
|
||||
|
||||
}
|
||||
.zb_popper__right{
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-right: 6px solid $theme-bg-color;
|
||||
left:-5px;
|
||||
}
|
||||
|
||||
.zb_popper__left{
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-left: 6px solid $theme-bg-color;
|
||||
right:-5px;
|
||||
}
|
||||
|
||||
.zb_popper__up{
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid $theme-bg-color;
|
||||
top:-5px;
|
||||
}
|
||||
.fixed{
|
||||
position: absolute;width: 100vw;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
pointer-events: auto;
|
||||
background: red;
|
||||
z-index:-1;
|
||||
}
|
||||
</style>
|
83
kinit-uni/uni_modules/zb-tooltip/package.json
Normal file
@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "zb-tooltip",
|
||||
"displayName": "zb-tooltip (文字提示气泡框)",
|
||||
"version": "1.0.11",
|
||||
"description": "简单的文字提示气泡框,可以自定义皮肤颜色",
|
||||
"keywords": [
|
||||
"tooltip",
|
||||
"tip",
|
||||
"文字提示",
|
||||
"气泡框",
|
||||
"自定义皮肤颜色、Popover"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "y",
|
||||
"联盟": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
kinit-uni/uni_modules/zb-tooltip/readme.md
Normal file
@ -0,0 +1,30 @@
|
||||
## 介绍
|
||||
基于uni-app开发的一个普通的提示组件,功能点击提示
|
||||
|
||||
|
||||
## 友情链接
|
||||
#### vue-admin-perfect —— [企业级、通用型中后台前端解决方案 预览地址](http://182.61.5.190:8889/)
|
||||
#### vue-admin-perfect —— [企业级、通用型中后台前端解决方案(基于vue3.0+TS+Element-Plus 最新版,同时支持电脑,手机,平板)](https://github.com/zouzhibin/vue-admin-perfect)
|
||||
|
||||
|
||||
## Tooltip 属性
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
| ------ | ------ | ------ | ------ | ------ |
|
||||
| visible | 是否显示 tooltip,支持 .sync 修饰符 | Boolean |visible.sync | false |
|
||||
| content | 显示的内容,也可以通过 slot#content | String |-- | ' ' |
|
||||
| color | 自定义主题颜色| String |'#303133' | '#303133' |
|
||||
| placement | Tooltip 的出现位置 | String |top/top-start/top-end/bottom/bottom-start/bottom-end/left/left-start/left-end/right/right-start/right-end | top |
|
||||
|
||||
|
||||
## Slot 插槽
|
||||
| 参数 | 说明 |
|
||||
| ------ | ------ |
|
||||
| content | 显示提示框得内容 |
|
||||
|
||||
|
||||
```
|
||||
因为uniapp 中小程序中没有window对象,需手动调用 关闭
|
||||
第一种办法关闭:this.$refs.tooltip.close()
|
||||
第二种办法关闭:visible.sync = false
|
||||
|
||||
```
|
5
kinit-uni/unpackage/dist/build/h5/index.html
vendored
@ -1,5 +0,0 @@
|
||||
<!DOCTYPE html><html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><title>Kinit</title><link rel="shortcut icon" type=image/x-icon href=https://api.kinit.ktianc.top/media/system/favicon.ico><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=./static/index.b0707a6a.css></head><body><noscript><strong>本站点必须要开启JavaScript才能运行.</strong></noscript><div id=app></div><script src=./static/js/chunk-vendors.9910a52b.js></script><script src=./static/js/index.a38713ec.js></script></body></html>
|
BIN
kinit-uni/unpackage/dist/build/h5/static/favicon.ico
vendored
Before Width: | Height: | Size: 17 KiB |
@ -1,539 +0,0 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
cursor: pointer;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: -1px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
padding: 30px 100px;
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
color: #333;
|
||||
text-align: left;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
font-size: 160px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
width: 100% !important;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
list-style: none !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 42px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentColor;
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #404040;
|
||||
margin: 1.6em 0 0.6em 0;
|
||||
font-weight: 500;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
margin: 16px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown>p,
|
||||
.markdown>blockquote,
|
||||
.markdown>.highlight,
|
||||
.markdown>ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul>li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown>ul li,
|
||||
.markdown blockquote ul>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown>ul li p,
|
||||
.markdown>ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol>li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown>ol li,
|
||||
.markdown blockquote ol>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
border: 1px solid #e9e9e9;
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table th,
|
||||
.markdown>table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
opacity: 1;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown>br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
@ -1,283 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 3803079 */
|
||||
src: url('/static/font/iconfont.woff2?t=1670058157651') format('woff2'),
|
||||
url('/static/font/iconfont.woff?t=1670058157651') format('woff'),
|
||||
url('/static/font/iconfont.ttf?t=1670058157651') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-chazhaoyonghu:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.icon-users:before {
|
||||
content: "\e651";
|
||||
}
|
||||
|
||||
.icon-caidan:before {
|
||||
content: "\e605";
|
||||
}
|
||||
|
||||
.icon-rizhi:before {
|
||||
content: "\e660";
|
||||
}
|
||||
|
||||
.icon-zidian:before {
|
||||
content: "\e679";
|
||||
}
|
||||
|
||||
.icon-changguizidian:before {
|
||||
content: "\e694";
|
||||
}
|
||||
|
||||
.icon-user2:before {
|
||||
content: "\e686";
|
||||
}
|
||||
|
||||
.icon-usertie:before {
|
||||
content: "\e65b";
|
||||
}
|
||||
|
||||
.icon-caidan1:before {
|
||||
content: "\e62c";
|
||||
}
|
||||
|
||||
.icon-caidan2:before {
|
||||
content: "\e61e";
|
||||
}
|
||||
|
||||
.icon-dictionary:before {
|
||||
content: "\e606";
|
||||
}
|
||||
|
||||
.icon-shujuzidian:before {
|
||||
content: "\e666";
|
||||
}
|
||||
|
||||
.icon-caidan3:before {
|
||||
content: "\eaf1";
|
||||
}
|
||||
|
||||
.icon-rizhi1:before {
|
||||
content: "\e627";
|
||||
}
|
||||
|
||||
.icon-rizhi2:before {
|
||||
content: "\e647";
|
||||
}
|
||||
|
||||
.icon-caidan4:before {
|
||||
content: "\e668";
|
||||
}
|
||||
|
||||
.icon-caidan5:before {
|
||||
content: "\e61b";
|
||||
}
|
||||
|
||||
.icon-24gl-portraitMalePlus4:before {
|
||||
content: "\eb25";
|
||||
}
|
||||
|
||||
.icon-user1:before {
|
||||
content: "\e755";
|
||||
}
|
||||
|
||||
.icon-user-tag:before {
|
||||
content: "\e631";
|
||||
}
|
||||
|
||||
.icon-rizhi3:before {
|
||||
content: "\e603";
|
||||
}
|
||||
|
||||
.icon-zidianguanli:before {
|
||||
content: "\e669";
|
||||
}
|
||||
|
||||
.icon-caidan6:before {
|
||||
content: "\e624";
|
||||
}
|
||||
|
||||
.icon-user3:before {
|
||||
content: "\e616";
|
||||
}
|
||||
|
||||
.icon-user-o:before {
|
||||
content: "\e664";
|
||||
}
|
||||
|
||||
.icon-rizhi4:before {
|
||||
content: "\e66a";
|
||||
}
|
||||
|
||||
.icon-user4:before {
|
||||
content: "\e8fa";
|
||||
}
|
||||
|
||||
.icon-caidan7:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.icon-user5:before {
|
||||
content: "\e62b";
|
||||
}
|
||||
|
||||
.icon-zidianmokuai2:before {
|
||||
content: "\e621";
|
||||
}
|
||||
|
||||
.icon-right:before {
|
||||
content: "\e6a3";
|
||||
}
|
||||
|
||||
.icon-right1:before {
|
||||
content: "\e7eb";
|
||||
}
|
||||
|
||||
.icon-arrow-right:before {
|
||||
content: "\e665";
|
||||
}
|
||||
|
||||
.icon-arrow-right-bold:before {
|
||||
content: "\e687";
|
||||
}
|
||||
|
||||
.icon-dianhua:before {
|
||||
content: "\e609";
|
||||
}
|
||||
|
||||
.icon-wenti1-copy:before {
|
||||
content: "\eca9";
|
||||
}
|
||||
|
||||
.icon-wenti1-copy1:before {
|
||||
content: "\eca3";
|
||||
}
|
||||
|
||||
.icon-aixin1-copy:before {
|
||||
content: "\eca4";
|
||||
}
|
||||
|
||||
.icon-shezhi-copy:before {
|
||||
content: "\eca5";
|
||||
}
|
||||
|
||||
.icon-xitongjiaose-copy:before {
|
||||
content: "\eca6";
|
||||
}
|
||||
|
||||
.icon-kefu-copy:before {
|
||||
content: "\eca7";
|
||||
}
|
||||
|
||||
.icon-shezhi:before {
|
||||
content: "\e62a";
|
||||
}
|
||||
|
||||
.icon-shezhitianchong:before {
|
||||
content: "\e68d";
|
||||
}
|
||||
|
||||
.icon-shezhi1:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-yijianfankui:before {
|
||||
content: "\e625";
|
||||
}
|
||||
|
||||
.icon-riqi:before {
|
||||
content: "\e636";
|
||||
}
|
||||
|
||||
.icon-kefu:before {
|
||||
content: "\e741";
|
||||
}
|
||||
|
||||
.icon-jiaoseguanli:before {
|
||||
content: "\ea62";
|
||||
}
|
||||
|
||||
.icon-yijianfankui1:before {
|
||||
content: "\e82f";
|
||||
}
|
||||
|
||||
.icon-dianzan:before {
|
||||
content: "\e611";
|
||||
}
|
||||
|
||||
.icon-shezhi2:before {
|
||||
content: "\e892";
|
||||
}
|
||||
|
||||
.icon-shezhi3:before {
|
||||
content: "\e70f";
|
||||
}
|
||||
|
||||
.icon-dianzan1:before {
|
||||
content: "\ec7f";
|
||||
}
|
||||
|
||||
.icon-yaoqingdaoshi-copy:before {
|
||||
content: "\eca8";
|
||||
}
|
||||
|
||||
.icon-jiaofuriqi:before {
|
||||
content: "\e667";
|
||||
}
|
||||
|
||||
.icon-aixin:before {
|
||||
content: "\eca1";
|
||||
}
|
||||
|
||||
.icon-yaoqingdaoshi:before {
|
||||
content: "\e640";
|
||||
}
|
||||
|
||||
.icon-dianzan2:before {
|
||||
content: "\e604";
|
||||
}
|
||||
|
||||
.icon-wenti:before {
|
||||
content: "\e78d";
|
||||
}
|
||||
|
||||
.icon-aixin1:before {
|
||||
content: "\e8ab";
|
||||
}
|
||||
|
||||
.icon-aixin2:before {
|
||||
content: "\e8c3";
|
||||
}
|
||||
|
||||
.icon-jiaoseguanli1:before {
|
||||
content: "\e64a";
|
||||
}
|
||||
|
||||
.icon-xitongjiaose:before {
|
||||
content: "\e60c";
|
||||
}
|
||||
|
||||
.icon-wenti1:before {
|
||||
content: "\e6e2";
|
||||
}
|
||||
|
||||
.icon-jiaoseguanli2:before {
|
||||
content: "\e676";
|
||||
}
|
||||
|
||||
.icon-dianzan1-copy:before {
|
||||
content: "\eca2";
|
||||
}
|
||||
|
||||
.icon-user:before {
|
||||
content: "\e677";
|
||||
}
|
||||
|
@ -1,478 +0,0 @@
|
||||
{
|
||||
"id": "3803079",
|
||||
"name": "kinit-uni",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "1261",
|
||||
"name": "查找用户",
|
||||
"font_class": "chazhaoyonghu",
|
||||
"unicode": "e601",
|
||||
"unicode_decimal": 58881
|
||||
},
|
||||
{
|
||||
"icon_id": "312606",
|
||||
"name": "users",
|
||||
"font_class": "users",
|
||||
"unicode": "e651",
|
||||
"unicode_decimal": 58961
|
||||
},
|
||||
{
|
||||
"icon_id": "383596",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan",
|
||||
"unicode": "e605",
|
||||
"unicode_decimal": 58885
|
||||
},
|
||||
{
|
||||
"icon_id": "570698",
|
||||
"name": "日志",
|
||||
"font_class": "rizhi",
|
||||
"unicode": "e660",
|
||||
"unicode_decimal": 58976
|
||||
},
|
||||
{
|
||||
"icon_id": "577700",
|
||||
"name": "字典",
|
||||
"font_class": "zidian",
|
||||
"unicode": "e679",
|
||||
"unicode_decimal": 59001
|
||||
},
|
||||
{
|
||||
"icon_id": "740849",
|
||||
"name": "常规字典",
|
||||
"font_class": "changguizidian",
|
||||
"unicode": "e694",
|
||||
"unicode_decimal": 59028
|
||||
},
|
||||
{
|
||||
"icon_id": "773022",
|
||||
"name": "user2",
|
||||
"font_class": "user2",
|
||||
"unicode": "e686",
|
||||
"unicode_decimal": 59014
|
||||
},
|
||||
{
|
||||
"icon_id": "1013067",
|
||||
"name": "高管",
|
||||
"font_class": "usertie",
|
||||
"unicode": "e65b",
|
||||
"unicode_decimal": 58971
|
||||
},
|
||||
{
|
||||
"icon_id": "1304947",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan1",
|
||||
"unicode": "e62c",
|
||||
"unicode_decimal": 58924
|
||||
},
|
||||
{
|
||||
"icon_id": "1330918",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan2",
|
||||
"unicode": "e61e",
|
||||
"unicode_decimal": 58910
|
||||
},
|
||||
{
|
||||
"icon_id": "1368559",
|
||||
"name": "字典搜索",
|
||||
"font_class": "dictionary",
|
||||
"unicode": "e606",
|
||||
"unicode_decimal": 58886
|
||||
},
|
||||
{
|
||||
"icon_id": "1680700",
|
||||
"name": "数据字典",
|
||||
"font_class": "shujuzidian",
|
||||
"unicode": "e666",
|
||||
"unicode_decimal": 58982
|
||||
},
|
||||
{
|
||||
"icon_id": "5387521",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan3",
|
||||
"unicode": "eaf1",
|
||||
"unicode_decimal": 60145
|
||||
},
|
||||
{
|
||||
"icon_id": "6176576",
|
||||
"name": "日志",
|
||||
"font_class": "rizhi1",
|
||||
"unicode": "e627",
|
||||
"unicode_decimal": 58919
|
||||
},
|
||||
{
|
||||
"icon_id": "6527123",
|
||||
"name": "日志",
|
||||
"font_class": "rizhi2",
|
||||
"unicode": "e647",
|
||||
"unicode_decimal": 58951
|
||||
},
|
||||
{
|
||||
"icon_id": "6536738",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan4",
|
||||
"unicode": "e668",
|
||||
"unicode_decimal": 58984
|
||||
},
|
||||
{
|
||||
"icon_id": "7588087",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan5",
|
||||
"unicode": "e61b",
|
||||
"unicode_decimal": 58907
|
||||
},
|
||||
{
|
||||
"icon_id": "7596825",
|
||||
"name": "24gl-portraitMalePlus4",
|
||||
"font_class": "24gl-portraitMalePlus4",
|
||||
"unicode": "eb25",
|
||||
"unicode_decimal": 60197
|
||||
},
|
||||
{
|
||||
"icon_id": "7685353",
|
||||
"name": "user",
|
||||
"font_class": "user1",
|
||||
"unicode": "e755",
|
||||
"unicode_decimal": 59221
|
||||
},
|
||||
{
|
||||
"icon_id": "7852107",
|
||||
"name": "user-tag",
|
||||
"font_class": "user-tag",
|
||||
"unicode": "e631",
|
||||
"unicode_decimal": 58929
|
||||
},
|
||||
{
|
||||
"icon_id": "8229518",
|
||||
"name": "日志",
|
||||
"font_class": "rizhi3",
|
||||
"unicode": "e603",
|
||||
"unicode_decimal": 58883
|
||||
},
|
||||
{
|
||||
"icon_id": "8605754",
|
||||
"name": "字典管理",
|
||||
"font_class": "zidianguanli",
|
||||
"unicode": "e669",
|
||||
"unicode_decimal": 58985
|
||||
},
|
||||
{
|
||||
"icon_id": "10333707",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan6",
|
||||
"unicode": "e624",
|
||||
"unicode_decimal": 58916
|
||||
},
|
||||
{
|
||||
"icon_id": "10884971",
|
||||
"name": "user",
|
||||
"font_class": "user3",
|
||||
"unicode": "e616",
|
||||
"unicode_decimal": 58902
|
||||
},
|
||||
{
|
||||
"icon_id": "11132430",
|
||||
"name": "user-o",
|
||||
"font_class": "user-o",
|
||||
"unicode": "e664",
|
||||
"unicode_decimal": 58980
|
||||
},
|
||||
{
|
||||
"icon_id": "12331679",
|
||||
"name": "日志",
|
||||
"font_class": "rizhi4",
|
||||
"unicode": "e66a",
|
||||
"unicode_decimal": 58986
|
||||
},
|
||||
{
|
||||
"icon_id": "15617636",
|
||||
"name": "user",
|
||||
"font_class": "user4",
|
||||
"unicode": "e8fa",
|
||||
"unicode_decimal": 59642
|
||||
},
|
||||
{
|
||||
"icon_id": "18444812",
|
||||
"name": "菜单",
|
||||
"font_class": "caidan7",
|
||||
"unicode": "e60e",
|
||||
"unicode_decimal": 58894
|
||||
},
|
||||
{
|
||||
"icon_id": "28122474",
|
||||
"name": "user",
|
||||
"font_class": "user5",
|
||||
"unicode": "e62b",
|
||||
"unicode_decimal": 58923
|
||||
},
|
||||
{
|
||||
"icon_id": "31313067",
|
||||
"name": "字典模块2",
|
||||
"font_class": "zidianmokuai2",
|
||||
"unicode": "e621",
|
||||
"unicode_decimal": 58913
|
||||
},
|
||||
{
|
||||
"icon_id": "32305",
|
||||
"name": "right",
|
||||
"font_class": "right",
|
||||
"unicode": "e6a3",
|
||||
"unicode_decimal": 59043
|
||||
},
|
||||
{
|
||||
"icon_id": "4767011",
|
||||
"name": "right",
|
||||
"font_class": "right1",
|
||||
"unicode": "e7eb",
|
||||
"unicode_decimal": 59371
|
||||
},
|
||||
{
|
||||
"icon_id": "15838431",
|
||||
"name": "arrow-right",
|
||||
"font_class": "arrow-right",
|
||||
"unicode": "e665",
|
||||
"unicode_decimal": 58981
|
||||
},
|
||||
{
|
||||
"icon_id": "15838566",
|
||||
"name": "arrow-right-bold",
|
||||
"font_class": "arrow-right-bold",
|
||||
"unicode": "e687",
|
||||
"unicode_decimal": 59015
|
||||
},
|
||||
{
|
||||
"icon_id": "375643",
|
||||
"name": "telephone",
|
||||
"font_class": "dianhua",
|
||||
"unicode": "e609",
|
||||
"unicode_decimal": 58889
|
||||
},
|
||||
{
|
||||
"icon_id": "33176640",
|
||||
"name": "问题-copy",
|
||||
"font_class": "wenti1-copy",
|
||||
"unicode": "eca9",
|
||||
"unicode_decimal": 60585
|
||||
},
|
||||
{
|
||||
"icon_id": "33176200",
|
||||
"name": "问题-copy",
|
||||
"font_class": "wenti1-copy1",
|
||||
"unicode": "eca3",
|
||||
"unicode_decimal": 60579
|
||||
},
|
||||
{
|
||||
"icon_id": "33176203",
|
||||
"name": "爱心-copy",
|
||||
"font_class": "aixin1-copy",
|
||||
"unicode": "eca4",
|
||||
"unicode_decimal": 60580
|
||||
},
|
||||
{
|
||||
"icon_id": "33176204",
|
||||
"name": "设置-copy",
|
||||
"font_class": "shezhi-copy",
|
||||
"unicode": "eca5",
|
||||
"unicode_decimal": 60581
|
||||
},
|
||||
{
|
||||
"icon_id": "33176223",
|
||||
"name": "系统角色-copy",
|
||||
"font_class": "xitongjiaose-copy",
|
||||
"unicode": "eca6",
|
||||
"unicode_decimal": 60582
|
||||
},
|
||||
{
|
||||
"icon_id": "33176232",
|
||||
"name": "客服-copy",
|
||||
"font_class": "kefu-copy",
|
||||
"unicode": "eca7",
|
||||
"unicode_decimal": 60583
|
||||
},
|
||||
{
|
||||
"icon_id": "145433",
|
||||
"name": "设置",
|
||||
"font_class": "shezhi",
|
||||
"unicode": "e62a",
|
||||
"unicode_decimal": 58922
|
||||
},
|
||||
{
|
||||
"icon_id": "145720",
|
||||
"name": "设置_填充",
|
||||
"font_class": "shezhitianchong",
|
||||
"unicode": "e68d",
|
||||
"unicode_decimal": 59021
|
||||
},
|
||||
{
|
||||
"icon_id": "162882",
|
||||
"name": "设置",
|
||||
"font_class": "shezhi1",
|
||||
"unicode": "e600",
|
||||
"unicode_decimal": 58880
|
||||
},
|
||||
{
|
||||
"icon_id": "270836",
|
||||
"name": "意见反馈",
|
||||
"font_class": "yijianfankui",
|
||||
"unicode": "e625",
|
||||
"unicode_decimal": 58917
|
||||
},
|
||||
{
|
||||
"icon_id": "524001",
|
||||
"name": "日期",
|
||||
"font_class": "riqi",
|
||||
"unicode": "e636",
|
||||
"unicode_decimal": 58934
|
||||
},
|
||||
{
|
||||
"icon_id": "577345",
|
||||
"name": "客服",
|
||||
"font_class": "kefu",
|
||||
"unicode": "e741",
|
||||
"unicode_decimal": 59201
|
||||
},
|
||||
{
|
||||
"icon_id": "742126",
|
||||
"name": "角色管理",
|
||||
"font_class": "jiaoseguanli",
|
||||
"unicode": "ea62",
|
||||
"unicode_decimal": 60002
|
||||
},
|
||||
{
|
||||
"icon_id": "831398",
|
||||
"name": "意见反馈",
|
||||
"font_class": "yijianfankui1",
|
||||
"unicode": "e82f",
|
||||
"unicode_decimal": 59439
|
||||
},
|
||||
{
|
||||
"icon_id": "886699",
|
||||
"name": "点赞",
|
||||
"font_class": "dianzan",
|
||||
"unicode": "e611",
|
||||
"unicode_decimal": 58897
|
||||
},
|
||||
{
|
||||
"icon_id": "2076270",
|
||||
"name": "设置",
|
||||
"font_class": "shezhi2",
|
||||
"unicode": "e892",
|
||||
"unicode_decimal": 59538
|
||||
},
|
||||
{
|
||||
"icon_id": "3456457",
|
||||
"name": "设置",
|
||||
"font_class": "shezhi3",
|
||||
"unicode": "e70f",
|
||||
"unicode_decimal": 59151
|
||||
},
|
||||
{
|
||||
"icon_id": "6337455",
|
||||
"name": "点赞",
|
||||
"font_class": "dianzan1",
|
||||
"unicode": "ec7f",
|
||||
"unicode_decimal": 60543
|
||||
},
|
||||
{
|
||||
"icon_id": "33176261",
|
||||
"name": "意见反馈-copy",
|
||||
"font_class": "yaoqingdaoshi-copy",
|
||||
"unicode": "eca8",
|
||||
"unicode_decimal": 60584
|
||||
},
|
||||
{
|
||||
"icon_id": "6614709",
|
||||
"name": "交付日期",
|
||||
"font_class": "jiaofuriqi",
|
||||
"unicode": "e667",
|
||||
"unicode_decimal": 58983
|
||||
},
|
||||
{
|
||||
"icon_id": "6775644",
|
||||
"name": "爱心",
|
||||
"font_class": "aixin",
|
||||
"unicode": "eca1",
|
||||
"unicode_decimal": 60577
|
||||
},
|
||||
{
|
||||
"icon_id": "7140563",
|
||||
"name": "意见反馈",
|
||||
"font_class": "yaoqingdaoshi",
|
||||
"unicode": "e640",
|
||||
"unicode_decimal": 58944
|
||||
},
|
||||
{
|
||||
"icon_id": "8718258",
|
||||
"name": "点赞",
|
||||
"font_class": "dianzan2",
|
||||
"unicode": "e604",
|
||||
"unicode_decimal": 58884
|
||||
},
|
||||
{
|
||||
"icon_id": "10232772",
|
||||
"name": "问题",
|
||||
"font_class": "wenti",
|
||||
"unicode": "e78d",
|
||||
"unicode_decimal": 59277
|
||||
},
|
||||
{
|
||||
"icon_id": "11372639",
|
||||
"name": "爱心",
|
||||
"font_class": "aixin1",
|
||||
"unicode": "e8ab",
|
||||
"unicode_decimal": 59563
|
||||
},
|
||||
{
|
||||
"icon_id": "11372756",
|
||||
"name": "爱心",
|
||||
"font_class": "aixin2",
|
||||
"unicode": "e8c3",
|
||||
"unicode_decimal": 59587
|
||||
},
|
||||
{
|
||||
"icon_id": "15388180",
|
||||
"name": "角色管理",
|
||||
"font_class": "jiaoseguanli1",
|
||||
"unicode": "e64a",
|
||||
"unicode_decimal": 58954
|
||||
},
|
||||
{
|
||||
"icon_id": "18383762",
|
||||
"name": "系统角色",
|
||||
"font_class": "xitongjiaose",
|
||||
"unicode": "e60c",
|
||||
"unicode_decimal": 58892
|
||||
},
|
||||
{
|
||||
"icon_id": "20266225",
|
||||
"name": "问题",
|
||||
"font_class": "wenti1",
|
||||
"unicode": "e6e2",
|
||||
"unicode_decimal": 59106
|
||||
},
|
||||
{
|
||||
"icon_id": "24271959",
|
||||
"name": "角色管理",
|
||||
"font_class": "jiaoseguanli2",
|
||||
"unicode": "e676",
|
||||
"unicode_decimal": 58998
|
||||
},
|
||||
{
|
||||
"icon_id": "33176180",
|
||||
"name": "点赞-copy",
|
||||
"font_class": "dianzan1-copy",
|
||||
"unicode": "eca2",
|
||||
"unicode_decimal": 60578
|
||||
},
|
||||
{
|
||||
"icon_id": "1175005",
|
||||
"name": "user",
|
||||
"font_class": "user",
|
||||
"unicode": "e677",
|
||||
"unicode_decimal": 58999
|
||||
}
|
||||
]
|
||||
}
|
Before Width: | Height: | Size: 229 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 229 KiB |
@ -1,24 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="https://api.kinit.ktianc.top/media/system/favicon.ico">
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>本站点必须要开启JavaScript才能运行.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-common-webview-index"],{2773:function(t,e,n){"use strict";n.r(e);var r=n("f841"),u=n("8bea");for(var a in u)"default"!==a&&function(t){n.d(e,t,(function(){return u[t]}))}(a);var i,c=n("f0c5"),o=Object(c["a"])(u["default"],r["b"],r["c"],!1,null,null,null,!1,r["a"],i);e["default"]=o.exports},"8bea":function(t,e,n){"use strict";n.r(e);var r=n("c807"),u=n.n(r);for(var a in r)"default"!==a&&function(t){n.d(e,t,(function(){return r[t]}))}(a);e["default"]=u.a},c807:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var r={data:function(){return{params:{},webviewStyles:{progress:{color:"#FF3333"}}}},props:{src:{type:[String],default:null}},onLoad:function(t){this.params=t,t.title&&uni.setNavigationBarTitle({title:t.title})}};e.default=r},f841:function(t,e,n){"use strict";var r;n.d(e,"b",(function(){return u})),n.d(e,"c",(function(){return a})),n.d(e,"a",(function(){return r}));var u=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.params.url?n("v-uni-view",[n("v-uni-web-view",{attrs:{"webview-styles":t.webviewStyles,src:""+t.params.url}})],1):t._e()},a=[]}}]);
|
@ -1 +0,0 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-index"],{"0a48":function(t,n,e){var a=e("24fb");n=a(!1),n.push([t.i,'@charset "UTF-8";\r\n/* uView的全局SCSS主题文件 */\r\n/**\r\n * uni-app内置的常用样式变量\r\n */\r\n/* 行为相关颜色 */\r\n/* 文字基本颜色 */\r\n/* 背景颜色 */\r\n/* 边框颜色 */\r\n/* 尺寸变量 */\r\n/* 文字尺寸 */\r\n/* 图片尺寸 */\r\n/* Border Radius */\r\n/* 水平间距 */\r\n/* 垂直间距 */\r\n/* 透明度 */\r\n/* 文章场景相关 */.content[data-v-3f7456ca]{display:flex;flex-direction:column;align-items:center;justify-content:center}.content .logo[data-v-3f7456ca]{height:%?200?%;width:%?200?%;margin-top:%?200?%;margin-left:auto;margin-right:auto;margin-bottom:%?50?%}.content .text-area[data-v-3f7456ca]{display:flex;justify-content:center}.content .text-area .title[data-v-3f7456ca]{font-size:%?36?%;color:#8f8f94}',""]),t.exports=n},"0cac":function(t,n,e){"use strict";e.r(n);var a=e("b0b5"),r=e("7053");for(var o in r)"default"!==o&&function(t){e.d(n,t,(function(){return r[t]}))}(o);e("ef9a");var i,u=e("f0c5"),c=Object(u["a"])(r["default"],a["b"],a["c"],!1,null,"3f7456ca",null,!1,a["a"],i);n["default"]=c.exports},"361d":function(t,n,e){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var a={computed:{name:function(){return this.$store.state.auth.name},logo:function(){return this.$store.state.app.logo},logoImage:function(){return this.$store.state.app.logoImage}}};n.default=a},"65f9":function(t,n,e){var a=e("0a48");a.__esModule&&(a=a.default),"string"===typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);var r=e("4f06").default;r("69a76130",a,!0,{sourceMap:!1,shadowMode:!1})},7053:function(t,n,e){"use strict";e.r(n);var a=e("361d"),r=e.n(a);for(var o in a)"default"!==o&&function(t){e.d(n,t,(function(){return a[t]}))}(o);n["default"]=r.a},b0b5:function(t,n,e){"use strict";var a;e.d(n,"b",(function(){return r})),e.d(n,"c",(function(){return o})),e.d(n,"a",(function(){return a}));var r=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("v-uni-view",{staticClass:"content"},[t.logo?e("v-uni-image",{staticClass:"logo",attrs:{src:t.logoImage}}):t._e(),e("v-uni-view",{staticClass:"text-area"},[e("v-uni-text",{staticClass:"title"},[t._v("Hello "+t._s(t.name))])],1)],1)},o=[]},ef9a:function(t,n,e){"use strict";var a=e("65f9"),r=e.n(a);r.a}}]);
|
@ -1 +0,0 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-mine-help-index"],{"0299":function(t,e,n){var i=n("24fb");e=i(!1),e.push([t.i,'@charset "UTF-8";\r\n/* uView的全局SCSS主题文件 */\r\n/**\r\n * uni-app内置的常用样式变量\r\n */\r\n/* 行为相关颜色 */\r\n/* 文字基本颜色 */\r\n/* 背景颜色 */\r\n/* 边框颜色 */\r\n/* 尺寸变量 */\r\n/* 文字尺寸 */\r\n/* 图片尺寸 */\r\n/* Border Radius */\r\n/* 水平间距 */\r\n/* 垂直间距 */\r\n/* 透明度 */\r\n/* 文章场景相关 */uni-page-body[data-v-0e82e800]{background-color:#f8f8f8}.help-container[data-v-0e82e800]{margin-bottom:%?100?%;padding:%?30?%}.list-title[data-v-0e82e800]{margin-bottom:%?30?%}.childList[data-v-0e82e800]{background:#fff;box-shadow:0 0 %?10?% hsla(0,0%,75.7%,.2);border-radius:%?16?%;margin-top:%?10?%}.line[data-v-0e82e800]{width:100%;height:%?1?%;background-color:#f5f5f5}.text-title[data-v-0e82e800]{color:#303133;font-size:%?32?%;font-weight:700;margin-left:%?10?%}.text-item[data-v-0e82e800]{font-size:%?28?%;padding:%?24?%}.question[data-v-0e82e800]{color:#606266;font-size:%?28?%}body.?%PAGE?%[data-v-0e82e800]{background-color:#f8f8f8}',""]),t.exports=e},1838:function(t,e,n){"use strict";var i;n.d(e,"b",(function(){return a})),n.d(e,"c",(function(){return o})),n.d(e,"a",(function(){return i}));var a=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("v-uni-view",{staticClass:"help-container"},t._l(t.list,(function(e,i){return n("v-uni-view",{key:i,staticClass:"list-title",attrs:{title:e.title}},[n("v-uni-view",{staticClass:"text-title"},[n("v-uni-view",[t._v(t._s(e.title))])],1),n("v-uni-view",{staticClass:"childList"},t._l(e.childList,(function(i,a){return n("v-uni-view",{key:a,staticClass:"question",attrs:{"hover-class":"hover"},on:{click:function(e){arguments[0]=e=t.$handleEvent(e),t.handleText(i)}}},[n("v-uni-view",{staticClass:"text-item"},[t._v(t._s(i.title))]),a!==e.childList.length-1?n("v-uni-view",{staticClass:"line"}):t._e()],1)})),1)],1)})),1)},o=[]},4518:function(t,e,n){"use strict";n.r(e);var i=n("1838"),a=n("4c9a");for(var o in a)"default"!==o&&function(t){n.d(e,t,(function(){return a[t]}))}(o);n("b272");var r,c=n("f0c5"),l=Object(c["a"])(a["default"],i["b"],i["c"],!1,null,"0e82e800",null,!1,i["a"],r);e["default"]=l.exports},"4c9a":function(t,e,n){"use strict";n.r(e);var i=n("bfb6"),a=n.n(i);for(var o in i)"default"!==o&&function(t){n.d(e,t,(function(){return i[t]}))}(o);e["default"]=a.a},"6ed9":function(t,e,n){var i=n("0299");i.__esModule&&(i=i.default),"string"===typeof i&&(i=[[t.i,i,""]]),i.locals&&(t.exports=i.locals);var a=n("4f06").default;a("547a298b",i,!0,{sourceMap:!1,shadowMode:!1})},b272:function(t,e,n){"use strict";var i=n("6ed9"),a=n.n(i);a.a},bfb6:function(t,e,n){"use strict";n("99af"),Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var i={data:function(){return{list:[{title:"KINIT 问题",childList:[{title:"KINIT-UNI 是使用若依-移动端进行的二次开发吗?",content:"是的,是在若依-移动端的基础上进行的二次开发,在此感谢若依团队!二次开发中我们重新将接口请求改为 luch-request 组件,项目结构也有所改动,并且加入了 uView UI 组件,uni-simple-router 路由拦截。"},{title:"KINIT 开源吗?",content:"开源"},{title:"KINIT 可以商用吗?",content:"可以"},{title:"KINIT 源码地址多少?",content:"https://gitee.com/ktianc/kinit"}]},{title:"其他问题",childList:[{title:"如何退出登录?",content:"请点击[我的] - [应用设置] - [退出登录]即可退出登录"},{title:"如何修改用户头像?",content:"请点击[我的] - [选择头像] - [点击提交]即可更换用户头像"},{title:"如何修改登录密码?",content:"请点击[我的] - [应用设置] - [修改密码]即可修改登录密码"}]}]}},methods:{handleText:function(t){this.$tab.navigateTo("/pages/common/textview/index?title=".concat(t.title,"&content=").concat(t.content))}}};e.default=i}}]);
|
@ -1 +0,0 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-mine-setting-index"],{"56c1":function(n,t,i){"use strict";var e;i.d(t,"b",(function(){return a})),i.d(t,"c",(function(){return o})),i.d(t,"a",(function(){return e}));var a=function(){var n=this,t=n.$createElement,i=n._self._c||t;return i("v-uni-view",{staticClass:"setting-container",style:{height:n.windowHeight+"px"}},[i("v-uni-view",{staticClass:"menu-list"},[i("v-uni-view",{staticClass:"list-cell list-cell-arrow",on:{click:function(t){arguments[0]=t=n.$handleEvent(t),n.handleToPwd.apply(void 0,arguments)}}},[i("v-uni-view",{staticClass:"menu-item-box"},[i("v-uni-view",{staticClass:"iconfont icon-password menu-icon"}),i("v-uni-view",[n._v("修改密码")])],1)],1),i("v-uni-view",{staticClass:"list-cell list-cell-arrow",on:{click:function(t){arguments[0]=t=n.$handleEvent(t),n.handleToUpgrade.apply(void 0,arguments)}}},[i("v-uni-view",{staticClass:"menu-item-box"},[i("v-uni-view",{staticClass:"iconfont icon-refresh menu-icon"}),i("v-uni-view",[n._v("检查更新")])],1)],1),i("v-uni-view",{staticClass:"list-cell list-cell-arrow",on:{click:function(t){arguments[0]=t=n.$handleEvent(t),n.handleCleanTmp.apply(void 0,arguments)}}},[i("v-uni-view",{staticClass:"menu-item-box"},[i("v-uni-view",{staticClass:"iconfont icon-clean menu-icon"}),i("v-uni-view",[n._v("清理缓存")])],1)],1)],1),i("v-uni-view",{staticClass:"cu-list menu"},[i("v-uni-view",{staticClass:"cu-item item-box"},[i("v-uni-view",{staticClass:"content text-center",on:{click:function(t){arguments[0]=t=n.$handleEvent(t),n.handleLogout.apply(void 0,arguments)}}},[i("v-uni-text",{staticClass:"text-black"},[n._v("退出登录")])],1)],1)],1)],1)},o=[]},a0bf:function(n,t,i){var e=i("e5de");e.__esModule&&(e=e.default),"string"===typeof e&&(e=[[n.i,e,""]]),e.locals&&(n.exports=e.locals);var a=i("4f06").default;a("b37e4e38",e,!0,{sourceMap:!1,shadowMode:!1})},bbc3:function(n,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var e={data:function(){return{windowHeight:uni.getSystemInfoSync().windowHeight}},methods:{handleToPwd:function(){this.$tab.navigateTo("/pages/mine/pwd/index")},handleToUpgrade:function(){this.$modal.showToast("模块建设中~")},handleCleanTmp:function(){this.$modal.showToast("模块建设中~")},handleLogout:function(){var n=this;this.$modal.confirm("确定注销并退出系统吗?").then((function(){n.$store.dispatch("LogOut")}))}}};t.default=e},c68a:function(n,t,i){"use strict";i.r(t);var e=i("56c1"),a=i("e48e");for(var o in a)"default"!==o&&function(n){i.d(t,n,(function(){return a[n]}))}(o);i("fcf5");var c,s=i("f0c5"),u=Object(s["a"])(a["default"],e["b"],e["c"],!1,null,"168c4196",null,!1,e["a"],c);t["default"]=u.exports},e48e:function(n,t,i){"use strict";i.r(t);var e=i("bbc3"),a=i.n(e);for(var o in e)"default"!==o&&function(n){i.d(t,n,(function(){return e[n]}))}(o);t["default"]=a.a},e5de:function(n,t,i){var e=i("24fb");t=e(!1),t.push([n.i,'@charset "UTF-8";\r\n/* uView的全局SCSS主题文件 */\r\n/**\r\n * uni-app内置的常用样式变量\r\n */\r\n/* 行为相关颜色 */\r\n/* 文字基本颜色 */\r\n/* 背景颜色 */\r\n/* 边框颜色 */\r\n/* 尺寸变量 */\r\n/* 文字尺寸 */\r\n/* 图片尺寸 */\r\n/* Border Radius */\r\n/* 水平间距 */\r\n/* 垂直间距 */\r\n/* 透明度 */\r\n/* 文章场景相关 */.page[data-v-168c4196]{background-color:#f8f8f8}.item-box[data-v-168c4196]{background-color:#fff;margin:%?30?%;display:flex;flex-direction:row;justify-content:center;align-items:center;padding:%?10?%;border-radius:%?8?%;color:#303133;font-size:%?32?%}',""]),n.exports=t},fcf5:function(n,t,i){"use strict";var e=i("a0bf"),a=i.n(e);a.a}}]);
|
BIN
kinit-uni/unpackage/dist/build/h5/static/logo.png
vendored
Before Width: | Height: | Size: 3.5 KiB |
BIN
kinit-uni/unpackage/dist/build/h5/static/logo200.png
vendored
Before Width: | Height: | Size: 7.8 KiB |
@ -1,90 +0,0 @@
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.font-13 {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.font-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.font-11 {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.text-grey1 {
|
||||
color: #888;
|
||||
}
|
||||
.text-grey2 {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.list-cell-arrow::before {
|
||||
content: ' ';
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c0c0c0;
|
||||
border-style: solid;
|
||||
-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
padding: 26rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-cell:first-child {
|
||||
border-radius: 8rpx 8rpx 0 0;
|
||||
}
|
||||
|
||||
.list-cell:last-child {
|
||||
border-radius: 0 0 8rpx 8rpx;
|
||||
}
|
||||
|
||||
.list-cell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-bottom: 1px solid #eaeef1;
|
||||
-webkit-transform: scaleY(0.5) translateZ(0);
|
||||
transform: scaleY(0.5) translateZ(0);
|
||||
transform-origin: 0 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
.menu-list {
|
||||
margin: 15px 15px;
|
||||
|
||||
.menu-item-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.menu-icon {
|
||||
color: #007AFF;
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
margin-left: auto;
|
||||
margin-right: 34rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
/* uview ui */
|
||||
@import "uview-ui/index.scss";
|
||||
// global
|
||||
@import "./global.scss";
|
||||
// color-ui
|
||||
@import "@/static/scss/colorui.css";
|
||||
// iconfont
|
||||
@import "@/static/font/iconfont.css";
|