Compare commits

..

61 Commits

Author SHA1 Message Date
ktianc
dd2e3a65af 更新二维码 2025-03-25 09:32:44 +08:00
ktianc
7adc37990a 版本信息说明更新 2024-12-28 13:29:01 +08:00
ktianc
8a75c11182 不影响的微调 2024-09-06 15:32:26 +08:00
ktianc
7fd7366e32 新增接口部分初始化失败的文档 2024-08-27 10:54:10 +08:00
ktianc
1354ea21e4 merge pr !20 添加了kinit-api 的 readme:数据迁移 、CRUD 2024-07-05 10:21:17 +08:00
ktianc
2d6108be44 Merge branch 'zsr_20240620' of https://gitee.com/westernCloud/kinit 2024-07-05 10:16:43 +08:00
zhusr39924
ef5c73b468 更新readme:数据迁移和生成CRUD,路由配置 2024-07-03 11:08:48 +08:00
zhusr39924
afe3b042d9 更新readme:数据迁移和生成CRUD,路由配置 2024-07-03 10:41:54 +08:00
zhusr39924
5af56e956c 更新readme:数据迁移和生成CRUD,路由配置 2024-07-03 10:34:54 +08:00
ktianc
1cc3fb0c3b update README.md 2024-07-03 09:25:24 +08:00
ktianc
39194d51c0 修复版本 2024-04-25 10:26:48 +08:00
ktianc
8d582b482c 前端路由 alwaysShow 不起作用问题修复 2024-04-25 10:23:27 +08:00
ktianc
13e124c02a 异常修复 2024-04-25 09:02:23 +08:00
ktianc
10ea077735 更新群二维码 2024-04-25 08:59:15 +08:00
ktianc
e191f76809 更新群链接 2024-04-21 22:33:35 +08:00
ktianc
e91dca078b 更新群链接 2024-04-14 22:13:22 +08:00
ktianc
e1d388dbfc 更新群链接 2024-04-06 16:35:49 +08:00
ktianc
39cd05fb44 更新群二维码 2024-03-30 16:25:59 +08:00
ktianc
8364ef731e
!18 3.10.0
Merge pull request !18 from ktianc/master
2024-03-23 10:05:56 +00:00
ktianc
cff85f09d5 更新群二维码 2024-03-23 18:02:29 +08:00
ktianc
eff099877e 优化忽略文件 2024-03-23 17:38:05 +08:00
ktianc
303777910c 清理无用文件 2024-03-23 16:57:58 +08:00
ktianc
76bd8ed3fe 微信小程序优化 2024-03-23 16:52:47 +08:00
ktianc
53c12a787e 优化忽略文件 2024-03-23 16:48:23 +08:00
ktianc
2970fe16da 修复声明返回类型错误 2024-03-21 21:42:56 +08:00
ktianc
4229620d8d
Merge pull request #25 from yaqiangsun/master
Fix alembic.ini config in README.md
2024-03-18 17:35:19 +08:00
yaqiang.sun
9c148dbb6b
Fix alembic.ini config in README.md
Remove extra 'sqlalchemy.url =' in alembic.ini config in README.md
2024-03-18 16:10:24 +08:00
ktianc
74c0b0a484 Merge branch 'master' of https://gitee.com/ktianc/kinit_dev 2024-03-17 12:17:46 +08:00
ktianc
974322a2b8
!17 更新群二维码
Merge pull request !17 from ktianc/master
2024-03-17 04:16:44 +00:00
ktianc
7ca8bd3244
Revert "add chat 1"
This reverts commit 9f635dc5f4b137fda6b6d73af0fdcb40562ac97c.
2024-03-17 04:14:51 +00:00
ktianc
332e728ca3
Revert "更新1"
This reverts commit 53a694be367e0b30a1070e9a72476cf01be8db90.
2024-03-17 04:14:35 +00:00
ktianc
bc5fa85ba6
Revert "Revert "更新至 3.9.0""
This reverts commit 03d8bd2eb4ae77ed2e57aa55635972b43515b10c.
2024-03-17 04:13:30 +00:00
ktianc
aafcb6527f Merge branch 'master' of https://gitee.com/ktianc/kinit_dev 2024-03-17 12:11:22 +08:00
ktianc
03d8bd2eb4
Revert "更新至 3.9.0"
This reverts commit adc7b21fc287c8d74ddd804c9be0d6c177793b9d.
2024-03-17 04:10:52 +00:00
ktianc
7a33c4d4f7 更新群二维码 2024-03-17 11:55:06 +08:00
ktianc
bc5f239cb7 更新群链接 2024-03-17 11:21:14 +08:00
ktianc
53a694be36 更新1 2024-03-15 17:39:17 +08:00
ktianc
9f635dc5f4 add chat 1 2024-03-13 18:57:53 +08:00
ktianc
b3b427edef
!16 3.9.0
Merge pull request !16 from ktianc/master
2024-03-12 10:26:14 +00:00
ktianc
adc7b21fc2 更新至 3.9.0 2024-03-12 18:24:55 +08:00
ktianc
61f39a7c64 vue-element-plus-admin 框架更新至最新版本 3.7.0(3.7.0中新增功能未更新只修复了问题) 2024-03-12 18:23:03 +08:00
ktianc
13bfb7d7b8
!15 3.8.1
Merge pull request !15 from ktianc/master
2024-03-09 08:59:47 +00:00
ktianc
8265cbc6d0 修复使用自定义数据权限报错问题 2024-03-09 12:30:18 +08:00
ktianc
4d240c24d2
!14 v3.8.1
Merge pull request !14 from ktianc/master
2024-03-08 08:35:32 +00:00
ktianc
2c39c91108 更新版本 2024-03-08 16:33:40 +08:00
ktianc
df611901c6 更新群相册 2024-03-08 16:32:19 +08:00
ktianc
ae44370f78 增加快捷操作 2024-03-08 16:32:03 +08:00
ktianc
149812914e 修复 oss 文件上传路径错误问题 2024-03-08 16:31:14 +08:00
ktianc
b08cd1ca42
!13 更新至 v3.8.0
Merge pull request !13 from ktianc/master
2024-03-07 09:59:17 +00:00
ktianc
1e7dbec10b 更新版本 2024-03-07 09:01:23 +08:00
ktianc
9bb0d17fb8 部分代码优化,接口依赖包升级 2024-03-06 19:05:49 +08:00
ktianc
953cdda006 新增用户密码加入请求校验,如果密码发生改变需要重新登陆,便于使用密码进行强制退出 2024-03-06 19:04:20 +08:00
ktianc
3ccbc2c4b2 新增演示接口黑名单功能 2024-03-06 18:59:29 +08:00
ktianc
057915375a 登录日志列表获取倒叙 2024-03-06 16:47:13 +08:00
ktianc
64f221fb3f
!12 3.7.1
Merge pull request !12 from ktianc/master
2024-03-02 12:02:24 +00:00
ktianc
0189fa867a 更新版本号,默认配置为使用演示环境 2024-03-02 19:56:40 +08:00
ktianc
c5cfe3ffcb 更新群二维码 2024-03-02 19:56:01 +08:00
ktianc
5053d59f62 前端优化 2024-03-02 19:55:23 +08:00
ktianc
f8c748a15a 修复系统基本信息修改报错问题 2024-03-02 19:54:31 +08:00
ktianc
7036c1fc02 异步上传保存文件到本地问题修复 2024-03-02 19:53:24 +08:00
ktianc
20a425ed8c 更新群二维码 2024-02-25 16:53:15 +08:00
353 changed files with 1992 additions and 22635 deletions

21
.gitignore vendored
View File

@ -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

View File

@ -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. 创建数据库

View File

@ -5,3 +5,5 @@ dist-ssr
*-lock.*
pnpm-debug
stats.html
dist-pro
.vscode

View File

@ -1,3 +0,0 @@
{
"recommendations": ["vue.volar", "lokalise.i18n-ally"]
}

View File

@ -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"
}

View File

@ -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": {

View File

@ -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>

View File

@ -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.5pxel-input-number,
min-width: 229.5px;
}
}
</style>

View File

@ -93,7 +93,7 @@ export default defineComponent({
>
{{
default: () => {
const { renderMenuItem } = useRenderMenuItem(unref(menuMode))
const { renderMenuItem } = useRenderMenuItem()
return renderMenuItem(unref(routers))
}
}}

View File

@ -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
}
}

View File

@ -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)
}
]}

View File

@ -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
})

View File

@ -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')
}

View File

@ -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

View File

@ -113,7 +113,7 @@ service.interceptors.response.use(
case 401:
// 强制要求重新登录因账号已冻结账号已过期手机号码错误刷新token无效等问题导致
authStore.logout()
message = '认证已过期,请重新登录'
message = '认证已失效,请重新登录'
break
case 403:
// 强制要求重新登录,因无系统权限,而进入到系统访问等问题导致

View File

@ -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()

View File

@ -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)) {

View File

@ -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

View File

@ -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>

View 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>

View 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>

View File

@ -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 {

View File

@ -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 []
}
}

View File

@ -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({

View File

@ -10,7 +10,6 @@ logs/*
!logs/.gitkeep
temp/*
!temp/.gitkeep
!static/.gitkeep
!alembic/versions/.gitkeep
# dotenv

View File

@ -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 验证生成的接口
## 查询数据
### 自定义的一些查询过滤

View File

@ -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"
]
"""
引入数据库配置

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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:

View File

@ -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

View File

@ -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"]))
):

View File

@ -32,3 +32,4 @@ class LoginParams(QueryParams):
self.address = ("like", address)
self.status = status
self.platform = platform
self.v_order = "desc"

View File

@ -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)

View File

@ -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 文档",

View File

@ -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,
}
)

View File

@ -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)

Binary file not shown.

View 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)

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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,

View File

@ -11,4 +11,7 @@
package-lock.json
yarn.lock
kinit-uni.code-workspace
/unpackage/*

View File

@ -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
}
}
}

View File

@ -26,6 +26,11 @@ uni.$u.setConfig({
size: 33,
labelSize: 30
},
checkbox: {
size: 33,
labelSize: 30,
iconSize: 20
},
button: {
loadingSize: 28
},

View File

@ -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%;

View File

@ -0,0 +1,24 @@
## 1.0.112023-01-29
优化点击,加入点击自己再次点击也会关闭
## 1.0.102023-01-17
优化
## 1.0.92023-01-17
增加注释
## 1.0.82022-08-18
优化细节
## 1.0.672022-05-09
修复安卓报错
## 1.0.62022-05-07
修改默认展示
## 1.0.52022-04-28
进行优化
## 1.0.42022-04-27
进行优化
## 1.0.32022-04-25
去掉多余得注释
## 1.0.22022-04-25
增加自定义主题颜色
## 1.0.12022-04-25
进行优化显示
## 1.0.02022-04-24
初始化

View File

@ -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>

View 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"
}
}
}
}
}

View 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
```

View File

@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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";
}

File diff suppressed because one or more lines are too long

View File

@ -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
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

File diff suppressed because one or more lines are too long

View File

@ -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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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=[]}}]);

View File

@ -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}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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}}]);

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

File diff suppressed because it is too large Load Diff

View File

@ -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;
}
}
}

View File

@ -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";

Some files were not shown because too many files have changed in this diff Show More