清理一些未引用的文件

This commit is contained in:
ktianc 2022-10-11 17:41:06 +08:00
parent f5996560fb
commit 2695c806ad
27 changed files with 69 additions and 1603 deletions

View File

@ -26,7 +26,7 @@ Kinit 是一套全部开源的快速开发平台,毫无保留给个人及企
## 在线体验 ## 在线体验
👩‍👧‍👦演示地址:正在部署中。。。。。 👩‍👧‍👦演示地址:http://kinit.ktianc.top/
- 账号admin - 账号admin
- 密码123456 - 密码123456

View File

@ -8,4 +8,4 @@ VITE_API_BASEPATH=base
VITE_BASE_PATH=/ VITE_BASE_PATH=/
# 标题 # 标题
VITE_APP_TITLE=KInit VITE_APP_TITLE=Kinit

View File

@ -20,4 +20,4 @@ VITE_SOURCEMAP=true
VITE_OUT_DIR=dist-dev VITE_OUT_DIR=dist-dev
# 标题 # 标题
VITE_APP_TITLE=KInit VITE_APP_TITLE=Kinit

View File

@ -20,4 +20,4 @@ VITE_SOURCEMAP=false
VITE_OUT_DIR=dist-pro VITE_OUT_DIR=dist-pro
# 标题 # 标题
VITE_APP_TITLE=KInit VITE_APP_TITLE=Kinit

View File

@ -20,4 +20,4 @@ VITE_SOURCEMAP=false
VITE_OUT_DIR=dist-pro VITE_OUT_DIR=dist-pro
# 标题 # 标题
VITE_APP_TITLE=ElementAdmin VITE_APP_TITLE=Kinit

View File

@ -20,4 +20,4 @@ VITE_SOURCEMAP=true
VITE_OUT_DIR=dist-test VITE_OUT_DIR=dist-test
# 标题 # 标题
VITE_APP_TITLE=ElementAdmin VITE_APP_TITLE=Kinit

View File

@ -3,6 +3,5 @@ node_modules
dist dist
dist-ssr dist-ssr
*.local *.local
/dist*
*-lock.* *-lock.*
pnpm-debug pnpm-debug

View File

@ -1,5 +1,4 @@
<div align="center"> <a href="https://github.com/kailong321200875/vue-element-plus-admin"> <img width="100" src="./public/logo.png"> </a> <br> <br> <div align="center"> <a href="https://github.com/kailong321200875/vue-element-plus-admin"> <img width="100" src="./public/logo.png"> </a> <br> <br>
[![license](https://img.shields.io/github/license/kailong321200875/vue-element-plus-admin.svg)](LICENSE) [![license](https://img.shields.io/github/license/kailong321200875/vue-element-plus-admin.svg)](LICENSE)
<h1>vue-element-plus-admin</h1> <h1>vue-element-plus-admin</h1>
@ -68,7 +67,6 @@ git clone https://github.com/kailong321200875/vue-element-plus-admin.git
cd vue-element-plus-admin cd vue-element-plus-admin
pnpm install pnpm install
``` ```
- 运行 - 运行

View File

@ -1,63 +0,0 @@
import { config } from '@/config/axios/config'
import { MockMethod } from 'vite-plugin-mock'
const { result_code } = config
const timeout = 1000
const dictObj: Recordable = {
importance: [
{
value: 0,
label: 'tableDemo.commonly'
},
{
value: 1,
label: 'tableDemo.good'
},
{
value: 2,
label: 'tableDemo.important'
}
]
}
export default [
// 字典接口
{
url: '/api/dict/list',
method: 'get',
timeout,
response: () => {
return {
code: result_code,
data: dictObj
}
}
},
// 获取某个字典
{
url: '/api/dict/one',
method: 'get',
timeout,
response: () => {
return {
code: result_code,
data: [
{
label: 'test1',
value: 0
},
{
label: 'test2',
value: 1
},
{
label: 'test3',
value: 2
}
]
}
}
}
] as MockMethod[]

View File

@ -1,534 +0,0 @@
import { config } from '@/config/axios/config'
import { MockMethod } from 'vite-plugin-mock'
const { result_code } = config
const timeout = 1000
const adminList = [
{
path: '/dashboard',
component: '#',
redirect: '/dashboard/analysis',
name: 'Dashboard',
meta: {
title: 'router.dashboard',
icon: 'ant-design:dashboard-filled',
alwaysShow: true
},
children: [
{
path: 'analysis',
component: 'views/Dashboard/Analysis',
name: 'Analysis',
meta: {
title: 'router.analysis',
noCache: true
}
},
{
path: 'workplace',
component: 'views/Dashboard/Workplace',
name: 'Workplace',
meta: {
title: 'router.workplace',
noCache: true
}
}
]
},
{
path: '/external-link',
component: '#',
meta: {},
name: 'ExternalLink',
children: [
{
path: 'https://element-plus-admin-doc.cn/',
name: 'DocumentLink',
meta: {
title: 'router.document',
icon: 'clarity:document-solid'
}
}
]
},
{
path: '/guide',
component: '#',
name: 'Guide',
meta: {},
children: [
{
path: 'index',
component: 'views/Guide/Guide',
name: 'GuideDemo',
meta: {
title: 'router.guide',
icon: 'cib:telegram-plane'
}
}
]
},
{
path: '/components',
component: '#',
redirect: '/components/form/default-form',
name: 'ComponentsDemo',
meta: {
title: 'router.component',
icon: 'bx:bxs-component',
alwaysShow: true
},
children: [
{
path: 'form',
component: '##',
name: 'Form',
meta: {
title: 'router.form',
alwaysShow: true
},
children: [
{
path: 'default-form',
component: 'views/Components/Form/DefaultForm',
name: 'DefaultForm',
meta: {
title: 'router.defaultForm'
}
},
{
path: 'use-form',
component: 'views/Components/Form/UseFormDemo',
name: 'UseForm',
meta: {
title: 'UseForm'
}
},
{
path: 'ref-form',
component: 'views/Components/Form/RefForm',
name: 'RefForm',
meta: {
title: 'RefForm'
}
}
]
},
{
path: 'table',
component: '##',
redirect: '/components/table/default-table',
name: 'TableDemo',
meta: {
title: 'router.table',
alwaysShow: true
},
children: [
{
path: 'default-table',
component: 'views/Components/Table/DefaultTable',
name: 'DefaultTable',
meta: {
title: 'router.defaultTable'
}
},
{
path: 'use-table',
component: 'views/Components/Table/UseTableDemo',
name: 'UseTable',
meta: {
title: 'UseTable'
}
},
{
path: 'ref-table',
component: 'views/Components/Table/RefTable',
name: 'RefTable',
meta: {
title: 'RefTable'
}
}
]
},
{
path: 'editor-demo',
component: '##',
redirect: '/components/editor-demo/editor',
name: 'EditorDemo',
meta: {
title: 'router.editor',
alwaysShow: true
},
children: [
{
path: 'editor',
component: 'views/Components/Editor/Editor',
name: 'Editor',
meta: {
title: 'router.richText'
}
}
]
},
{
path: 'search',
component: 'views/Components/Search',
name: 'Search',
meta: {
title: 'router.search'
}
},
{
path: 'descriptions',
component: 'views/Components/Descriptions',
name: 'Descriptions',
meta: {
title: 'router.descriptions'
}
},
{
path: 'image-viewer',
component: 'views/Components/ImageViewer',
name: 'ImageViewer',
meta: {
title: 'router.imageViewer'
}
},
{
path: 'dialog',
component: 'views/Components/Dialog',
name: 'Dialog',
meta: {
title: 'router.dialog'
}
},
{
path: 'icon',
component: 'views/Components/Icon',
name: 'Icon',
meta: {
title: 'router.icon'
}
},
{
path: 'echart',
component: 'views/Components/Echart',
name: 'Echart',
meta: {
title: 'router.echart'
}
},
{
path: 'count-to',
component: 'views/Components/CountTo',
name: 'CountTo',
meta: {
title: 'router.countTo'
}
},
{
path: 'qrcode',
component: 'views/Components/Qrcode',
name: 'Qrcode',
meta: {
title: 'router.qrcode'
}
},
{
path: 'highlight',
component: 'views/Components/Highlight',
name: 'Highlight',
meta: {
title: 'router.highlight'
}
},
{
path: 'infotip',
component: 'views/Components/Infotip',
name: 'Infotip',
meta: {
title: 'router.infotip'
}
},
{
path: 'input-password',
component: 'views/Components/InputPassword',
name: 'InputPassword',
meta: {
title: 'router.inputPassword'
}
},
{
path: 'sticky',
component: 'views/Components/Sticky',
name: 'Sticky',
meta: {
title: 'router.sticky'
}
}
]
},
{
path: '/hooks',
component: '#',
redirect: '/hooks/useWatermark',
name: 'Hooks',
meta: {
title: 'hooks',
icon: 'ic:outline-webhook',
alwaysShow: true
},
children: [
{
path: 'useWatermark',
component: 'views/hooks/useWatermark',
name: 'UseWatermark',
meta: {
title: 'useWatermark'
}
},
{
path: 'useCrudSchemas',
component: 'views/hooks/useCrudSchemas',
name: 'UseCrudSchemas',
meta: {
title: 'useCrudSchemas'
}
}
]
},
{
path: '/level',
component: '#',
redirect: '/level/menu1/menu1-1/menu1-1-1',
name: 'Level',
meta: {
title: 'router.level',
icon: 'carbon:skill-level-advanced'
},
children: [
{
path: 'menu1',
name: 'Menu1',
component: '##',
redirect: '/level/menu1/menu1-1/menu1-1-1',
meta: {
title: 'router.menu1'
},
children: [
{
path: 'menu1-1',
name: 'Menu11',
component: '##',
redirect: '/level/menu1/menu1-1/menu1-1-1',
meta: {
title: 'router.menu11',
alwaysShow: true
},
children: [
{
path: 'menu1-1-1',
name: 'Menu111',
component: 'views/Level/Menu111',
meta: {
title: 'router.menu111'
}
}
]
},
{
path: 'menu1-2',
name: 'Menu12',
component: 'views/Level/Menu12',
meta: {
title: 'router.menu12'
}
}
]
},
{
path: 'menu2',
name: 'Menu2Demo',
component: 'views/Level/Menu2',
meta: {
title: 'router.menu2'
}
}
]
},
{
path: '/example',
component: '#',
redirect: '/example/example-dialog',
name: 'Example',
meta: {
title: 'router.example',
icon: 'ep:management',
alwaysShow: true
},
children: [
{
path: 'example-dialog',
component: 'views/Example/Dialog/ExampleDialog',
name: 'ExampleDialog',
meta: {
title: 'router.exampleDialog'
}
},
{
path: 'example-page',
component: 'views/Example/Page/ExamplePage',
name: 'ExamplePage',
meta: {
title: 'router.examplePage'
}
},
{
path: 'example-add',
component: 'views/Example/Page/ExampleAdd',
name: 'ExampleAdd',
meta: {
title: 'router.exampleAdd',
noTagsView: true,
noCache: true,
hidden: true,
showMainRoute: true,
activeMenu: '/example/example-page'
}
},
{
path: 'example-edit',
component: 'views/Example/Page/ExampleEdit',
name: 'ExampleEdit',
meta: {
title: 'router.exampleEdit',
noTagsView: true,
noCache: true,
hidden: true,
showMainRoute: true,
activeMenu: '/example/example-page'
}
},
{
path: 'example-detail',
component: 'views/Example/Page/ExampleDetail',
name: 'ExampleDetail',
meta: {
title: 'router.exampleDetail',
noTagsView: true,
noCache: true,
hidden: true,
showMainRoute: true,
activeMenu: '/example/example-page'
}
}
]
},
{
path: '/error',
component: '#',
redirect: '/error/404',
name: 'Error',
meta: {
title: 'router.errorPage',
icon: 'ci:error',
alwaysShow: true
},
children: [
{
path: '404-demo',
component: 'views/Error/404',
name: '404Demo',
meta: {
title: '404'
}
},
{
path: '403-demo',
component: 'views/Error/403',
name: '403Demo',
meta: {
title: '403'
}
},
{
path: '500-demo',
component: 'views/Error/500',
name: '500Demo',
meta: {
title: '500'
}
}
]
}
]
const testList: string[] = [
'/dashboard',
'/dashboard/analysis',
'/dashboard/workplace',
'external-link',
'https://element-plus-admin-doc.cn/',
'/guide',
'/guide/index',
'/components',
'/components/form',
'/components/form/default-form',
'/components/form/use-form',
'/components/form/ref-form',
'/components/table',
'/components/table/default-table',
'/components/table/use-table',
'/components/table/ref-table',
'/components/editor-demo',
'/components/editor-demo/editor',
'/components/search',
'/components/descriptions',
'/components/image-viewer',
'/components/dialog',
'/components/icon',
'/components/echart',
'/components/count-to',
'/components/qrcode',
'/components/highlight',
'/components/infotip',
'/Components/InputPassword',
'/Components/Sticky',
'/hooks',
'/hooks/useWatermark',
'/hooks/useCrudSchemas',
'/level',
'/level/menu1',
'/level/menu1/menu1-1',
'/level/menu1/menu1-1/menu1-1-1',
'/level/menu1/menu1-2',
'/level/menu2',
'/example',
'/example/example-dialog',
'/example/example-page',
'/example/example-add',
'/example/example-edit',
'/example/example-detail',
'/error',
'/error/404-demo',
'/error/403-demo',
'/error/500-demo'
]
export default [
// 列表接口
// {
// url: '/role/list',
// method: 'get',
// timeout,
// response: ({ query }) => {
// const { roleName } = query
// return {
// code: result_code,
// data: roleName === 'admin' ? adminList : testList
// }
// }
// }
] as MockMethod[]

View File

@ -1,137 +0,0 @@
import { config } from '@/config/axios/config'
import { MockMethod } from 'vite-plugin-mock'
import { toAnyString } from '@/utils'
import Mock from 'mockjs'
const { result_code } = config
const timeout = 1000
const count = 100
const baseContent =
'<p>I am testing data, I am testing data.</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>'
let List: {
id: string
author: string
title: string
content: string
importance: number
display_time: string
pageviews: number
}[] = []
for (let i = 0; i < count; i++) {
List.push(
Mock.mock({
id: toAnyString(),
// timestamp: +Mock.Random.date('T'),
author: '@first',
title: '@title(5, 10)',
content: baseContent,
importance: '@integer(1, 3)',
display_time: '@datetime',
pageviews: '@integer(300, 5000)'
// image_uri
})
)
}
export default [
// 列表接口
{
url: '/api/example/list',
method: 'get',
timeout,
response: ({ query }) => {
const { title, pageIndex, pageSize } = query
const mockList = List.filter((item) => {
if (title && item.title.indexOf(title) < 0) return false
return true
})
const pageList = mockList.filter(
(_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)
)
return {
code: result_code,
data: {
total: mockList.length,
list: pageList
}
}
}
},
// 保存接口
{
url: '/example/save',
method: 'post',
timeout,
response: ({ body }) => {
if (!body.id) {
List = [
Object.assign(body, {
id: toAnyString()
})
].concat(List)
return {
code: result_code,
data: 'success'
}
} else {
List.map((item) => {
if (item.id === body.id) {
for (const key in item) {
item[key] = body[key]
}
}
})
return {
code: result_code,
data: 'success'
}
}
}
},
// 详情接口
{
url: '/example/detail',
method: 'get',
response: ({ query }) => {
const { id } = query
for (const example of List) {
if (example.id === id) {
return {
code: result_code,
data: example
}
}
}
}
},
// 删除接口
{
url: '/example/delete',
method: 'post',
response: ({ body }) => {
const ids = body.ids
if (!ids) {
return {
code: '500',
message: '请选择需要删除的数据'
}
} else {
let i = List.length
while (i--) {
if (ids.indexOf(List[i].id) !== -1) {
List.splice(i, 1)
}
}
return {
code: result_code,
data: 'success'
}
}
}
}
] as MockMethod[]

View File

@ -1,93 +0,0 @@
import { config } from '@/config/axios/config'
import { MockMethod } from 'vite-plugin-mock'
const { result_code } = config
const timeout = 1000
const List: {
username: string
password: string
role: string
roleId: string
permissions: string | string[]
}[] = [
{
username: 'admin',
password: 'admin',
role: 'admin',
roleId: '1',
permissions: ['*.*.*']
},
{
username: 'test',
password: 'test',
role: 'test',
roleId: '2',
permissions: ['example:dialog:create', 'example:dialog:delete']
}
]
export default [
// 列表接口
{
url: '/user/list',
method: 'get',
response: ({ query }) => {
const { username, pageIndex, pageSize } = query
const mockList = List.filter((item) => {
if (username && item.username.indexOf(username) < 0) return false
return true
})
const pageList = mockList.filter(
(_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)
)
return {
code: result_code,
data: {
total: mockList.length,
list: pageList
}
}
}
},
// 登录接口
// {
// url: '/user/login',
// method: 'post',
// timeout,
// response: ({ body }) => {
// const data = body
// let hasUser = false
// for (const user of List) {
// if (user.username === data.username && user.password === data.password) {
// hasUser = true
// return {
// code: result_code,
// data: user
// }
// }
// }
// if (!hasUser) {
// return {
// code: '500',
// message: '手机号或密码错误'
// }
// }
// }
// },
// 退出接口
{
url: '/user/loginOut',
method: 'get',
timeout,
response: () => {
return {
code: result_code,
data: null
}
}
}
] as MockMethod[]

View File

@ -1,11 +0,0 @@
import request from '@/config/axios'
// 获取所有字典
export const getDictApi = (): Promise<IResponse> => {
return request.get({ url: '/dict/list' })
}
// 模拟获取某个字典
export const getDictOneApi = async (): Promise<IResponse> => {
return request.get({ url: '/dict/one' })
}

View File

@ -1,21 +1,10 @@
import request from '@/config/axios' import request from '@/config/axios'
import type { UserLoginType, UserType } from './types' import type { UserLoginType } from './types'
export const loginApi = (data: UserLoginType): Promise<IResponse> => { export const loginApi = (data: UserLoginType): Promise<IResponse> => {
return request.post({ url: '/auth/login/', data }) return request.post({ url: '/auth/login/', data })
} }
export const loginOutApi = (): Promise<IResponse> => {
return request.get({ url: '/user/loginOut' })
}
export const getUserListApi = ({ params }: AxiosConfig) => {
return request.get<{
total: number
list: UserType[]
}>({ url: '/user/list', params })
}
export const getRoleMenusApi = (): Promise<IResponse<AppCustomRouteRecordRaw[]>> => { export const getRoleMenusApi = (): Promise<IResponse<AppCustomRouteRecordRaw[]>> => {
return request.get({ url: '/auth/getMenuList/' }) return request.get({ url: '/auth/getMenuList/' })
} }

View File

@ -1,18 +0,0 @@
import request from '@/config/axios'
import type { TableData } from './types'
export const getTableListApi = (params: any): Promise<IResponse> => {
return request.get({ url: '/example/list', params })
}
export const saveTableApi = (data: Partial<TableData>): Promise<IResponse> => {
return request.post({ url: '/example/save', data })
}
export const getTableDetApi = (id: string): Promise<IResponse<TableData>> => {
return request.get({ url: '/example/detail', params: { id } })
}
export const delTableListApi = (ids: string[] | number[]): Promise<IResponse> => {
return request.post({ url: '/example/delete', data: { ids } })
}

View File

@ -1,9 +0,0 @@
export type TableData = {
id: string
author: string
title: string
content: string
importance: number
display_time: string
pageviews: number
}

View File

@ -51,6 +51,8 @@ export const useForm = (props?: FormProps) => {
*/ */
setSchema: async (schemaProps: FormSetPropsType[]) => { setSchema: async (schemaProps: FormSetPropsType[]) => {
const form = await getForm() const form = await getForm()
console.log(1111111111, schemaProps)
console.log(222222, form)
form?.setSchema(schemaProps) form?.setSchema(schemaProps)
}, },

View File

@ -16,23 +16,6 @@ export const constantRouterMap: AppRouteRecordRaw[] = [
hidden: true hidden: true
} }
}, },
{
path: '/redirect',
component: Layout,
name: 'Redirect',
children: [
{
path: '/redirect/:path(.*)',
name: 'Redirect',
component: () => import('@/views/Redirect/Redirect.vue'),
meta: {}
}
],
meta: {
hidden: true,
noTagsView: true
}
},
{ {
path: '/login', path: '/login',
component: () => import('@/views/Login/Login.vue'), component: () => import('@/views/Login/Login.vue'),

View File

@ -1,200 +0,0 @@
<script setup lang="ts">
import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
import { CountTo } from '@/components/CountTo'
import { useDesign } from '@/hooks/web/useDesign'
import { useI18n } from '@/hooks/web/useI18n'
import { ref, reactive } from 'vue'
import { getCountApi } from '@/api/dashboard/analysis'
import type { AnalysisTotalTypes } from '@/api/dashboard/analysis/types'
const { t } = useI18n()
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('panel')
const loading = ref(true)
let totalState = reactive<AnalysisTotalTypes>({
users: 0,
messages: 0,
moneys: 0,
shoppings: 0
})
const getCount = async () => {
const res = await getCountApi()
.catch(() => {})
.finally(() => {
loading.value = false
})
totalState = Object.assign(totalState, res?.data || {})
}
getCount()
</script>
<template>
<ElRow :gutter="20" justify="space-between" :class="prefixCls">
<ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
<ElCard shadow="hover" class="mb-20px">
<ElSkeleton :loading="loading" animated :rows="2">
<template #default>
<div :class="`${prefixCls}__item flex justify-between`">
<div>
<div
:class="`${prefixCls}__item--icon ${prefixCls}__item--peoples p-16px inline-block rounded-6px`"
>
<Icon icon="svg-icon:peoples" :size="40" />
</div>
</div>
<div class="flex flex-col justify-between">
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
t('analysis.newUser')
}}</div>
<CountTo
class="text-20px font-700 text-right"
:start-val="0"
:end-val="102400"
:duration="2600"
/>
</div>
</div>
</template>
</ElSkeleton>
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
<ElCard shadow="hover" class="mb-20px">
<ElSkeleton :loading="loading" animated :rows="2">
<template #default>
<div :class="`${prefixCls}__item flex justify-between`">
<div>
<div
:class="`${prefixCls}__item--icon ${prefixCls}__item--message p-16px inline-block rounded-6px`"
>
<Icon icon="svg-icon:message" :size="40" />
</div>
</div>
<div class="flex flex-col justify-between">
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
t('analysis.unreadInformation')
}}</div>
<CountTo
class="text-20px font-700 text-right"
:start-val="0"
:end-val="81212"
:duration="2600"
/>
</div>
</div>
</template>
</ElSkeleton>
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
<ElCard shadow="hover" class="mb-20px">
<ElSkeleton :loading="loading" animated :rows="2">
<template #default>
<div :class="`${prefixCls}__item flex justify-between`">
<div>
<div
:class="`${prefixCls}__item--icon ${prefixCls}__item--money p-16px inline-block rounded-6px`"
>
<Icon icon="svg-icon:money" :size="40" />
</div>
</div>
<div class="flex flex-col justify-between">
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
t('analysis.transactionAmount')
}}</div>
<CountTo
class="text-20px font-700 text-right"
:start-val="0"
:end-val="9280"
:duration="2600"
/>
</div>
</div>
</template>
</ElSkeleton>
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
<ElCard shadow="hover" class="mb-20px">
<ElSkeleton :loading="loading" animated :rows="2">
<template #default>
<div :class="`${prefixCls}__item flex justify-between`">
<div>
<div
:class="`${prefixCls}__item--icon ${prefixCls}__item--shopping p-16px inline-block rounded-6px`"
>
<Icon icon="svg-icon:shopping" :size="40" />
</div>
</div>
<div class="flex flex-col justify-between">
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
t('analysis.totalShopping')
}}</div>
<CountTo
class="text-20px font-700 text-right"
:start-val="0"
:end-val="13600"
:duration="2600"
/>
</div>
</div>
</template>
</ElSkeleton>
</ElCard>
</ElCol>
</ElRow>
</template>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-panel';
.@{prefix-cls} {
&__item {
&--peoples {
color: #40c9c6;
}
&--message {
color: #36a3f7;
}
&--money {
color: #f4516c;
}
&--shopping {
color: #34bfa3;
}
&:hover {
:deep(.@{namespace}-icon) {
color: #fff !important;
}
.@{prefix-cls}__item--icon {
transition: all 0.38s ease-out;
}
.@{prefix-cls}__item--peoples {
background: #40c9c6;
}
.@{prefix-cls}__item--message {
background: #36a3f7;
}
.@{prefix-cls}__item--money {
background: #f4516c;
}
.@{prefix-cls}__item--shopping {
background: #34bfa3;
}
}
}
}
</style>

View File

@ -1,310 +0,0 @@
import { EChartsOption } from 'echarts'
import { EChartsOption as EChartsWordOption } from 'echarts-wordcloud'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
export const lineOptions: EChartsOption = {
title: {
text: t('analysis.monthlySales'),
left: 'center'
},
xAxis: {
data: [
t('analysis.january'),
t('analysis.february'),
t('analysis.march'),
t('analysis.april'),
t('analysis.may'),
t('analysis.june'),
t('analysis.july'),
t('analysis.august'),
t('analysis.september'),
t('analysis.october'),
t('analysis.november'),
t('analysis.december')
],
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 20,
right: 20,
bottom: 20,
top: 80,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: [t('analysis.estimate'), t('analysis.actual')],
top: 50
},
series: [
{
name: t('analysis.estimate'),
smooth: true,
type: 'line',
data: [100, 120, 161, 134, 105, 160, 165, 114, 163, 185, 118, 123],
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: t('analysis.actual'),
smooth: true,
type: 'line',
itemStyle: {},
data: [120, 82, 91, 154, 162, 140, 145, 250, 134, 56, 99, 123],
animationDuration: 2800,
animationEasing: 'quadraticOut'
}
]
}
export const pieOptions: EChartsOption = {
title: {
text: t('analysis.userAccessSource'),
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
data: [
t('analysis.directAccess'),
t('analysis.mailMarketing'),
t('analysis.allianceAdvertising'),
t('analysis.videoAdvertising'),
t('analysis.searchEngines')
]
},
series: [
{
name: t('analysis.userAccessSource'),
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: [
{ value: 335, name: t('analysis.directAccess') },
{ value: 310, name: t('analysis.mailMarketing') },
{ value: 234, name: t('analysis.allianceAdvertising') },
{ value: 135, name: t('analysis.videoAdvertising') },
{ value: 1548, name: t('analysis.searchEngines') }
]
}
]
}
export const barOptions: EChartsOption = {
title: {
text: t('analysis.weeklyUserActivity'),
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: 50,
right: 20,
bottom: 20
},
xAxis: {
type: 'category',
data: [
t('analysis.monday'),
t('analysis.tuesday'),
t('analysis.wednesday'),
t('analysis.thursday'),
t('analysis.friday'),
t('analysis.saturday'),
t('analysis.sunday')
],
axisTick: {
alignWithLabel: true
}
},
yAxis: {
type: 'value'
},
series: [
{
name: t('analysis.activeQuantity'),
data: [13253, 34235, 26321, 12340, 24643, 1322, 1324],
type: 'bar'
}
]
}
export const radarOption: EChartsOption = {
legend: {
data: [t('workplace.personal'), t('workplace.team')]
},
radar: {
// shape: 'circle',
indicator: [
{ name: t('workplace.quote'), max: 65 },
{ name: t('workplace.contribution'), max: 160 },
{ name: t('workplace.hot'), max: 300 },
{ name: t('workplace.yield'), max: 130 },
{ name: t('workplace.follow'), max: 100 }
]
},
series: [
{
name: `xxx${t('workplace.index')}`,
type: 'radar',
data: [
{
value: [42, 30, 20, 35, 80],
name: t('workplace.personal')
},
{
value: [50, 140, 290, 100, 90],
name: t('workplace.team')
}
]
}
]
}
export const wordOptions: EChartsWordOption = {
series: [
{
type: 'wordCloud',
gridSize: 2,
sizeRange: [12, 50],
rotationRange: [-90, 90],
shape: 'pentagon',
width: 600,
height: 400,
drawOutOfBound: true,
textStyle: {
color: function () {
return (
'rgb(' +
[
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 160)
].join(',') +
')'
)
}
},
emphasis: {
textStyle: {
shadowBlur: 10,
shadowColor: '#333'
}
},
data: [
{
name: 'Sam S Club',
value: 10000,
textStyle: {
color: 'black'
},
emphasis: {
textStyle: {
color: 'red'
}
}
},
{
name: 'Macys',
value: 6181
},
{
name: 'Amy Schumer',
value: 4386
},
{
name: 'Jurassic World',
value: 4055
},
{
name: 'Charter Communications',
value: 2467
},
{
name: 'Chick Fil A',
value: 2244
},
{
name: 'Planet Fitness',
value: 1898
},
{
name: 'Pitch Perfect',
value: 1484
},
{
name: 'Express',
value: 1112
},
{
name: 'Home',
value: 965
},
{
name: 'Johnny Depp',
value: 847
},
{
name: 'Lena Dunham',
value: 582
},
{
name: 'Lewis Hamilton',
value: 555
},
{
name: 'KXAN',
value: 550
},
{
name: 'Mary Ellen Mark',
value: 462
},
{
name: 'Farrah Abraham',
value: 366
},
{
name: 'Rita Ora',
value: 360
},
{
name: 'Serena Williams',
value: 282
},
{
name: 'NCAA baseball tournament',
value: 273
},
{
name: 'Point Break',
value: 265
}
]
}
]
}

View File

@ -1,12 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { LoginForm, RegisterForm } from './components' import { LoginForm } from './components'
import { ThemeSwitch } from '@/components/ThemeSwitch' import { ThemeSwitch } from '@/components/ThemeSwitch'
import { LocaleDropdown } from '@/components/LocaleDropdown' import { LocaleDropdown } from '@/components/LocaleDropdown'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { underlineToHump } from '@/utils' import { underlineToHump } from '@/utils'
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign' import { useDesign } from '@/hooks/web/useDesign'
import { ref } from 'vue'
const { getPrefixCls } = useDesign() const { getPrefixCls } = useDesign()
@ -15,16 +14,6 @@ const prefixCls = getPrefixCls('login')
const appStore = useAppStore() const appStore = useAppStore()
const { t } = useI18n() const { t } = useI18n()
const isLogin = ref(true)
const toRegister = () => {
isLogin.value = false
}
const toLogin = () => {
isLogin.value = true
}
</script> </script>
<template> <template>
@ -70,16 +59,7 @@ const toLogin = () => {
<div <div
class="h-full flex items-center m-auto w-[100%] @2xl:max-w-500px @xl:max-w-500px @md:max-w-500px @lg:max-w-500px" class="h-full flex items-center m-auto w-[100%] @2xl:max-w-500px @xl:max-w-500px @md:max-w-500px @lg:max-w-500px"
> >
<LoginForm <LoginForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
v-if="isLogin"
class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)"
@to-register="toRegister"
/>
<RegisterForm
v-else
class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)"
@to-login="toLogin"
/>
</div> </div>
</Transition> </Transition>
</div> </div>

View File

@ -155,11 +155,6 @@ const getMenu = async () => {
push({ path: redirect.value || permissionStore.addRouters[0].path }) push({ path: redirect.value || permissionStore.addRouters[0].path })
} }
} }
//
const toRegister = () => {
emit('to-register')
}
</script> </script>
<template> <template>
@ -189,11 +184,6 @@ const toRegister = () => {
{{ t('login.login') }} {{ t('login.login') }}
</ElButton> </ElButton>
</div> </div>
<div class="w-[100%] mt-15px">
<ElButton class="w-[100%]" @click="toRegister">
{{ t('login.register') }}
</ElButton>
</div>
</template> </template>
<template #otherIcon> <template #otherIcon>

View File

@ -1,144 +0,0 @@
<script setup lang="ts">
import { Form } from '@/components/Form'
import { reactive, ref, unref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { useForm } from '@/hooks/web/useForm'
import { ElButton, ElInput, FormRules } from 'element-plus'
import { useValidator } from '@/hooks/web/useValidator'
const emit = defineEmits(['to-login'])
const { register, elFormRef } = useForm()
const { t } = useI18n()
const { required } = useValidator()
const schema = reactive<FormSchema[]>([
{
field: 'title',
colProps: {
span: 24
}
},
{
field: 'username',
label: t('login.username'),
value: '',
component: 'Input',
colProps: {
span: 24
},
componentProps: {
placeholder: t('login.usernamePlaceholder')
}
},
{
field: 'password',
label: t('login.password'),
value: '',
component: 'InputPassword',
colProps: {
span: 24
},
componentProps: {
style: {
width: '100%'
},
strength: true,
placeholder: t('login.passwordPlaceholder')
}
},
{
field: 'check_password',
label: t('login.checkPassword'),
value: '',
component: 'InputPassword',
colProps: {
span: 24
},
componentProps: {
style: {
width: '100%'
},
strength: true,
placeholder: t('login.passwordPlaceholder')
}
},
{
field: 'code',
label: t('login.code'),
colProps: {
span: 24
}
},
{
field: 'register',
colProps: {
span: 24
}
}
])
const rules: FormRules = {
username: [required()],
password: [required()],
check_password: [required()],
code: [required()]
}
const toLogin = () => {
emit('to-login')
}
const loading = ref(false)
const loginRegister = async () => {
const formRef = unref(elFormRef)
formRef?.validate(async (valid) => {
if (valid) {
try {
loading.value = true
toLogin()
} finally {
loading.value = false
}
}
})
}
</script>
<template>
<Form
:schema="schema"
:rules="rules"
label-position="top"
hide-required-asterisk
size="large"
class="dark:(border-1 border-[var(--el-border-color)] border-solid)"
@register="register"
>
<template #title>
<h2 class="text-2xl font-bold text-center w-[100%]">{{ t('login.register') }}</h2>
</template>
<template #code="form">
<div class="w-[100%] flex">
<ElInput v-model="form['code']" :placeholder="t('login.codePlaceholder')" />
</div>
</template>
<template #register>
<div class="w-[100%]">
<ElButton type="primary" class="w-[100%]" :loading="loading" @click="loginRegister">
{{ t('login.register') }}
</ElButton>
</div>
<div class="w-[100%] mt-15px">
<ElButton class="w-[100%]" @click="toLogin">
{{ t('login.hasUser') }}
</ElButton>
</div>
</template>
</Form>
</template>

View File

@ -1,4 +1,3 @@
import LoginForm from './LoginForm.vue' import LoginForm from './LoginForm.vue'
import RegisterForm from './RegisterForm.vue'
export { LoginForm, RegisterForm } export { LoginForm }

View File

@ -1,6 +1,5 @@
import { ElTag } from 'element-plus' import { ElTag } from 'element-plus'
import { h, reactive } from 'vue' import { h, reactive } from 'vue'
import { getDictTypeOptionsApi } from '@/api/vadmin/system/dict'
export const columns = reactive<TableColumn[]>([ export const columns = reactive<TableColumn[]>([
{ {
@ -135,9 +134,6 @@ export const schema = reactive<FormSchema[]>([
} }
]) ])
const res = await getDictTypeOptionsApi()
const data = res.data
export const searchSchema = reactive<FormSchema[]>([ export const searchSchema = reactive<FormSchema[]>([
{ {
field: 'label', field: 'label',
@ -152,7 +148,6 @@ export const searchSchema = reactive<FormSchema[]>([
label: '字典类型', label: '字典类型',
component: 'Select', component: 'Select',
componentProps: { componentProps: {
options: data,
optionsAlias: { optionsAlias: {
labelField: 'dict_name', labelField: 'dict_name',
valueField: 'id' valueField: 'id'

View File

@ -6,7 +6,8 @@ import {
addDictDetailsListApi, addDictDetailsListApi,
delDictDetailsListApi, delDictDetailsListApi,
putDictDetailsListApi, putDictDetailsListApi,
getDictDetailsApi getDictDetailsApi,
getDictTypeOptionsApi
} from '@/api/vadmin/system/dict' } from '@/api/vadmin/system/dict'
import { useTable } from '@/hooks/web/useTable' import { useTable } from '@/hooks/web/useTable'
import { columns, searchSchema } from './components/detail.data' import { columns, searchSchema } from './components/detail.data'
@ -24,10 +25,21 @@ const { t } = useI18n()
let dictType = currentRoute.value.query.dictType let dictType = currentRoute.value.query.dictType
const searchSetSchemaList = [] as FormSetPropsType[] const searchSetSchemaList = ref([] as FormSetPropsType[])
const getOptions = async () => {
const res = await getDictTypeOptionsApi()
searchSetSchemaList.value.push({
field: 'dict_type_id',
path: 'componentProps.options',
value: res.data
})
}
getOptions()
if (typeof dictType === 'string') { if (typeof dictType === 'string') {
searchSetSchemaList.push({ searchSetSchemaList.value.push({
field: 'dict_type_id', field: 'dict_type_id',
path: 'value', path: 'value',
value: parseInt(dictType) value: parseInt(dictType)

View File

@ -227,11 +227,49 @@ vim /etc/nginx/conf.d/kinit.conf
内容如下: 内容如下:
```nginx ```nginx
# 如果需要使用搭配小程序使用则需要配置api的访问域名并配置域名证书
server
{
listen 80;
listen 443 ssl http2;
server_name 127.0.0.1;
root /opt/project/kinit/kinit-api/;
keepalive_timeout 180s;
client_max_body_size 20m;
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
#HTTP_TO_HTTPS_END
ssl_certificate /etc/nginx/conf.d/cert/kinit/kinit.pem;
ssl_certificate_key /etc/nginx/conf.d/cert/kinit/kinit.key;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
location ~ \.well-known{
allow all;
}
location /api/ {
rewrite ^/api/(.*) /$1 break;
}
location / {
proxy_pass http://127.0.0.1:9000;
}
access_log /opt/logs/kinit.api.nginx.log;
error_log /opt/logs/kinit.api.nginx.error.log;
}
server server
{ {
listen 80; listen 80;
server_name 127.0.0.1; server_name 127.0.0.1;
root /opt/project/kinit/kinit-admin/dist/; root /opt/project/kinit/kinit-admin/dist-pro/;
keepalive_timeout 180s; keepalive_timeout 180s;
client_max_body_size 20m; client_max_body_size 20m;
@ -241,7 +279,7 @@ server
} }
location / { location / {
try_files $uri $uri/ @router; try_files $uri $uri/ @router;
root /opt/project/kinit/kinit-admin/dist/; root /opt/project/kinit/kinit-admin/dist-pro/;
index index.html; index index.html;
} }
location /api/ { location /api/ {
@ -253,8 +291,8 @@ server
rewrite ^.*$ /index.html break; rewrite ^.*$ /index.html break;
} }
access_log /opt/logs/kinit.log; access_log /opt/logs/kinit.nginx.log;
error_log /opt/logs/kinit.log; error_log /opt/logs/kinit.nginx.error.log;
} }
``` ```