Bladeren bron

some change

aexiaoliou 1 jaar geleden
bovenliggende
commit
f4b86609f3

+ 5 - 0
api/app/admin/controller/Test.php

@@ -16,4 +16,9 @@ class Test extends Base
         return Db::execute('SELECT 1');
     }
 
+    public function vir()
+    {
+        return getVirRootDir();
+    }
+
 }

+ 4 - 0
api/app/common.php

@@ -43,6 +43,10 @@ if (!function_exists('getVirRootDir')) {
      */
     function getVirRootDir()
     {
+        if (isset($_SERVER['HTTP_X_ORIGINAL_URI'])) {
+            $url = $_SERVER['HTTP_X_ORIGINAL_URI'];
+            return preg_replace('/index\.php.*/m', '', $url);
+        }
         $url = $_SERVER['SCRIPT_NAME'];
         $url = substr($url, 0, strripos($url, "/"));
         return $url;

+ 2 - 2
api/app/common/service/FileService.php

@@ -39,7 +39,7 @@ class FileService extends Service
     }
 
     /**
-     * 上传图片
+     * 上传附件
      * 本地运行如果无法写入图片可能是没有给public目录写权限
      * 
      * @param string $path 上传路径,默认为'default'
@@ -50,7 +50,7 @@ class FileService extends Service
         // 获取表单上传文件
         $files = request()->file();
         // 验证上传文件格式和大小
-        $this->validate($files, Validate::rule(['file' => 'fileSize:8388608|fileExt:pdf,doc,docx']));
+        $this->validate($files, Validate::rule(['file' => 'fileExt:pdf,doc,docx']));
         $file = request()->file('file');
         try {
             // 保存上传文件到public目录下的$path目录中

+ 83 - 75
h5/src/App.vue

@@ -1,100 +1,108 @@
 <template>
-	<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
-        <Suspense>
-            <router-view v-show="themeConfig.lockScreenTime > 1" />
-            <template #fallback>
-                <el-card>
-                    <el-empty description="Loading" />
-                </el-card>
+    <el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
+        <router-view v-show="themeConfig.lockScreenTime > 1" v-slot="{ Component }">
+            <template v-if="Component">
+                <Transition mode="out-in">
+                    <KeepAlive>
+                        <Suspense>
+                            <!-- 主要内容 -->
+                            <component :is="Component"></component>
+                            <!-- 加载中状态 -->
+                            <template #fallback>
+                                正在加载...
+                            </template>
+                        </Suspense>
+                    </KeepAlive>
+                </Transition>
             </template>
-        </Suspense>
-		<LockScreen v-if="themeConfig.isLockScreen" />
-		<Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
-		<CloseFull v-if="!themeConfig.isLockScreen" />
-		<!-- <Upgrade v-if="getVersion" /> -->
-	</el-config-provider>
+        </router-view>
+        <LockScreen v-if="themeConfig.isLockScreen" />
+        <Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
+        <CloseFull v-if="!themeConfig.isLockScreen" />
+        <!-- <Upgrade v-if="getVersion" /> -->
+    </el-config-provider>
 </template>
 
 <script setup lang="ts" name="app">
-import { defineAsyncComponent, computed, ref, onBeforeMount, onMounted, onUnmounted, nextTick, watch } from 'vue';
-import { useRoute } from 'vue-router';
-import { useI18n } from 'vue-i18n';
-import { storeToRefs } from 'pinia';
-import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
-import { useThemeConfig } from '/@/stores/themeConfig';
-import other from '/@/utils/other';
-import { Local, Session } from '/@/utils/storage';
-import mittBus from '/@/utils/mitt';
-import setIntroduction from '/@/utils/setIconfont';
+import { defineAsyncComponent, computed, ref, onBeforeMount, onMounted, onUnmounted, nextTick, watch } from 'vue'
+import { useRoute } from 'vue-router'
+import { useI18n } from 'vue-i18n'
+import { storeToRefs } from 'pinia'
+import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'
+import { useThemeConfig } from '/@/stores/themeConfig'
+import other from '/@/utils/other'
+import { Local, Session } from '/@/utils/storage'
+import mittBus from '/@/utils/mitt'
+import setIntroduction from '/@/utils/setIconfont'
 
 // 引入组件
-const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
-const Setings = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/setings.vue'));
-const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.vue'));
-const Upgrade = defineAsyncComponent(() => import('/@/layout/upgrade/index.vue'));
+const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'))
+const Setings = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/setings.vue'))
+const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.vue'))
+const Upgrade = defineAsyncComponent(() => import('/@/layout/upgrade/index.vue'))
 
 // 定义变量内容
-const { messages, locale } = useI18n();
-const setingsRef = ref();
-const route = useRoute();
-const stores = useTagsViewRoutes();
-const storesThemeConfig = useThemeConfig();
-const { themeConfig } = storeToRefs(storesThemeConfig);
+const { messages, locale } = useI18n()
+const setingsRef = ref()
+const route = useRoute()
+const stores = useTagsViewRoutes()
+const storesThemeConfig = useThemeConfig()
+const { themeConfig } = storeToRefs(storesThemeConfig)
 
 // 获取版本号
 const getVersion = computed(() => {
-	let isVersion = false;
-	if (route.path !== '/login') {
-		// @ts-ignore
-		if ((Local.get('version') && Local.get('version') !== __VERSION__) || !Local.get('version')) isVersion = true;
-	}
-	return isVersion;
-});
+    let isVersion = false
+    if (route.path !== '/login') {
+        // @ts-ignore
+        if ((Local.get('version') && Local.get('version') !== __VERSION__) || !Local.get('version')) isVersion = true
+    }
+    return isVersion
+})
 // 获取全局组件大小
 const getGlobalComponentSize = computed(() => {
-	return other.globalComponentSize();
-});
+    return other.globalComponentSize()
+})
 // 获取全局 i18n
 const getGlobalI18n = computed(() => {
-	return messages.value[locale.value];
-});
+    return messages.value[locale.value]
+})
 // 设置初始化,防止刷新时恢复默认
 onBeforeMount(() => {
-	// 设置批量第三方 icon 图标
-	setIntroduction.cssCdn();
-	// 设置批量第三方 js
-	setIntroduction.jsCdn();
-});
+    // 设置批量第三方 icon 图标
+    setIntroduction.cssCdn()
+    // 设置批量第三方 js
+    setIntroduction.jsCdn()
+})
 // 页面加载时
 onMounted(() => {
-	nextTick(() => {
-		// 监听布局配'置弹窗点击打开
-		mittBus.on('openSetingsDrawer', () => {
-			setingsRef.value.openDrawer();
-		});
-		// 获取缓存中的布局配置
-		if (Local.get('themeConfig')) {
-			storesThemeConfig.setThemeConfig({ themeConfig: Local.get('themeConfig') });
-			document.documentElement.style.cssText = Local.get('themeConfigStyle');
-		}
-		// 获取缓存中的全屏配置
-		if (Session.get('isTagsViewCurrenFull')) {
-			stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
-		}
-	});
-});
+    nextTick(() => {
+        // 监听布局配'置弹窗点击打开
+        mittBus.on('openSetingsDrawer', () => {
+            setingsRef.value.openDrawer()
+        })
+        // 获取缓存中的布局配置
+        if (Local.get('themeConfig')) {
+            storesThemeConfig.setThemeConfig({ themeConfig: Local.get('themeConfig') })
+            document.documentElement.style.cssText = Local.get('themeConfigStyle')
+        }
+        // 获取缓存中的全屏配置
+        if (Session.get('isTagsViewCurrenFull')) {
+            stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'))
+        }
+    })
+})
 // 页面销毁时,关闭监听布局配置/i18n监听
 onUnmounted(() => {
-	mittBus.off('openSetingsDrawer', () => {});
-});
+    mittBus.off('openSetingsDrawer', () => { })
+})
 // 监听路由的变化,设置网站标题
 watch(
-	() => route.path,
-	() => {
-		other.useTitle();
-	},
-	{
-		deep: true,
-	}
-);
+    () => route.path,
+    () => {
+        other.useTitle()
+    },
+    {
+        deep: true,
+    }
+)
 </script>

+ 9 - 0
h5/src/api/role/index.ts

@@ -37,6 +37,15 @@ export interface Role {
     delete_time?: Date | string
 }
 
+export const newRole = (): Role => {
+    return {
+        id: 0,
+        name: '',
+        remark: '',
+        valid: 1
+    }
+}
+
 export interface CodeTree {
     code: string
     cn: string

+ 65 - 0
h5/src/components/role/codes.vue

@@ -0,0 +1,65 @@
+<template>
+    <el-dialog :modelValue="modelValue" @close="$emit('update:modelValue', false)" title="编辑权限">
+        <el-tree-v2 ref="tree" :data="codes" :props="treeProps" :default-checked-keys="role?.codes" show-checkbox :height="500">
+            <template #default="{ node }">
+                <span>{{ node.data.lable }}</span>
+            </template>
+        </el-tree-v2>
+        <template #footer>
+            <el-button type="default" @click="$emit('update:modelValue', false)">取消</el-button>
+            <el-button v-loading="submitLoading" type="primary" @click="submitForm()">提交</el-button>
+        </template>
+    </el-dialog>
+</template>
+
+<script setup lang="ts">
+import { update, codes as getCodes } from '/@/api/role'
+import type { Role } from '/@/api/role'
+import { ref, onMounted } from 'vue'
+import type { ElTreeV2 } from 'element-plus'
+import { clone } from 'lodash'
+import { ElMessage } from 'element-plus'
+
+const { modelValue, role } = defineProps<{
+    modelValue: boolean,
+    role?: Role
+}>()
+const emit = defineEmits(['update:modelValue'])
+
+const codes = ref()
+
+const tree = ref()
+
+const submitLoading = ref(false)
+
+const treeProps = {
+    value: 'id',
+    label: 'label',
+    children: 'children',
+}
+
+onMounted(async () => {
+    codes.value = (await getCodes()).data
+})
+
+const submitForm = async () => {
+    const checkedCodes = tree.value?.getCheckedNodes(true).map(node => node.lable)
+    console.log("🚀 ~ file: edit.vue:43 ~ submitForm ~ checkedCodes:", checkedCodes)
+    const checkedKeys = tree.value?.getCheckedKeys()
+
+    const updateRole = clone(role) as Role
+    updateRole.codes = checkedKeys
+    updateRole.codes_cn = checkedCodes
+
+    submitLoading.value = true
+    const result = await update(updateRole)
+    if (result.code != 0) {
+        return
+    }
+    submitLoading.value = false
+    ElMessage({ message: '更新成功' })
+
+    emit('update:modelValue', false)
+}
+
+</script>

+ 17 - 37
h5/src/components/role/edit.vue

@@ -1,10 +1,16 @@
 <template>
     <el-dialog :modelValue="modelValue" @close="$emit('update:modelValue', false)" title="编辑权限">
-        <el-tree-v2 ref="tree" :data="codes" :props="treeProps" :default-checked-keys="role?.codes" show-checkbox>
-            <template #default="{ node }">
-                <span>{{ node.data.lable }}</span>
-            </template>
-        </el-tree-v2>
+        <el-form :model="role" lable-width="120px">
+            <el-form-item lable="名字">
+                <el-input v-model="role.name" />
+            </el-form-item>
+            <el-form-item lable="是否启用">
+                <el-switch v-model="role.valid" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+            <el-form-item lable="备注">
+                <el-input v-model="role.remark" type="textarea" />
+            </el-form-item>
+        </el-form>
         <template #footer>
             <el-button type="default" @click="$emit('update:modelValue', false)">取消</el-button>
             <el-button v-loading="submitLoading" type="primary" @click="submitForm()">提交</el-button>
@@ -13,46 +19,21 @@
 </template>
 
 <script setup lang="ts">
-import { update, codes as getCodes } from '/@/api/role'
-import type { Role, CodeTree } from '/@/api/role'
-import { ref, onMounted } from 'vue'
-import type { ElTreeV2 } from 'element-plus'
-import { clone } from 'lodash'
+import { ref } from 'vue'
+import { update } from '/@/api/role'
+import type { Role } from '/@/api/role'
 import { ElMessage } from 'element-plus'
 
 const { modelValue, role } = defineProps<{
     modelValue: boolean,
-    role?: Role
+    role: Role
 }>()
 const emit = defineEmits(['update:modelValue'])
-
-const codes = ref()
-
-const tree = ref()
-
 const submitLoading = ref(false)
 
-const treeProps = {
-    value: 'id',
-    label: 'label',
-    children: 'children',
-}
-
-onMounted(async () => {
-    codes.value = (await getCodes()).data
-})
-
 const submitForm = async () => {
-    const checkedCodes = tree.value?.getCheckedNodes(true).map(node => node.lable)
-    console.log("🚀 ~ file: edit.vue:43 ~ submitForm ~ checkedCodes:", checkedCodes)
-    const checkedKeys = tree.value?.getCheckedKeys()
-
-    const updateRole = clone(role) as Role
-    updateRole.codes = checkedKeys
-    updateRole.codes_cn = checkedCodes
-
     submitLoading.value = true
-    const result = await update(updateRole)
+    const result = await update(role)
     if (result.code != 0) {
         return
     }
@@ -61,5 +42,4 @@ const submitForm = async () => {
 
     emit('update:modelValue', false)
 }
-
-</script>
+</script>

+ 4 - 4
h5/src/router/route.ts

@@ -1,4 +1,4 @@
-import { RouteRecordRaw } from 'vue-router';
+import { RouteRecordRaw } from 'vue-router'
 
 /**
  * 建议:路由 path 路径与文件夹名称相同,找文件可浏览器地址找,方便定位文件位置
@@ -95,11 +95,11 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 						},
 					},
 					{
-						path: '/admin/adminrole',
-						name: 'adminRole',
+						path: '/admin/role',
+						name: 'role',
 						component: () => import('/@/views/admin/role/index.vue'),
 						meta: {
-							title: 'message.router.adminRole', //角色管理
+                            title: '角色管理', // 角色管理
 							isLink: '',
 							isHide: false,
 							isKeepAlive: true,

+ 5 - 0
h5/src/utils/component/suspense.tsx

@@ -0,0 +1,5 @@
+import { Suspense } from "vue"
+
+export const withSuspense = (component) => {
+    return () => <Suspense>{component}</Suspense>
+}

+ 3 - 0
h5/src/utils/use/useDialog.ts

@@ -0,0 +1,3 @@
+export const useDialog = () => {
+    
+}

+ 29 - 7
h5/src/views/admin/role/index.vue

@@ -1,5 +1,6 @@
 <template>
-    <Edit v-model="showCodesEditForm" :role="editRole"></Edit>
+    <Codes v-model="showCodesEditForm" :role="editRole" />
+    <Edit v-model="showRoleEditForm" :role="editRole" />
     <div>
         <el-card class="box-card" v-loading="wholeLoading" element-loading-text="Loading..." style="height: 600px">
             <template #header>
@@ -23,10 +24,11 @@
 <script lang="ts" setup name="underlyingRoleManage">
 import { ref, reactive, onMounted, h } from 'vue'
 import { ElSwitch, ElTag, ElMessage, ElMessageBox, ElButton, TableV2FixedDir, roleTypes } from 'element-plus'
-import type { Column, RowClassNameGetter } from 'element-plus'
+import type { Column } from 'element-plus'
 import { throttle } from 'lodash'
-import { init, update } from '/@/api/role'
+import { init, update, newRole } from '/@/api/role'
 import type { Role } from '/@/api/role'
+import Codes from '/@/components/role/codes.vue'
 import Edit from '/@/components/role/edit.vue'
 
 /**
@@ -41,8 +43,14 @@ const wholeLoading = ref(false)
  * 编辑权限表单的显示控制
  */
 const showCodesEditForm = ref(false)
-
-const editRole = ref<Role>()
+/**
+ * 编辑角色表单的显示控制
+ */
+const showRoleEditForm = ref(false)
+/**
+ * 需要编辑的角色
+ */
+const editRole = ref<Role>(newRole())
 
 /**
  * 虚拟表格列信息
@@ -107,12 +115,22 @@ const columns: Column<any>[] = [
                         type: 'primary',
                         onClick: throttle(() => {
                             showCodesEditForm.value = true
-                            console.log(showCodesEditForm)
                             editRole.value = row
                         }),
                     },
                     '权限'
                 ),
+                h(
+                    ElButton,
+                    {
+                        type: 'primary',
+                        onClick: throttle(() => {
+                            showRoleEditForm.value = true
+                            editRole.value = row
+                        }),
+                    },
+                    '编辑'
+                ),
             ]),
     },
 ]
@@ -120,11 +138,15 @@ const columns: Column<any>[] = [
 /**
  * 创建
  */
-const create = () => { }
+const create = throttle(() => {
+    showRoleEditForm.value = true
+    editRole.value = newRole()
+})
 /**
  * 刷新
  */
 const reflush = () => { }
+
 </script>
 
 <style lang="scss" scoped>