diff --git a/src/components/customPic/index.vue b/src/components/customPic/index.vue
new file mode 100644
index 0000000..6382230
--- /dev/null
+++ b/src/components/customPic/index.vue
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
diff --git a/src/components/exportExcel/exportExcel.vue b/src/components/exportExcel/exportExcel.vue
new file mode 100644
index 0000000..26ceb18
--- /dev/null
+++ b/src/components/exportExcel/exportExcel.vue
@@ -0,0 +1,58 @@
+
+ 导出
+
+
+
diff --git a/src/components/exportExcel/exportTemplate.vue b/src/components/exportExcel/exportTemplate.vue
new file mode 100644
index 0000000..9e099eb
--- /dev/null
+++ b/src/components/exportExcel/exportTemplate.vue
@@ -0,0 +1,28 @@
+
+ 下载模板
+
+
+
diff --git a/src/components/exportExcel/importExcel.vue b/src/components/exportExcel/importExcel.vue
new file mode 100644
index 0000000..30eef29
--- /dev/null
+++ b/src/components/exportExcel/importExcel.vue
@@ -0,0 +1,40 @@
+
+
+ 导入
+
+
+
+
+
diff --git a/src/components/office/docx.vue b/src/components/office/docx.vue
new file mode 100644
index 0000000..35e3e5a
--- /dev/null
+++ b/src/components/office/docx.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
diff --git a/src/components/office/excel.vue b/src/components/office/excel.vue
new file mode 100644
index 0000000..ac449da
--- /dev/null
+++ b/src/components/office/excel.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/office/index.vue b/src/components/office/index.vue
new file mode 100644
index 0000000..a6704d6
--- /dev/null
+++ b/src/components/office/index.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/office/pdf.vue b/src/components/office/pdf.vue
new file mode 100644
index 0000000..8098f06
--- /dev/null
+++ b/src/components/office/pdf.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/richtext/rich-edit.vue b/src/components/richtext/rich-edit.vue
new file mode 100644
index 0000000..cee3b2e
--- /dev/null
+++ b/src/components/richtext/rich-edit.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/richtext/rich-view.vue b/src/components/richtext/rich-view.vue
new file mode 100644
index 0000000..fd6616e
--- /dev/null
+++ b/src/components/richtext/rich-view.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/selectFile/selectFile.vue b/src/components/selectFile/selectFile.vue
new file mode 100644
index 0000000..c85b652
--- /dev/null
+++ b/src/components/selectFile/selectFile.vue
@@ -0,0 +1,85 @@
+
+
+
+ 上传文件
+
+
+
+
+
+
diff --git a/src/components/selectImage/selectImage.vue b/src/components/selectImage/selectImage.vue
new file mode 100644
index 0000000..a08393d
--- /dev/null
+++ b/src/components/selectImage/selectImage.vue
@@ -0,0 +1,485 @@
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+ 上传
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/svgIcon/svgIcon.vue b/src/components/svgIcon/svgIcon.vue
new file mode 100644
index 0000000..c6f7665
--- /dev/null
+++ b/src/components/svgIcon/svgIcon.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/src/components/upload/common.vue b/src/components/upload/common.vue
new file mode 100644
index 0000000..6234917
--- /dev/null
+++ b/src/components/upload/common.vue
@@ -0,0 +1,75 @@
+
+
+
+ 普通上传
+
+
+
+
+
+
diff --git a/src/components/upload/image.vue b/src/components/upload/image.vue
new file mode 100644
index 0000000..e643fa8
--- /dev/null
+++ b/src/components/upload/image.vue
@@ -0,0 +1,97 @@
+
+
+
+
+ 压缩上传
+
+
+
+
+
+
+
diff --git a/src/components/warningBar/warningBar.vue b/src/components/warningBar/warningBar.vue
new file mode 100644
index 0000000..1a88c1e
--- /dev/null
+++ b/src/components/warningBar/warningBar.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ {{ title }}
+
+
+
+
diff --git a/src/core/admin.js b/src/core/admin.js
new file mode 100644
index 0000000..4cd23b7
--- /dev/null
+++ b/src/core/admin.js
@@ -0,0 +1,12 @@
+/*
+ * web框架组
+ *
+ * */
+// 加载网站配置文件夹
+import { register } from './global'
+
+export default {
+ install: (app) => {
+ register(app)
+ }
+}
diff --git a/src/core/config.js b/src/core/config.js
new file mode 100644
index 0000000..72f1281
--- /dev/null
+++ b/src/core/config.js
@@ -0,0 +1,16 @@
+/**
+ * 网站配置文件
+ */
+
+const config = {
+ appName: '利农天下',
+ appLogo: '',
+ showViteLogo: true,
+ logs: [],
+}
+
+export const viteLogo = (env) => {
+ console.log('哈哈哈')
+}
+
+export default config
diff --git a/src/core/global.js b/src/core/global.js
new file mode 100644
index 0000000..212f6ca
--- /dev/null
+++ b/src/core/global.js
@@ -0,0 +1,44 @@
+import config from './config'
+import { h } from 'vue'
+
+// 统一导入el-icon图标
+import * as ElIconModules from '@element-plus/icons-vue'
+import svgIcon from '@/components/svgIcon/svgIcon.vue'
+// 导入转换图标名称的函数
+
+const createIconComponent = (name) => ({
+ name: 'SvgIcon',
+ render() {
+ return h(svgIcon, {
+ name: name,
+ })
+ },
+})
+
+const registerIcons = async (app) => {
+ const iconModules = import.meta.glob('@/assets/icons/**/*.svg')
+ for (const path in iconModules) {
+ const iconName = path.split('/').pop().replace(/\.svg$/, '')
+ // 如果iconName带空格则不加入到图标库中并且提示名称不合法
+ if (iconName.indexOf(' ') !== -1) {
+ console.error(`icon ${iconName}.svg includes whitespace`)
+ continue
+ }
+ const iconComponent = createIconComponent(iconName)
+ config.logs.push({
+ 'key': iconName,
+ 'label': iconName,
+ })
+ app.component(iconName, iconComponent)
+ }
+}
+
+export const register = (app) => {
+ // 统一注册el-icon图标
+ for (const iconName in ElIconModules) {
+ app.component(iconName, ElIconModules[iconName])
+ }
+ app.component('SvgIcon', svgIcon)
+ registerIcons(app)
+ app.config.globalProperties.$GIN_VUE_ADMIN = config
+}
diff --git a/src/directive/auth.js b/src/directive/auth.js
new file mode 100644
index 0000000..50594d4
--- /dev/null
+++ b/src/directive/auth.js
@@ -0,0 +1,41 @@
+// 权限按钮展示指令
+import { useUserStore } from '@/pinia/modules/user'
+export default {
+ install: (app) => {
+ const userStore = useUserStore()
+ app.directive('auth', {
+ // 当被绑定的元素插入到 DOM 中时……
+ mounted: function(el, binding) {
+ const userInfo = userStore.userInfo
+ let type = ''
+ switch (Object.prototype.toString.call(binding.value)) {
+ case '[object Array]':
+ type = 'Array'
+ break
+ case '[object String]':
+ type = 'String'
+ break
+ case '[object Number]':
+ type = 'Number'
+ break
+ default:
+ type = ''
+ break
+ }
+ if (type === '') {
+ el.parentNode.removeChild(el)
+ return
+ }
+ const waitUse = binding.value.toString().split(',')
+ let flag = waitUse.some(item => Number(item) === userInfo.authorityId)
+ if (binding.modifiers.not) {
+ flag = !flag
+ }
+ if (!flag) {
+ el.parentNode.removeChild(el)
+ }
+ }
+ })
+ }
+}
+
diff --git a/src/hooks/use-windows-resize.js b/src/hooks/use-windows-resize.js
new file mode 100644
index 0000000..4ddf3f0
--- /dev/null
+++ b/src/hooks/use-windows-resize.js
@@ -0,0 +1,23 @@
+// 监听 window 的 resize 事件,返回当前窗口的宽高
+import { shallowRef } from 'vue'
+import { tryOnMounted, useEventListener } from '@vueuse/core'
+
+const width = shallowRef(0)
+const height = shallowRef(0)
+
+export const useWindowResize = (cb) => {
+ const onResize = () => {
+ width.value = window.innerWidth
+ height.value = window.innerHeight
+ if (cb && typeof cb === 'function') {
+ cb(width.value, height.value)
+ }
+ }
+
+ tryOnMounted(onResize)
+ useEventListener('resize', onResize, { passive: true })
+ return {
+ width,
+ height,
+ }
+}
diff --git a/src/pinia/index.js b/src/pinia/index.js
new file mode 100644
index 0000000..a6063cf
--- /dev/null
+++ b/src/pinia/index.js
@@ -0,0 +1,7 @@
+import { createPinia } from 'pinia'
+
+const store = createPinia()
+
+export {
+ store
+}
diff --git a/src/pinia/modules/dictionary.js b/src/pinia/modules/dictionary.js
new file mode 100644
index 0000000..cd88f8c
--- /dev/null
+++ b/src/pinia/modules/dictionary.js
@@ -0,0 +1,40 @@
+import { findSysDictionary } from '@/api/sysDictionary'
+
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+export const useDictionaryStore = defineStore('dictionary', () => {
+ const dictionaryMap = ref({})
+
+ const setDictionaryMap = (dictionaryRes) => {
+ dictionaryMap.value = { ...dictionaryMap.value, ...dictionaryRes }
+ }
+
+ const getDictionary = async(type) => {
+ if (dictionaryMap.value[type] && dictionaryMap.value[type].length) {
+ return dictionaryMap.value[type]
+ } else {
+ const res = await findSysDictionary({ type })
+ if (res.code === 0) {
+ const dictionaryRes = {}
+ const dict = []
+ res.data.resysDictionary.sysDictionaryDetails && res.data.resysDictionary.sysDictionaryDetails.forEach(item => {
+ dict.push({
+ label: item.label,
+ value: item.value,
+ extend: item.extend
+ })
+ })
+ dictionaryRes[res.data.resysDictionary.type] = dict
+ setDictionaryMap(dictionaryRes)
+ return dictionaryMap.value[type]
+ }
+ }
+ }
+
+ return {
+ dictionaryMap,
+ setDictionaryMap,
+ getDictionary
+ }
+})
diff --git a/src/pinia/modules/router.js b/src/pinia/modules/router.js
new file mode 100644
index 0000000..36b9ec0
--- /dev/null
+++ b/src/pinia/modules/router.js
@@ -0,0 +1,103 @@
+import { asyncRouterHandle } from '@/utils/asyncRouter'
+import { emitter } from '@/utils/bus.js'
+import { asyncMenu } from '@/api/menu'
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+const notLayoutRouterArr = []
+const keepAliveRoutersArr = []
+const nameMap = {}
+
+const formatRouter = (routes, routeMap, parent) => {
+ routes && routes.forEach(item => {
+ item.parent = parent
+ item.meta.btns = item.btns
+ item.meta.hidden = item.hidden
+ if (item.meta.defaultMenu === true) {
+ if (!parent) {
+ item = { ...item, path: `/${item.path}` }
+ notLayoutRouterArr.push(item)
+ }
+ }
+ routeMap[item.name] = item
+ if (item.children && item.children.length > 0) {
+ formatRouter(item.children, routeMap, item)
+ }
+ })
+}
+
+const KeepAliveFilter = (routes) => {
+ routes && routes.forEach(item => {
+ // 子菜单中有 keep-alive 的,父菜单也必须 keep-alive,否则无效。这里将子菜单中有 keep-alive 的父菜单也加入。
+ if ((item.children && item.children.some(ch => ch.meta.keepAlive) || item.meta.keepAlive)) {
+ item.component && item.component().then(val => {
+ keepAliveRoutersArr.push(val.default.name)
+ nameMap[item.name] = val.default.name
+ })
+ }
+ if (item.children && item.children.length > 0) {
+ KeepAliveFilter(item.children)
+ }
+ })
+}
+
+export const useRouterStore = defineStore('router', () => {
+ const keepAliveRouters = ref([])
+ const asyncRouterFlag = ref(0)
+ const setKeepAliveRouters = (history) => {
+ const keepArrTemp = []
+ history.forEach(item => {
+ if (nameMap[item.name]) {
+ keepArrTemp.push(nameMap[item.name])
+ }
+ })
+ keepAliveRouters.value = Array.from(new Set(keepArrTemp))
+ }
+ emitter.on('setKeepAlive', setKeepAliveRouters)
+
+ const asyncRouters = ref([])
+ const routeMap = ({})
+ // 从后台获取动态路由
+ const SetAsyncRouter = async() => {
+ asyncRouterFlag.value++
+ const baseRouter = [{
+ path: '/layout',
+ name: 'layout',
+ component: 'view/layout/index.vue',
+ meta: {
+ title: '底层layout'
+ },
+ children: []
+ }]
+ const asyncRouterRes = await asyncMenu()
+ const asyncRouter = asyncRouterRes.data.menus
+ asyncRouter && asyncRouter.push({
+ path: 'reload',
+ name: 'Reload',
+ hidden: true,
+ meta: {
+ title: '',
+ closeTab: true,
+ },
+ component: 'view/error/reload.vue'
+ })
+ formatRouter(asyncRouter, routeMap)
+ baseRouter[0].children = asyncRouter
+ if (notLayoutRouterArr.length !== 0) {
+ baseRouter.push(...notLayoutRouterArr)
+ }
+ asyncRouterHandle(baseRouter)
+ KeepAliveFilter(asyncRouter)
+ asyncRouters.value = baseRouter
+ return true
+ }
+
+ return {
+ asyncRouters,
+ keepAliveRouters,
+ asyncRouterFlag,
+ SetAsyncRouter,
+ routeMap
+ }
+})
+
diff --git a/src/pinia/modules/user.js b/src/pinia/modules/user.js
new file mode 100644
index 0000000..7ec2b58
--- /dev/null
+++ b/src/pinia/modules/user.js
@@ -0,0 +1,162 @@
+import { login, getUserInfo, setSelfInfo } from '@/api/user'
+import { jsonInBlacklist } from '@/api/jwt'
+import router from '@/router/index'
+import { ElLoading, ElMessage } from 'element-plus'
+import { defineStore } from 'pinia'
+import { ref, computed, watch } from 'vue'
+import { useRouterStore } from './router'
+import cookie from 'js-cookie'
+
+export const useUserStore = defineStore('user', () => {
+ const loadingInstance = ref(null)
+
+ const userInfo = ref({
+ uuid: '',
+ nickName: '',
+ headerImg: '',
+ authority: {},
+ sideMode: 'dark',
+ activeColor: 'var(--el-color-primary)',
+ baseColor: '#fff'
+ })
+ const token = ref(window.localStorage.getItem('token') || cookie.get('x-token') || '')
+ const setUserInfo = (val) => {
+ userInfo.value = val
+ }
+
+ const setToken = (val) => {
+ token.value = val
+ }
+
+ const NeedInit = () => {
+ token.value = ''
+ window.localStorage.removeItem('token')
+ router.push({ name: 'Init', replace: true })
+ }
+
+ const ResetUserInfo = (value = {}) => {
+ userInfo.value = {
+ ...userInfo.value,
+ ...value
+ }
+ }
+ /* 获取用户信息*/
+ const GetUserInfo = async() => {
+ const res = await getUserInfo()
+ if (res.code === 0) {
+ setUserInfo(res.data.userInfo)
+ }
+ return res
+ }
+ /* 登录*/
+ const LoginIn = async(loginInfo) => {
+ loadingInstance.value = ElLoading.service({
+ fullscreen: true,
+ text: '登录中,请稍候...',
+ })
+ try {
+ const res = await login(loginInfo)
+ if (res.code === 0) {
+ setUserInfo(res.data.user)
+ setToken(res.data.token)
+ const routerStore = useRouterStore()
+ await routerStore.SetAsyncRouter()
+ const asyncRouters = routerStore.asyncRouters
+ asyncRouters.forEach(asyncRouter => {
+ router.addRoute(asyncRouter)
+ })
+
+ if (!router.hasRoute(userInfo.value.authority.defaultRouter)) {
+ ElMessage.error('请联系管理员进行授权')
+ } else {
+ await router.replace({ name: userInfo.value.authority.defaultRouter })
+ }
+
+ loadingInstance.value.close()
+
+ const isWin = ref(/windows/i.test(navigator.userAgent))
+ if (isWin.value) {
+ window.localStorage.setItem('osType', 'WIN')
+ } else {
+ window.localStorage.setItem('osType', 'MAC')
+ }
+ return true
+ }
+ } catch (e) {
+ loadingInstance.value.close()
+ }
+ loadingInstance.value.close()
+ }
+ /* 登出*/
+ const LoginOut = async() => {
+ const res = await jsonInBlacklist()
+ if (res.code === 0) {
+ await ClearStorage()
+ router.push({ name: 'Login', replace: true })
+ window.location.reload()
+ }
+ }
+ /* 清理数据 */
+ const ClearStorage = async() => {
+ token.value = ''
+ sessionStorage.clear()
+ window.localStorage.removeItem('token')
+ cookie.remove('x-token')
+ }
+ /* 设置侧边栏模式*/
+ const changeSideMode = async(data) => {
+ const res = await setSelfInfo({ sideMode: data })
+ if (res.code === 0) {
+ userInfo.value.sideMode = data
+ ElMessage({
+ type: 'success',
+ message: '设置成功'
+ })
+ }
+ }
+
+ const mode = computed(() => userInfo.value.sideMode)
+ const sideMode = computed(() => {
+ if (userInfo.value.sideMode === 'dark') {
+ return '#191a23'
+ } else if (userInfo.value.sideMode === 'light') {
+ return '#fff'
+ } else {
+ return userInfo.value.sideMode
+ }
+ })
+ const baseColor = computed(() => {
+ if (userInfo.value.sideMode === 'dark') {
+ return '#fff'
+ } else if (userInfo.value.sideMode === 'light') {
+ return '#191a23'
+ } else {
+ return userInfo.value.baseColor
+ }
+ })
+ const activeColor = computed(() => {
+ return 'var(--el-color-primary)'
+ })
+
+ watch(() => token.value, () => {
+ window.localStorage.setItem('token', token.value)
+ })
+
+ return {
+ userInfo,
+ token,
+ NeedInit,
+ ResetUserInfo,
+ GetUserInfo,
+ LoginIn,
+ LoginOut,
+ changeSideMode,
+ mode,
+ sideMode,
+ setToken,
+ baseColor,
+ activeColor,
+ loadingInstance,
+ ClearStorage
+ }
+})
diff --git a/src/plugin/email/api/email.js b/src/plugin/email/api/email.js
new file mode 100644
index 0000000..590c862
--- /dev/null
+++ b/src/plugin/email/api/email.js
@@ -0,0 +1,30 @@
+import service from '@/utils/request'
+// @Tags System
+// @Summary 发送测试邮件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
+// @Router /email/emailTest [post]
+export const emailTest = (data) => {
+ return service({
+ url: '/email/emailTest',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags System
+// @Summary 发送邮件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Param data body email_response.Email true "发送邮件必须的参数"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
+// @Router /email/sendEmail [post]
+export const sendEmail = (data) => {
+ return service({
+ url: '/email/sendEmail',
+ method: 'post',
+ data
+ })
+}
+
diff --git a/src/plugin/email/view/index.vue b/src/plugin/email/view/index.vue
new file mode 100644
index 0000000..11d57e4
--- /dev/null
+++ b/src/plugin/email/view/index.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 发送测试邮件
+ 发送邮件
+
+
+
+
+
+
+
+
+
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..52d3763
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,31 @@
+import { createRouter, createWebHashHistory } from 'vue-router'
+
+const routes = [{
+ path: '/',
+ redirect: '/login'
+},
+{
+ path: '/init',
+ name: 'Init',
+ component: () => import('@/view/init/index.vue')
+},
+{
+ path: '/login',
+ name: 'Login',
+ component: () => import('@/view/login/index.vue')
+},
+{
+ path: '/:catchAll(.*)',
+ meta: {
+ closeTab: true,
+ },
+ component: () => import('@/view/error/index.vue')
+}
+]
+
+const router = createRouter({
+ history: createWebHashHistory(),
+ routes,
+})
+
+export default router
diff --git a/src/style/element/index.scss b/src/style/element/index.scss
new file mode 100644
index 0000000..40ef0df
--- /dev/null
+++ b/src/style/element/index.scss
@@ -0,0 +1,24 @@
+@forward 'element-plus/theme-chalk/src/common/var.scss' with (
+ $colors: (
+ 'white': #ffffff,
+ 'black': #000000,
+ 'primary': (
+ 'base': #4d70ff,
+ ),
+ 'success': (
+ 'base': #67c23a,
+ ),
+ 'warning': (
+ 'base': #e6a23c,
+ ),
+ 'danger': (
+ 'base': #f56c6c,
+ ),
+ 'error': (
+ 'base': #f56c6c,
+ ),
+ 'info': (
+ 'base': #909399,
+ ),
+ )
+);
diff --git a/src/style/element_visiable.scss b/src/style/element_visiable.scss
new file mode 100644
index 0000000..0210664
--- /dev/null
+++ b/src/style/element_visiable.scss
@@ -0,0 +1,42 @@
+@import '@/style/main.scss';
+
+.el-button {
+ font-weight: 400;
+ border-radius: 2px;
+}
+
+::-webkit-scrollbar {
+ @apply hidden;
+}
+
+
+.gva-search-box {
+ @apply p-6 pb-0.5 bg-white rounded mb-3;
+}
+
+.gva-form-box {
+ @apply p-6 bg-white rounded;
+}
+
+.gva-pagination {
+ @apply flex justify-end;
+ .el-pagination__editor {
+ .el-input__inner {
+ @apply h-8;
+ }
+ }
+
+ .is-active {
+ @apply rounded text-white;
+ background: var(--el-color-primary);
+ color: #ffffff !important;
+ }
+}
+
+
+.el-drawer__header{
+ margin-bottom: 0 !important;
+ padding-top: 16px !important;
+ padding-bottom: 16px !important;
+ @apply border-0 border-b border-solid border-gray-200;
+}
diff --git a/src/style/iconfont.css b/src/style/iconfont.css
new file mode 100644
index 0000000..bc091a0
--- /dev/null
+++ b/src/style/iconfont.css
@@ -0,0 +1,47 @@
+@font-face {
+ font-family: 'gvaIcon';
+ src: url('data:font/ttf;charset=utf-8;base64,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AAAAAAALABMBkAADAAEECQAAACYAAAADAAEECQABABAAPAADAAEECQACAA4AVwADAAEECQADABAAbwADAAEECQAEABAAigADAAEECQAFABYApQADAAEECQAGABAAyQADAAEECQAKAFYA5AADAAEECQALACYBaABDAHIAZQBhAHQAZQBkACAAYgB5ACAAaQBjAG8AbgBmAG8AbgB0AABDcmVhdGVkIGJ5IGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABWAGUAcgBzAGkAbwBuACAAMQAuADAAAFZlcnNpb24gMS4wAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAABHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuAABoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAABodHRwOi8vZm9udGVsbG8uY29tAAAAAAIAAAAAAAAACgAAAAAAAQAAAAAAAAAAAAAAAAAAAAAACwAAAAEAAgECAQMBBAEFAQYBBwEIAQkRYXJyb3ctZG91YmxlLWxlZnQSYXJyb3ctZG91YmxlLXJpZ2h0EGN1c3RvbWVyLXNlcnZpY2URZnVsbHNjcmVlbi1leHBhbmQRZnVsbHNjcmVlbi1zaHJpbmsGcHJvbXB0B3JlZnJlc2gGc2VhcmNoAAAAAf//AAIAAQAAAAwAAAAWAAAAAgABAAMACgABAAQAAAACAAAAAAAAAAEAAAAA1aQnCAAAAADeWFEjAAAAAN5YUSM=') format('truetype');
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+}
+.gvaIcon {
+ font-family: "gvaIcon" !important;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 800;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+
+.gvaIcon-arrow-double-left:before {
+ content: "\e665";
+ }
+
+.gvaIcon-arrow-double-right:before {
+ content: "\e666";
+}
+
+.gvaIcon-fullscreen-shrink:before {
+ content: "\e676";
+}
+.gvaIcon-customer-service:before {
+ content: "\e66a";
+ }
+
+.gvaIcon-fullscreen-expand:before {
+ content: "\e675";
+}
+
+.gvaIcon-prompt:before {
+ content: "\e67b";
+}
+
+.gvaIcon-refresh:before {
+ content: "\e67c";
+}
+
+.gvaIcon-search:before {
+ content: "\e67d";
+}
+
diff --git a/src/style/main.scss b/src/style/main.scss
new file mode 100644
index 0000000..d4865cf
--- /dev/null
+++ b/src/style/main.scss
@@ -0,0 +1,701 @@
+/* Document
+ ========================================================================== */
+
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+@import '@/style/iconfont.css';
+html {
+ line-height: 1.15;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+}
+
+
+/* Sections
+ ========================================================================== */
+
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+ display: block;
+}
+
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+
+/* Grouping content
+ ========================================================================== */
+
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box;
+ /* 1 */
+ height: 0;
+ /* 1 */
+ overflow: visible;
+ /* 2 */
+}
+
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace;
+ /* 1 */
+ font-size: 1em;
+ /* 2 */
+}
+
+
+/* Text-level semantics
+ ========================================================================== */
+
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ border-bottom: none;
+ /* 1 */
+ text-decoration: underline;
+ /* 2 */
+ text-decoration: underline dotted;
+ /* 2 */
+}
+
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace, monospace;
+ /* 1 */
+ font-size: 1em;
+ /* 2 */
+}
+
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+
+/* Embedded content
+ ========================================================================== */
+
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+ border-style: none;
+}
+
+
+/* Forms
+ ========================================================================== */
+
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ /* 1 */
+ font-size: 100%;
+ /* 1 */
+ line-height: 1.15;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+}
+
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input {
+ /* 1 */
+ overflow: visible;
+}
+
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select {
+ /* 1 */
+ text-transform: none;
+}
+
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+}
+
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+ padding: 0.35em 0.75em 0.625em;
+}
+
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+legend {
+ box-sizing: border-box;
+ /* 1 */
+ color: inherit;
+ /* 2 */
+ display: table;
+ /* 1 */
+ max-width: 100%;
+ /* 1 */
+ padding: 0;
+ /* 3 */
+ white-space: normal;
+ /* 1 */
+}
+
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+ box-sizing: border-box;
+ /* 1 */
+ padding: 0;
+ /* 2 */
+}
+
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ outline-offset: -2px;
+ /* 2 */
+}
+
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ /* 1 */
+ font: inherit;
+ /* 2 */
+}
+
+
+/* Interactive
+ ========================================================================== */
+
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+ display: block;
+}
+
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+
+/* Misc
+ ========================================================================== */
+
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+ display: none;
+}
+
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+ display: none;
+}
+
+HTML,
+body,
+div,
+ul,
+ol,
+dl,
+li,
+dt,
+dd,
+p,
+blockquote,
+pre,
+form,
+fieldset,
+table,
+th,
+td {
+ border: none;
+ font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
+ font-size: 14px;
+ margin: 0px;
+ padding: 0px;
+}
+
+html,
+body {
+ height: 100%;
+ width: 100%;
+}
+
+address,
+caption,
+cite,
+code,
+th,
+var {
+ font-style: normal;
+ font-weight: normal;
+}
+
+a {
+ text-decoration: none;
+}
+
+input::-ms-clear {
+ display: none;
+}
+
+input::-ms-reveal {
+ display: none;
+}
+
+input {
+ -webkit-appearance: none;
+ margin: 0;
+ outline: none;
+ padding: 0;
+}
+
+input::-webkit-input-placeholder {
+ color: #ccc;
+}
+
+input::-ms-input-placeholder {
+ color: #ccc;
+}
+
+input::-moz-placeholder {
+ color: #ccc;
+}
+
+input[type=submit],
+input[type=button] {
+ cursor: pointer;
+}
+
+button[disabled],
+input[disabled] {
+ cursor: default;
+}
+
+img {
+ border: none;
+}
+
+ul,
+ol,
+li {
+ list-style-type: none;
+}
+
+// 导航
+#app {
+ .el-container {
+ @apply relative h-full w-full;
+ }
+ .el-container.mobile.openside {
+ @apply fixed top-0;
+ }
+ .gva-aside {
+ @apply fixed top-0 left-0 z-[1001] overflow-hidden;
+ .el-menu {
+ @apply border-r-0;
+ }
+ }
+ .aside {
+ .el-menu--collapse {
+ >.el-menu-item {
+ display: flex;
+ justify-content: center;
+ }
+ }
+ .el-sub-menu {
+ .el-menu {
+ .is-active {
+ // 关闭三级菜单二级菜单样式
+ ul {
+ border: none;
+ }
+ }
+ // 关闭三级菜单二级菜单样式
+ .is-active.is-opened {
+ ul {
+ border: none;
+ }
+ }
+ }
+ }
+ }
+ .hideside {
+ .aside {
+ @apply w-[54px]
+ }
+ }
+
+ .mobile {
+ .gva-aside {
+ @apply w-[54px];
+ }
+ }
+
+ .hideside {
+ .main-cont.el-main {
+ @apply ml-[54px];
+ }
+ }
+ .mobile {
+ .main-cont.el-main {
+ @apply ml-0;
+ }
+ }
+}
+
+// layout
+
+.admin-box {
+ @apply min-h-[calc(100vh-200px)] px-3 py-4 mt-28 mb-4 mx-1;
+ .el-table {
+ th {
+ @apply px-0 py-2;
+ .cell {
+ @apply leading-[40px] text-gray-700;
+ }
+ }
+ td {
+ @apply px-0 py-2;
+ .cell {
+ @apply leading-[40px] text-gray-600;
+ }
+ }
+ .is-leaf {
+ @apply border-b border-t-0 border-l-0 border-solid border-gray-50;
+ border-right:var(--el-table-border);
+ background: #F7FBFF !important;
+ }
+ }
+}
+
+// table
+.el-pagination {
+ @apply mt-8;
+ .btn-prev,
+ .btn-next {
+ @apply border border-solid border-gray-300 rounded;
+ }
+ .el-pager {
+ li {
+ @apply border border-solid border-gray-300 rounded text-gray-600 text-sm mx-1;
+ }
+ }
+}
+
+
+.el-container.layout-cont {
+ .header-cont {
+ @apply px-4 h-16 bg-white;
+ }
+
+
+ .main-cont {
+ @apply h-screen overflow-visible;
+ &.el-main {
+ @apply min-h-full ml-[220px] bg-main p-0 overflow-auto;
+ }
+
+ .breadcrumb {
+ @apply h-16 flex items-center p-0 ml-12 text-lg;
+ .el-breadcrumb__item {
+ .el-breadcrumb__inner {
+ @apply text-gray-600;
+ }
+ }
+ .el-breadcrumb__item:nth-last-child(1) {
+ .el-breadcrumb__inner {
+ @apply text-gray-600;
+ }
+ }
+ }
+
+ .router-history {
+ @apply bg-white p-0 border-t border-l-0 border-r-0 border-b-0 border-solid border-gray-100;
+ .el-tabs__header {
+ @apply m-0;
+ .el-tabs__item{
+ @apply border-solid border-r border-t-0 border-gray-100 border-b-0 border-l-0;
+ }
+ .el-tabs__item.is-active {
+ @apply bg-blue-500 bg-opacity-5;
+ }
+ .el-tabs__nav {
+ @apply border-0;
+ }
+ }
+ }
+
+ .aside {
+ @apply overflow-auto;
+ }
+ .el-menu-vertical {
+ @apply h-[calc(100vh-60px)];
+ &:not(.el-menu--collapse) {
+ @apply w-[220px];
+ }
+ }
+ .el-menu--collapse {
+ @apply w-[54px];
+ li {
+ .el-tooltip,
+ .el-sub-menu__title {
+ @apply px-4;
+ }
+ }
+ }
+ }
+}
+
+.el-dropdown {
+ @apply overflow-hidden
+}
+
+.gva-table-box {
+ @apply p-6 bg-white rounded;
+}
+
+.gva-btn-list {
+ @apply mb-3 flex gap-3 items-center;
+}
+
+
+#nprogress .bar {
+ background: #29d !important;
+}
+.gva-customer-icon{
+ @apply w-4 h-4;
+}
+
+.el-form--inline {
+ .el-form-item {
+ & > .el-input, .el-cascader, .el-select, .el-date-editor, .el-autocomplete {
+ @apply w-52;
+ }
+ }
+}
diff --git a/src/utils/asyncRouter.js b/src/utils/asyncRouter.js
new file mode 100644
index 0000000..dfa62bb
--- /dev/null
+++ b/src/utils/asyncRouter.js
@@ -0,0 +1,31 @@
+const viewModules = import.meta.glob('../view/**/*.vue')
+const pluginModules = import.meta.glob('../plugin/**/*.vue')
+
+export const asyncRouterHandle = (asyncRouter) => {
+ asyncRouter.forEach(item => {
+ if (item.component && typeof item.component === 'string') {
+ if (item.component.split('/')[0] === 'view') {
+ item.component = dynamicImport(viewModules, item.component)
+ } else if (item.component.split('/')[0] === 'plugin') {
+ item.component = dynamicImport(pluginModules, item.component)
+ }
+ }
+ if (item.children) {
+ asyncRouterHandle(item.children)
+ }
+ })
+}
+
+function dynamicImport(
+ dynamicViewsModules,
+ component
+) {
+ const keys = Object.keys(dynamicViewsModules)
+ const matchKeys = keys.filter((key) => {
+ const k = key.replace('../', '')
+ return k === component
+ })
+ const matchKey = matchKeys[0]
+
+ return dynamicViewsModules[matchKey]
+}
diff --git a/src/utils/btnAuth.js b/src/utils/btnAuth.js
new file mode 100644
index 0000000..f94fa9b
--- /dev/null
+++ b/src/utils/btnAuth.js
@@ -0,0 +1,6 @@
+import { useRoute } from 'vue-router'
+import { reactive } from 'vue'
+export const useBtnAuth = () => {
+ const route = useRoute()
+ return route.meta.btns || reactive({})
+}
diff --git a/src/utils/format.js b/src/utils/format.js
index b052ac9..851b77c 100644
--- a/src/utils/format.js
+++ b/src/utils/format.js
@@ -24,12 +24,6 @@ export const formatOnlyDate = (time) => {
return ''
}
}
-export const formatPriceType = (priceType) => {
- switch (priceType) {
- case 1: return '出厂价'
- default: '未定义'
- }
-}
export const filterDict = (value, options) => {
const rowLabel = options && options.filter(item => item.value === value)
diff --git a/src/view/dashboard/index.vue b/src/view/dashboard/index.vue
index a92d8f9..ed6b422 100644
--- a/src/view/dashboard/index.vue
+++ b/src/view/dashboard/index.vue
@@ -6,14 +6,14 @@
早安,请开始一天的工作吧
{{ weatherInfo }}
-
+
{
ip()
return weatherInfo
}
-export const ip = async () => {
+export const ip = async() => {
// key换成你自己的 https://console.amap.com/dev/index
if (amapKey === '') {
return false
}
const res = await axios.get('https://restapi.amap.com/v3/ip?key=' + amapKey)
- var cityCode
- if (res.data.status !== '0') {
- cityCode = res.data.adcode
- } else {
- cityCode = '100000'
+ if (res.data.adcode) {
+ getWeather(res.data.adcode)
}
- getWeather(cityCode)
}
-const getWeather = async (code) => {
- const url = 'https://restapi.amap.com/v3/weather/weatherInfo?key=' + amapKey + '&extensions=base&city=' + code
- const response = await axios.get(url)
+const getWeather = async(code) => {
+ const response = await axios.get('https://restapi.amap.com/v3/weather/weatherInfo?key=' + amapKey + '&extensions=base&city=' + code)
if (response.data.status === '1') {
const s = response.data.lives[0]
weatherInfo.value = s.city + ' 天气:' + s.weather + ' 温度:' + s.temperature + '摄氏度 风向:' + s.winddirection + ' 风力:' + s.windpower + '级 空气湿度:' + s.humidity
}
}
+