This commit is contained in:
zhuoda
2024-01-08 19:52:39 +08:00
parent 8dc663d885
commit 192e959d14
1126 changed files with 13783 additions and 68273 deletions

View File

@@ -18,7 +18,8 @@
import { useRouter } from 'vue-router';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
const router = useRouter();
function goHome() {
useRouter().push({ name: HOME_PAGE_NAME });
router.push({ name: HOME_PAGE_NAME });
}
</script>

View File

@@ -8,7 +8,7 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-result status="404 title="对不起您访问的内容不存在">
<a-result status="404" title="对不起,您访问的内容不存在">
<template #extra>
<a-button type="primary" @click="goHome">返回首页</a-button>
</template>
@@ -18,7 +18,8 @@
import { useRouter } from 'vue-router';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
const router = useRouter();
function goHome() {
useRouter().push({ name: HOME_PAGE_NAME });
router.push({ name: HOME_PAGE_NAME });
}
</script>

View File

@@ -28,7 +28,7 @@
</a-card>
</template>
<script setup>
import emitter from '/@/views/system/employee/department/department-mitt';
import emitter from '../../department-mitt';
const props = defineProps({
breadcrumb: Array,

View File

@@ -8,7 +8,7 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal v-model:visible="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose>
<a-modal v-model:open="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose>
<a-form ref="formRef" :model="formState" :rules="rules" layout="vertical">
<a-form-item label="上级部门" name="parentId" v-if="formState.parentId != 0">
<DepartmentTreeSelect ref="departmentTreeSelect" v-model:value="formState.parentId" :defaultValueFlag="false" width="100%" />
@@ -28,7 +28,7 @@
<script setup lang="ts">
import message from 'ant-design-vue/lib/message';
import { reactive, ref } from 'vue';
import { departmentApi } from '/@/api/system/department/department-api';
import { departmentApi } from '/@/api/system/department-api';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
import EmployeeSelect from '/@/components/system/employee-select/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';

View File

@@ -69,9 +69,9 @@
import _ from 'lodash';
import { createVNode, onMounted } from 'vue';
import DepartmentFormModal from '../department-form-modal/index.vue';
import { departmentApi } from '/@/api/system/department/department-api';
import { departmentApi } from '/@/api/system/department-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import departmentEmitter from '/@/views/system/employee/department/department-mitt';
import departmentEmitter from '../../department-mitt';
import { smartSentry } from '/@/lib/smart-sentry';
const DEPARTMENT_PARENT_ID = 0;
@@ -330,7 +330,6 @@
.sort-span {
margin-left: 5px;
color: @success-color;
}
.no-data {
margin: 10px;

View File

@@ -8,7 +8,7 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal v-model:visible="visible" title="调整部门" :footer="null" destroyOnClose>
<a-modal v-model:open="visible" title="调整部门" :footer="null" destroyOnClose>
<DepartmentTree ref="departmentTree" :height="400" :showMenu="false" />
<div class="footer">
<a-button style="margin-right: 8px" @click="closeModal">取消</a-button>
@@ -18,12 +18,12 @@
</template>
<script setup lang="ts">
import { message } from 'ant-design-vue';
import _ from 'lodash';
import { ref } from 'vue';
import DepartmentTree from '../department-tree/index.vue';
import { employeeApi } from '/@/api/system/employee/employee-api';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading';
import _ from 'lodash';
import { ref } from 'vue';
import DepartmentTree from '../department-tree/index.vue';
import { employeeApi } from '/@/api/system/employee-api';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading';
// ----------------------- 以下是字段定义 emits props ---------------------

View File

@@ -11,7 +11,7 @@
<a-drawer
:title="form.employeeId ? '编辑' : '添加'"
:width="600"
:visible="visible"
:open="visible"
:body-style="{ paddingBottom: '80px' }"
@close="onClose"
destroyOnClose
@@ -56,8 +56,8 @@
import { message } from 'ant-design-vue';
import _ from 'lodash';
import { nextTick, reactive, ref } from 'vue';
import { employeeApi } from '/@/api/system/employee/employee-api';
import { roleApi } from '/@/api/system/role/role-api';
import { employeeApi } from '/@/api/system/employee-api';
import { roleApi } from '/@/api/system/role-api';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
import { GENDER_ENUM } from '/@/constants/common-const';

View File

@@ -105,7 +105,7 @@
import { message, Modal } from 'ant-design-vue';
import _ from 'lodash';
import { computed, createVNode, reactive, ref, watch } from 'vue';
import { employeeApi } from '/@/api/system/employee/employee-api';
import { employeeApi } from '/@/api/system/employee-api';
import { PAGE_SIZE } from '/@/constants/common-const';
import { SmartLoading } from '/@/components/framework/smart-loading';
import EmployeeFormModal from '../employee-form-modal/index.vue';
@@ -202,7 +202,7 @@
params.departmentId = props.departmentId;
let res = await employeeApi.queryEmployee(params);
for (const item of res.data.list) {
item.roleNameList = _.join(item.roleNameList,',');
item.roleNameList = _.join(item.roleNameList, ',');
}
tableData.value = res.data.list;
total.value = res.data.total;

View File

@@ -8,7 +8,7 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal v-model:visible="visible" :zIndex="9999" :width="500" title="提示" :closable="false" :maskClosable="false">
<a-modal v-model:open="visible" :zIndex="9999" :width="500" title="提示" :closable="false" :maskClosable="false">
<!-- -->
<ul>
<li>登录名: {{ showLoginName }}</li>

View File

@@ -12,7 +12,7 @@
<div>
<div class="btn-group">
<a-button class="button-style" type="primary" @click="updateDataScope" v-privilege="'system:role:dataScope:update'"> 保存 </a-button>
<a-button class="button-style" @click="getDataScope" v-privilege="'role:query'"> 刷新 </a-button>
<a-button class="button-style" @click="getDataScope" > 刷新 </a-button>
</div>
<a-row class="header">
<a-col class="tab-margin" :span="4">业务单据</a-col>
@@ -46,7 +46,7 @@
import { message } from 'ant-design-vue';
import _ from 'lodash';
import { inject, onMounted, ref, watch } from 'vue';
import { roleApi } from '/@/api/system/role/role-api';
import { roleApi } from '/@/api/system/role-api';
import { smartSentry } from '/@/lib/smart-sentry';
const props = defineProps({

View File

@@ -14,7 +14,7 @@
<div>
关键字
<a-input style="width: 250px" v-model:value="queryForm.keywords" placeholder="姓名/手机号/登录账号" />
<a-button class="button-style" v-if="selectRoleId" type="primary" @click="queryRoleEmployee">搜索</a-button>
<a-button class="button-style" v-if="selectRoleId" type="primary" @click="onSearch">搜索</a-button>
<a-button class="button-style" v-if="selectRoleId" type="default" @click="resetQueryRoleEmployee">重置</a-button>
</div>
@@ -73,7 +73,7 @@
import { message, Modal } from 'ant-design-vue';
import _ from 'lodash';
import { computed, inject, onMounted, reactive, ref, watch } from 'vue';
import { roleApi } from '/@/api/system/role/role-api';
import { roleApi } from '/@/api/system/role-api';
import { PAGE_SIZE, showTableTotal, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { SmartLoading } from '/@/components/framework/smart-loading';
import EmployeeTableSelectModal from '/@/components/system/employee-table-select-modal/index.vue';
@@ -110,6 +110,11 @@
queryRoleEmployee();
}
function onSearch(){
queryForm.pageNum = 1;
queryRoleEmployee();
}
async function queryRoleEmployee() {
try {
tableLoading.value = true;

View File

@@ -9,11 +9,14 @@
*
-->
<template>
<a-modal :title="form.roleId ? '编辑角色' : '添加角色'" :width="600" :visible="modalVisible" @cancel="onClose" :footer="null">
<a-modal :title="form.roleId ? '编辑角色' : '添加角色'" :width="600" :open="modalVisible" @cancel="onClose" :footer="null">
<a-form ref="formRef" :model="form" :rules="rules" :labelCol="{ span: 4 }">
<a-form-item label="角色名称" name="roleName">
<a-input style="width: 100%" placeholder="请输入角色名称" v-model:value="form.roleName" />
</a-form-item>
<a-form-item label="角色编码" name="roleCode">
<a-input style="width: 100%" placeholder="请输入角色编码" v-model:value="form.roleCode" />
</a-form-item>
<a-form-item label="角色备注">
<a-input style="width: 100%" placeholder="请输入角色备注" v-model:value="form.remark" />
</a-form-item>
@@ -29,8 +32,8 @@
<script setup>
import { message } from 'ant-design-vue';
import { reactive, ref } from 'vue';
import { roleApi } from '/@/api/system/role/role-api';
import { smartSentry } from '/@/lib/smart-sentry';
import { roleApi } from '/@/api/system/role-api';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading';
// ----------------------- 以下是字段定义 emits props ---------------------
let emits = defineEmits(['refresh']);
@@ -62,6 +65,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
const formDefault = {
id: undefined,
remark: undefined,
roleCode: undefined,
roleName: undefined,
};
@@ -70,6 +74,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
// 表单规则
const rules = {
roleName: [{ required: true, message: '请输入角色名称' }],
roleCode: [{ required: true, message: '请输入角色编码' }],
};
// 提交表单

View File

@@ -33,7 +33,7 @@
import { message, Modal } from 'ant-design-vue';
import _ from 'lodash';
import { computed, onMounted, ref } from 'vue';
import { roleApi } from '/@/api/system/role/role-api';
import { roleApi } from '/@/api/system/role-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import RoleFormModal from '../role-form-modal/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';

View File

@@ -23,7 +23,7 @@
import { message } from 'ant-design-vue';
import _ from 'lodash';
import RoleTreeCheckbox from './role-tree-checkbox.vue';
import { roleMenuApi } from '/@/api/system/role-menu/role-menu-api';
import { roleMenuApi } from '/@/api/system/role-menu-api';
import { useRoleStore } from '/@/store/modules/system/role';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { smartSentry } from '/@/lib/smart-sentry';

View File

@@ -9,7 +9,7 @@
*
-->
<template>
<div style="height: 542px; overflow: auto">
<div style="overflow: auto">
<a-checkbox-group v-model:value="checkedData">
<div class="checked-box">
<ul>
@@ -32,7 +32,7 @@
default: [],
},
});
defineEmits('update:value');
defineEmits(['update:value']);
let roleStore = useRoleStore();
let checkedData = ref();

View File

@@ -37,7 +37,7 @@
default: 0,
},
});
defineEmits('update:value');
defineEmits(['update:value']);
let roleStore = useRoleStore();
function selectCheckbox(module) {
if (!module.menuId) {

View File

@@ -28,6 +28,6 @@
default: 0,
},
});
let emits = defineEmits('selectCheckbox');
let emits = defineEmits(['selectCheckbox']);
</script>
<style scoped lang="less"></style>

View File

@@ -27,7 +27,7 @@
defineProps({
value: Object,
});
defineEmits('update:value');
defineEmits(['update:value']);
let roleList = ref();
const selectRoleId = computed(() => {
@@ -42,7 +42,7 @@
.height100 {
height: 100%;
}
.role-setting{
width:calc(100% - 250px)
.role-setting {
width: calc(100% - 250px);
}
</style>

View File

@@ -30,7 +30,7 @@
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { smartSentry } from '/@/lib/smart-sentry';
import { changeLogApi } from '/@/api/support/change-log/change-log-api';
import { changeLogApi } from '/@/api/support/change-log-api';
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
import ChangeLogForm from '/@/views/support/change-log/change-log-modal.vue';
@@ -88,20 +88,7 @@
.time {
flex-shrink: 0;
color: @text-color-secondary;
min-width: 75px;
}
}
ul li :hover {
color: @primary-color;
}
.un-read a {
color: @text-color;
}
.read a {
color: @text-color-secondary;
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<default-home-card icon="ProfileTwoTone" title="【1024创新实验室】人员饭量">
<default-home-card icon="ProfileTwoTone" title="销量统计">
<div class="echarts-box">
<div class="category-main" id="category-main"></div>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<default-home-card icon="FundTwoTone" title="【1024创新实验室】代码提交量">
<default-home-card icon="FundTwoTone" title="代码提交量">
<div class="echarts-box">
<div class="gradient-main" id="gradient-main"></div>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<default-home-card icon="PieChartTwoTone" title="【1024创新实验室】上班摸鱼次数">
<default-home-card icon="PieChartTwoTone" title="加班统计">
<div class="echarts-box">
<div class="pie-main" id="pie-main"></div>
</div>
@@ -25,7 +25,7 @@ function init(){
},
series: [
{
name: '摸鱼次数',
name: '加班次数',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,

View File

@@ -9,7 +9,7 @@
*
-->
<template>
<default-home-card icon="SmileTwoTone" title="添加微信关注【小镇程序员】、【1024创新实验室】">
<default-home-card icon="SmileTwoTone" title="联系我们">
<div class="app-qr-box">
<div class="app-qr">
<img :src="zhuoda" />
@@ -18,22 +18,16 @@
</div>
<div class="app-qr">
<img :src="xiaozhen" />
<span class="qr-desc strong"> 小镇程序员 </span>
<span class="qr-desc"> 代码与生活还有钱途 </span>
</div>
<div class="app-qr">
<img :src="lab1024" />
<span class="qr-desc strong"> 1024创新实验室 </span>
<span class="qr-desc"> 官方账号 </span>
<span class="qr-desc strong"> 六边形工程师 </span>
<span class="qr-desc"> 赚钱代码生活 </span>
</div>
</div>
</default-home-card>
</template>
<script setup>
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
import lab1024 from '/@/assets/images/1024lab/1024lab-gzh.jpg';
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg';
import xiaozhen from '/@/assets/images/1024lab/xiaozhen-gzh.jpg';
import xiaozhen from '/@/assets/images/1024lab/gzh.jpg';
</script>
<style lang="less" scoped>
.app-qr-box {

View File

@@ -1,19 +1,19 @@
<template>
<a-modal v-model:visible="visible" title="新建快捷入口" @close="onClose">
<a-modal v-model:open="visible" title="新建快捷入口" @close="onClose">
<a-form ref="formRef" :model="form" :rules="rules">
<a-form-item label="图标" name="icon">
<IconSelect @updateIcon="selectIcon">
<template #iconSelect>
<a-input v-model:value="form.icon" placeholder="请输入菜单图标" style="width: 200px"/>
<component :is="$antIcons[form.icon]" class="smart-margin-left15" style="font-size: 20px"/>
<a-input v-model:value="form.icon" placeholder="请输入菜单图标" style="width: 200px" />
<component :is="$antIcons[form.icon]" class="smart-margin-left15" style="font-size: 20px" />
</template>
</IconSelect>
</a-form-item>
<a-form-item label="标题" name="title">
<a-input v-model:value="form.title" placeholder="请输入标题"/>
<a-input v-model:value="form.title" placeholder="请输入标题" />
</a-form-item>
<a-form-item label="路径" name="path">
<a-input v-model:value="form.path" placeholder="请输入路径"/>
<a-input v-model:value="form.path" placeholder="请输入路径" />
</a-form-item>
</a-form>
<template #footer>
@@ -23,59 +23,58 @@
</a-modal>
</template>
<script setup>
import {reactive, ref} from "vue";
import {message} from "ant-design-vue";
import IconSelect from '/@/components/framework/icon-select/index.vue';
import _ from "lodash";
import { reactive, ref } from 'vue';
import { message } from 'ant-design-vue';
import IconSelect from '/@/components/framework/icon-select/index.vue';
import _ from 'lodash';
defineExpose({
showModal
})
defineExpose({
showModal,
});
const emit = defineEmits("addQuickEntry");
const emit = defineEmits(['addQuickEntry']);
// 组件ref
const formRef = ref();
// 组件ref
const formRef = ref();
const formDefault = {
icon: undefined,
title: "",
path: "",
};
let form = reactive({...formDefault});
const rules = {
icon: [{required: true, message: "请选择图标"}],
title: [{required: true, message: "标题不能为空"}],
path: [{required: true, message: "路径不能为空"}],
};
const formDefault = {
icon: undefined,
title: '',
path: '',
};
let form = reactive({ ...formDefault });
const rules = {
icon: [{ required: true, message: '请选择图标' }],
title: [{ required: true, message: '标题不能为空' }],
path: [{ required: true, message: '路径不能为空' }],
};
const visible = ref(false);
const visible = ref(false);
function showModal() {
visible.value = true;
}
function showModal() {
visible.value = true;
}
function selectIcon(icon) {
form.icon = icon;
}
function selectIcon(icon) {
form.icon = icon;
}
function onClose() {
Object.assign(form, formDefault);
visible.value = false;
}
function onClose() {
Object.assign(form, formDefault);
visible.value = false;
}
function onSubmit() {
formRef.value
function onSubmit() {
formRef.value
.validate()
.then(() => {
emit("addQuickEntry", _.cloneDeep(form));
emit('addQuickEntry', _.cloneDeep(form));
onClose();
})
.catch((error) => {
console.log("error", error);
message.error("参数验证错误,请仔细填写表单数据!");
console.log('error', error);
message.error('参数验证错误,请仔细填写表单数据!');
});
}
}
</script>
<style lang='less' scoped></style>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,12 @@
export default [
'每个人的一生好比一根蜡烛,看似不经意间散发的光和热,都可能照亮和温暖他人。这是生活赋予我们的智慧,也让我们在寻常的日子成为一个温暖善良的人。',
'立规矩的目的,不是禁锢、限制,而是教育;孩子犯了错,父母不能帮孩子逃避,而应该让孩子学会承担责任。让孩子有面对错误的诚实和勇气,这才是立规矩的意义所在。',
'人这一辈子,格局大了、善良有了,成功自然也就近了。格局越大,人生越宽。你的人生会是什么样,与你在为人处世时的表现有很大关系。世间美好都是环环相扣的,善良的人总不会被亏待。',
'平日里的千锤百炼,才能托举出光彩时刻;逆境中的亮剑、失败后的奋起,才能让梦想成真。哪有什么一战成名,其实都是百炼成钢。“天才”都是汗水浇灌出来的,天赋或许可以决定起点,但唯有坚持和努力才能达到终点。',
'家,不在于奢华,而在于温馨;家,不在于大小,而在于珍惜。在家里,有父母的呵护,有爱人的陪伴,有子女的欢笑。一家人整整齐齐、和和睦睦,就是人生最大的幸福!',
'每一个不向命运低头、努力生活的人,都值得被尊重。',
'青年的肩上,从不只有清风明月,更有责任担当。岁月因青春慨然以赴而更加美好,世间因少年挺身向前而更加瑰丽。请相信,不会有人永远年轻,但永远有人年轻。',
'人生路上,总有人走得比你快,但不必介意,也不必着急。一味羡慕别人的成绩,只会给自己平添压力、徒增烦恼。不盲从别人的脚步,坚定目标,才能找到自己的节奏,进而逢山开路、遇水搭桥。',
'如果你真的在乎一个人,首先要学会的就是感恩对方的好。这样,对方才会在和你的相处中找到价值感,相处起来也会更加舒适愉悦。',
'一个人只有心里装得下别人,有换位思考的品质,有为他人谋幸福的信念,才能真正做到慷慨施予。同样,也只有赠人玫瑰而无所求时,你才会手有余香、真有所得。',
];

View File

@@ -10,26 +10,23 @@
-->
<template>
<div class="user-header">
<a-page-header :title="welcomeSentence" :sub-title="departmentName" >
<template #tags>
<a-tag color="blue">努力工作</a-tag>
<a-tag color="success">主动 / 皮实 / 可靠 </a-tag>
<a-tag color="error">自省 / 精进 / 创新</a-tag>
<a-page-header :title="welcomeSentence">
<template #subTitle>
<span style="color: #666; margin-left: 20px;">所属部门{{ departmentName }} </span>
</template>
<template #extra>
<p>{{ dayInfo }}</p>
<p style="color: #333">{{ dayInfo }}</p>
</template>
<a-row class="content">
<span class="heart-sentence">
<h3>{{ heartSentence }}</h3>
<p class="last-login-info">{{ lastLoginInfo }}</p>
<div></div>
<span class="left-content">
<p class="last-login-info"><AlertOutlined />{{ lastLoginInfo }}</p>
<a class="sentence" href="https://sentence.1024lab.net/" target="_blank"> <smile-outlined spin /> {{ heartSentence }} </a>
</span>
<div class="weather">
<iframe
width="100%"
scrolling="no"
height="60"
height="50"
frameborder="0"
allowtransparency="true"
src="//i.tianqi.com/index.php?c=code&id=12&icon=1&num=3&site=12"
@@ -45,10 +42,11 @@
import uaparser from 'ua-parser-js';
import { Solar, Lunar } from 'lunar-javascript';
import _ from 'lodash';
import heartSentenceArray from './heart-sentence';
const userStore = useUserStore();
const departmentName = computed(() => useUserStore.departmentName);
const departmentName = computed(() => userStore.departmentName);
// 欢迎语
const welcomeSentence = computed(() => {
@@ -74,9 +72,7 @@
if (userStore.$state.lastLoginTime) {
info = info + '上次登录:' + userStore.$state.lastLoginTime;
}
if (userStore.$state.lastLoginIp) {
info = info + '; IP:' + userStore.$state.lastLoginIp;
}
if (userStore.$state.lastLoginUserAgent) {
let ua = uaparser(userStore.$state.lastLoginUserAgent);
info = info + '; 设备:';
@@ -88,9 +84,16 @@
}
let device = ua.device.vendor ? ua.device.vendor + ua.device.model : null;
if (device) {
info = info + ' ' + device;
info = info + ' ' + device + ';';
}
}
if (userStore.$state.lastLoginIpRegion) {
info = info + '; ' + userStore.$state.lastLoginIpRegion;
}
if (userStore.$state.lastLoginIp) {
info = info + '; ' + userStore.$state.lastLoginIp;
}
return info;
});
@@ -113,18 +116,6 @@
});
// 毒鸡汤
const heartSentenceArray = [
'每个人的一生好比一根蜡烛,看似不经意间散发的光和热,都可能照亮和温暖他人。这是生活赋予我们的智慧,也让我们在寻常的日子成为一个温暖善良的人。',
'立规矩的目的,不是禁锢、限制,而是教育;孩子犯了错,父母不能帮孩子逃避,而应该让孩子学会承担责任。让孩子有面对错误的诚实和勇气,这才是立规矩的意义所在。',
'人这一辈子,格局大了、善良有了,成功自然也就近了。格局越大,人生越宽。你的人生会是什么样,与你在为人处世时的表现有很大关系。世间美好都是环环相扣的,善良的人总不会被亏待。',
'平日里的千锤百炼,才能托举出光彩时刻;逆境中的亮剑、失败后的奋起,才能让梦想成真。哪有什么一战成名,其实都是百炼成钢。“天才”都是汗水浇灌出来的,天赋或许可以决定起点,但唯有坚持和努力才能达到终点。',
'家,不在于奢华,而在于温馨;家,不在于大小,而在于珍惜。在家里,有父母的呵护,有爱人的陪伴,有子女的欢笑。一家人整整齐齐、和和睦睦,就是人生最大的幸福!',
'每一个不向命运低头、努力生活的人,都值得被尊重。',
'青年的肩上,从不只有清风明月,更有责任担当。岁月因青春慨然以赴而更加美好,世间因少年挺身向前而更加瑰丽。请相信,不会有人永远年轻,但永远有人年轻。',
'人生路上,总有人走得比你快,但不必介意,也不必着急。一味羡慕别人的成绩,只会给自己平添压力、徒增烦恼。不盲从别人的脚步,坚定目标,才能找到自己的节奏,进而逢山开路、遇水搭桥。',
'如果你真的在乎一个人,首先要学会的就是感恩对方的好。这样,对方才会在和你的相处中找到价值感,相处起来也会更加舒适愉悦。',
'一个人只有心里装得下别人,有换位思考的品质,有为他人谋幸福的信念,才能真正做到慷慨施予。同样,也只有赠人玫瑰而无所求时,你才会手有余香、真有所得。',
];
const heartSentence = computed(() => {
return heartSentenceArray[_.random(0, heartSentenceArray.length - 1)];
});
@@ -135,7 +126,7 @@
background-color: #fff;
margin-bottom: 10px;
.heart-sentence {
.left-content {
width: calc(100% - 420px);
h3 {
color: rgba(0, 0, 0, 0.75);
@@ -152,8 +143,23 @@
.last-login-info {
font-size: 13px;
color: rgba(0, 0, 0, 0.45);
color: #333;
overflow-wrap: break-word;
padding: 0;
margin: 1px 0 0 0;
}
.sentence {
display: block;
font-size: 12px;
color: #acacac;
overflow-wrap: break-word;
padding: 5px 0 0 0;
margin: 6px 0 0 0;
}
.sentence:hover {
cursor: pointer;
text-decoration: underline;
}
}
</style>

View File

@@ -11,32 +11,36 @@
<template>
<default-home-card extra="更多" icon="SoundTwoTone" title="通知公告" @extraClick="onMore">
<a-spin :spinning="loading">
<div class="content-wrapper">
<a-empty v-if="$lodash.isEmpty(data)" />
<ul v-else>
<li v-for="(item, index) in data" :key="index" :class="[item.viewFlag ? 'read' : 'un-read']">
<a-tooltip placement="top">
<template #title>
<span>{{ item.title }}</span>
</template>
<a class="content" @click="toDetail(item.noticeId)">
<a-badge :status="item.viewFlag ? 'default' : 'error'" />
{{ item.title }}
</a>
</a-tooltip>
<span class="time"> {{ item.publishDate }}</span>
</li>
</ul>
</div>
<div class="content-wrapper">
<a-empty v-if="$lodash.isEmpty(data)" />
<ul v-else>
<li v-for="(item, index) in data" :key="index" :class="[item.viewFlag ? 'read' : 'un-read']">
<a-tooltip placement="top">
<template #title>
<span>{{ item.title }}</span>
</template>
<a class="content" @click="toDetail(item.noticeId)">
<a-badge :status="item.viewFlag ? 'default' : 'error'" />
{{ item.title }}
</a>
</a-tooltip>
<span class="time"> {{ item.publishDate }}</span>
</li>
</ul>
</div>
</a-spin>
</default-home-card>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { smartSentry } from '/@/lib/smart-sentry';
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
import { useRouter } from 'vue-router';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { smartSentry } from '/@/lib/smart-sentry';
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
import { theme } from 'ant-design-vue';
const { useToken } = theme;
const { token } = useToken();
const colorPrimary = token.value.colorPrimary;
const props = defineProps({
noticeTypeId: {
@@ -90,7 +94,7 @@ import DefaultHomeCard from '/@/views/system/home/components/default-home-card.v
</script>
<style lang="less" scoped>
@read-color: #666;
.content-wrapper{
.content-wrapper {
height: 150px;
overflow-y: hidden;
overflow-x: hidden;
@@ -106,6 +110,7 @@ import DefaultHomeCard from '/@/views/system/home/components/default-home-card.v
overflow: hidden;
word-break: break-all;
margin-right: 5px;
color: v-bind(colorPrimary);
}
.time {
@@ -115,15 +120,7 @@ import DefaultHomeCard from '/@/views/system/home/components/default-home-card.v
}
}
ul li :hover {
color: @primary-color;
}
.un-read a {
color: @text-color;
}
.read a {
color: @read-color;
color: @read-color !important;
}
</style>

View File

@@ -45,6 +45,7 @@
font-size: 15px;
font-weight: 500;
margin: 40px 0 60px 0;
line-height: 21px;
.setence {
font-size: 13px;
@@ -106,7 +107,7 @@
transform: translateX(0);
}
100% {
transform: translateX(-220%);
transform: translateX(-30%);
}
}
@@ -117,7 +118,7 @@
display: inline-block;
width: 100%;
white-space: nowrap;
animation: marquee 15s linear infinite;
animation: marquee 5s linear infinite;
}
}
}
@@ -128,10 +129,9 @@
font-weight: 700;
text-align: center;
color: #1e1e1e;
margin-bottom: 35px;
}
.login-form {
margin-top: 37px;
.captcha-input {
width: 60%;
}

View File

@@ -12,12 +12,14 @@
<div class="login-container">
<div class="box-item desc">
<div class="welcome">
<p>欢迎登录 SmartAdmin V2</p>
<p>欢迎登录 SmartAdmin V3</p>
<p class="desc">
SmartAdmin 是由 河南·洛阳
<a target="_blank" href="https://www.1024lab.net"
style="color: white; weight: bolder; font-size: 15px; text-decoration: underline">1024创新实验室1024Lab</a>
使用SpringBoot2.x Vue3.2 Setup语法糖 Composition Api (同时支持JavaScript和TypeScript双版本) 开发出的一套简洁易用的中后台解决方案
<a target="_blank" href="https://www.1024lab.net" style="color: white; weight: bolder; font-size: 15px; text-decoration: underline"
>1024创新实验室1024Lab</a
>
基于SpringBoot + Sa-Token + Mybatis-Plus Vue3 + Vite5 + Ant Design Vue 4 (同时支持JavaScript和TypeScript双版本)
高质量代码为核心简洁高效安全的快速开发平台
<br />
<br />
<span class="setence">
@@ -28,9 +30,8 @@
保持谦逊保持学习热爱代码更热爱生活 !<br />
永远年轻永远前行 !<br />
<span class="author">
<a target="_blank" href="https://zhuoda.vip"
style="color: white; font-size: 13px; text-decoration: underline">
1024创新实验室-主任卓大
<a target="_blank" href="https://zhuoda.vip" style="color: white; font-size: 13px; text-decoration: underline">
1024创新实验室-主任卓大
</a>
</span>
</span>
@@ -42,8 +43,12 @@
<span class="qr-desc"> 加微信骚扰卓大 :) </span>
</div>
<div class="app-qr">
<img :src="xiaozhen" />
<div class="qr-desc-marquee"><div class="marquee"><span>关注小镇程序员了解二三线城市程序员的代码与钱途技术与生活城市可能无法选择但未来可以拼搏</span></div></div>
<img :src="gzh" />
<div class="qr-desc-marquee">
<div class="marquee">
<span>关注六边形工程师分享赚钱代码生活</span>
</div>
</div>
</div>
</div>
</div>
@@ -55,8 +60,12 @@
<a-input v-model:value.trim="loginForm.loginName" placeholder="请输入用户名" />
</a-form-item>
<a-form-item name="password">
<a-input-password v-model:value="loginForm.password" autocomplete="on"
:type="showPassword ? 'text' : 'password'" placeholder="请输入密码" />
<a-input-password
v-model:value="loginForm.password"
autocomplete="on"
:type="showPassword ? 'text' : 'password'"
placeholder="请输入密码:至少三种字符,最小 8 位"
/>
</a-form-item>
<a-form-item name="captchaCode">
<a-input class="captcha-input" v-model:value.trim="loginForm.captchaCode" placeholder="请输入验证码" />
@@ -84,117 +93,124 @@
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { message } from 'ant-design-vue';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { loginApi } from '/@/api/system/login/login-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
import { useUserStore } from '/@/store/modules/system/user';
import { saveTokenToCookie } from '/@/utils/cookie-util';
import { message } from 'ant-design-vue';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { loginApi } from '/@/api/system/login-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
import { useUserStore } from '/@/store/modules/system/user';
import { saveTokenToCookie } from '/@/utils/cookie-util';
import gongzhonghao from '/@/assets/images/1024lab/1024lab-gzh.jpg';
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg';
import loginQR from '/@/assets/images/login/login-qr.png';
import xiaozhen from '/@/assets/images/1024lab/xiaozhen-gzh.jpg';
import gongzhonghao from '/@/assets/images/1024lab/1024lab-gzh.jpg';
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg';
import loginQR from '/@/assets/images/login/login-qr.png';
import gzh from '/@/assets/images/1024lab/gzh.jpg';
import aliLogin from '/@/assets/images/login/ali-icon.png';
import googleLogin from '/@/assets/images/login/google-icon.png';
import qqLogin from '/@/assets/images/login/qq-icon.png';
import weiboLogin from '/@/assets/images/login/weibo-icon.png';
import aliLogin from '/@/assets/images/login/ali-icon.png';
import googleLogin from '/@/assets/images/login/google-icon.png';
import qqLogin from '/@/assets/images/login/qq-icon.png';
import weiboLogin from '/@/assets/images/login/weibo-icon.png';
import { buildRoutes } from '/@/router/index';
import { smartSentry } from '/@/lib/smart-sentry';
import { buildRoutes } from '/@/router/index';
import { smartSentry } from '/@/lib/smart-sentry';
import { encryptData } from '/@/lib/encrypt';
//--------------------- 登录表单 ---------------------------------
//--------------------- 登录表单 ---------------------------------
const loginForm = reactive({
loginName: 'admin',
password: '',
captchaCode: '',
captchaUuid: '',
loginDevice: LOGIN_DEVICE_ENUM.PC.value,
});
const rules = {
loginName: [{ required: true, message: '用户名不能为空' }],
password: [{ required: true, message: '密码不能为空' }],
captchaCode: [{ required: true, message: '验证码不能为空' }],
};
const showPassword = ref(false);
const router = useRouter();
const formRef = ref();
const rememberPwd = ref(false);
onMounted(() => {
document.onkeyup = (e) => {
if (e.keyCode == 13) {
onLogin();
}
};
});
onUnmounted(() => {
document.onkeyup = null;
});
//登录
async function onLogin() {
formRef.value.validate().then(async () => {
try {
SmartLoading.show();
const res = await loginApi.login(loginForm);
stopRefrestCaptchaInterval();
saveTokenToCookie(res.data.token ? res.data.token : '');
message.success('登录成功');
//更新用户信息到pinia
useUserStore().setUserLoginInfo(res.data);
//构建系统的路由
buildRoutes();
router.push('/home');
} catch (e) {
if (e.data && e.data.code === 30001) {
loginForm.captchaCode = '';
getCaptcha();
}
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
const loginForm = reactive({
loginName: 'admin',
password: '',
captchaCode: '',
captchaUuid: '',
loginDevice: LOGIN_DEVICE_ENUM.PC.value,
});
}
const rules = {
loginName: [{ required: true, message: '用户名不能为空' }],
password: [{ required: true, message: '密码不能为空' }],
captchaCode: [{ required: true, message: '验证码不能为空' }],
};
//--------------------- 验证码 ---------------------------------
const showPassword = ref(false);
const router = useRouter();
const formRef = ref();
const rememberPwd = ref(false);
const captchaBase64Image = ref('');
async function getCaptcha() {
try {
let captchaResult = await loginApi.getCaptcha();
captchaBase64Image.value = captchaResult.data.captchaBase64Image;
loginForm.captchaUuid = captchaResult.data.captchaUuid;
beginRefrestCaptchaInterval(captchaResult.data.expireSeconds);
} catch (e) {
console.log(e);
onMounted(() => {
document.onkeyup = (e) => {
if (e.keyCode == 13) {
onLogin();
}
};
});
onUnmounted(() => {
document.onkeyup = null;
});
//登录
async function onLogin() {
formRef.value.validate().then(async () => {
try {
SmartLoading.show();
// 密码加密
let encryptPasswordForm = Object.assign({}, loginForm, {
password: encryptData(loginForm.password),
});
const res = await loginApi.login(encryptPasswordForm);
stopRefrestCaptchaInterval();
saveTokenToCookie(res.data.token ? res.data.token : '');
message.success('登录成功');
//更新用户信息到pinia
useUserStore().setUserLoginInfo(res.data);
//构建系统的路由
buildRoutes();
router.push('/home');
} catch (e) {
if (e.data && e.data.code !== 0) {
loginForm.captchaCode = '';
getCaptcha();
}
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
});
}
}
let refrestCaptchaInterval = null;
function beginRefrestCaptchaInterval(expireSeconds) {
if (refrestCaptchaInterval === null) {
refrestCaptchaInterval = setInterval(getCaptcha, (expireSeconds - 5) * 1000);
//--------------------- 验证码 ---------------------------------
const captchaBase64Image = ref('');
async function getCaptcha() {
try {
let captchaResult = await loginApi.getCaptcha();
captchaBase64Image.value = captchaResult.data.captchaBase64Image;
loginForm.captchaUuid = captchaResult.data.captchaUuid;
beginRefrestCaptchaInterval(captchaResult.data.expireSeconds);
} catch (e) {
console.log(e);
}
}
}
function stopRefrestCaptchaInterval() {
if (refrestCaptchaInterval != null) {
clearInterval(refrestCaptchaInterval);
refrestCaptchaInterval = null;
let refrestCaptchaInterval = null;
function beginRefrestCaptchaInterval(expireSeconds) {
if (refrestCaptchaInterval === null) {
refrestCaptchaInterval = setInterval(getCaptcha, (expireSeconds - 5) * 1000);
}
}
}
onMounted(getCaptcha);
function stopRefrestCaptchaInterval() {
if (refrestCaptchaInterval != null) {
clearInterval(refrestCaptchaInterval);
refrestCaptchaInterval = null;
}
}
onMounted(getCaptcha);
</script>
<style lang="less" scoped>@import './login.less';</style>
<style lang="less" scoped>
@import './login.less';
</style>

View File

@@ -12,8 +12,8 @@
:body-style="{ paddingBottom: '80px' }"
:maskClosable="true"
:title="form.menuId ? '编辑' : '添加'"
:visible="visible"
:width="550"
:open="visible"
:width="600"
@close="onClose"
>
<a-form ref="formRef" :labelCol="{ span: labelColSpan }" :labelWrap="true" :model="form" :rules="rules">
@@ -28,7 +28,7 @@
<MenuTreeSelect ref="parentMenuTreeSelect" v-model:value="form.parentId" />
</a-form-item>
<!-- 目录 菜单 start -->
<template v-if="form.menuType == MENU_TYPE_ENUM.CATALOG.value || form.menuType == MENU_TYPE_ENUM.MENU.value">
<template v-if="form.menuType === MENU_TYPE_ENUM.CATALOG.value || form.menuType === MENU_TYPE_ENUM.MENU.value">
<a-form-item label="菜单名称" name="menuName">
<a-input v-model:value="form.menuName" placeholder="请输入菜单名称" />
</a-form-item>
@@ -40,14 +40,10 @@
</template>
</IconSelect>
</a-form-item>
<a-form-item v-if="form.menuType == MENU_TYPE_ENUM.MENU.value" label="路由地址" name="path">
<a-form-item v-if="form.menuType === MENU_TYPE_ENUM.MENU.value" label="路由地址" name="path">
<a-input v-model:value="form.path" placeholder="请输入路由地址" />
</a-form-item>
<a-form-item label="排序" name="sort">
<a-input-number v-model:value="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
<h6 style="color: #ababab">值越小越靠前</h6>
</a-form-item>
<template v-if="form.menuType == MENU_TYPE_ENUM.MENU.value">
<template v-if="form.menuType === MENU_TYPE_ENUM.MENU.value">
<a-form-item v-if="form.frameFlag" label="外链地址" name="frameUrl">
<a-input v-model:value="form.frameUrl" placeholder="请输入外链地址" />
</a-form-item>
@@ -55,11 +51,10 @@
<a-input v-model:value="form.component" placeholder="请输入组件地址 默认带有开头/@/views" />
</a-form-item>
</template>
<a-form-item v-if="form.menuType == MENU_TYPE_ENUM.MENU.value" label="是否缓存" name="cacheFlag">
<a-form-item v-if="form.menuType === MENU_TYPE_ENUM.MENU.value" label="是否缓存" name="cacheFlag">
<a-switch v-model:checked="form.cacheFlag" checked-children="开启缓存" un-checked-children="不缓存" />
</a-form-item>
<a-form-item v-if="form.menuType == MENU_TYPE_ENUM.MENU.value" label="是否外链" name="frameFlag">
<a-form-item v-if="form.menuType === MENU_TYPE_ENUM.MENU.value" label="是否外链" name="frameFlag">
<a-switch v-model:checked="form.frameFlag" checked-children="是外链" un-checked-children="不是外链" />
</a-form-item>
<a-form-item label="显示状态" name="frameFlag">
@@ -71,7 +66,7 @@
</template>
<!-- 目录 菜单 end -->
<!-- 按钮 start -->
<template v-if="form.menuType == MENU_TYPE_ENUM.POINTS.value">
<template v-if="form.menuType === MENU_TYPE_ENUM.POINTS.value">
<a-form-item label="功能点名称" name="menuName">
<a-input v-model:value="form.menuName" placeholder="请输入功能点名称" />
</a-form-item>
@@ -82,22 +77,24 @@
<a-switch v-model:checked="form.disabledFlag" checked-children="启用" un-checked-children="禁用" />
</a-form-item>
<a-form-item label="权限类型" name="permsType">
<a-radio-group v-model:value="form.permsType" >
<a-radio-group v-model:value="form.permsType">
<a-radio v-for="item in MENU_PERMS_TYPE_ENUM" :key="item.value" :value="item.value">
{{ item.desc }}
</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item :label="form.permsType === MENU_PERMS_TYPE_ENUM.SPRING_SECURITY.value ? '权限字符' : '前端权限字符'" name="webPerms">
<a-input v-model:value="form.webPerms" placeholder="请输入权限字符" />
<a-form-item label="前端权限" name="webPerms" help="用于前端按钮等功能的展示和隐藏搭配v-privilege使用">
<a-input v-model:value="form.webPerms" placeholder="请输入前端权限" />
</a-form-item>
<a-form-item label="权限URL" name="apiPermsList" v-if="form.permsType === MENU_PERMS_TYPE_ENUM.URL.value">
<a-select v-model:value="form.apiPermsList" mode="multiple" placeholder="请选择接口权限" style="width: 100%">
<a-select-option v-for="item in allUrlData" :key="item.name">{{ item.url }} </a-select-option>
</a-select>
<a-form-item label="后端权限" name="apiPerms" help="后端@SaCheckPermission中的权限字符串多个以英文逗号,分割">
<a-input v-model:value="form.apiPerms" placeholder="请输入后端权限" />
</a-form-item>
</template>
<!-- 按钮 end -->
<a-form-item label="排序" name="sort">
<a-input-number v-model:value="form.sort" :min="0" placeholder="请输入排序" style="width: 100px" />
<h6 style="color: #ababab">值越小越靠前</h6>
</a-form-item>
</a-form>
<div class="footer">
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
@@ -109,11 +106,11 @@
<script setup>
import { message } from 'ant-design-vue';
import _ from 'lodash';
import { computed, nextTick, reactive, ref, watch } from 'vue';
import { computed, nextTick, reactive, ref } from 'vue';
import MenuTreeSelect from './menu-tree-select.vue';
import { menuApi } from '/@/api/system/menu/menu-api';
import { menuApi } from '/@/api/system/menu-api';
import IconSelect from '/@/components/framework/icon-select/index.vue';
import { MENU_DEFAULT_PARENT_ID, MENU_TYPE_ENUM, MENU_PERMS_TYPE_ENUM } from '/@/constants/system/menu-const';
import { MENU_DEFAULT_PARENT_ID, MENU_PERMS_TYPE_ENUM, MENU_TYPE_ENUM } from '/@/constants/system/menu-const';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading';
@@ -127,18 +124,12 @@
const visible = ref(false);
const labelColSpan = computed(() => {
if (form.menuType == MENU_TYPE_ENUM.POINTS.value) {
if (form.menuType === MENU_TYPE_ENUM.POINTS.value) {
return 6;
}
return 4;
});
watch(visible, (e) => {
if (e) {
getAuthUrl();
}
});
const contextMenuTreeSelect = ref();
const parentMenuTreeSelect = ref();
@@ -173,16 +164,6 @@
visible.value = false;
}
// ----------------------- 预加载数据 ------------------------
let allUrlData = ref([]);
// url数据
async function getAuthUrl() {
let res = await menuApi.getAuthUrl();
allUrlData.value = res.data;
}
// ----------------------- form表单相关操作 ------------------------
const formRef = ref();
@@ -193,12 +174,12 @@
icon: undefined,
parentId: undefined,
path: undefined,
permsType: MENU_PERMS_TYPE_ENUM.SPRING_SECURITY.value,
permsType: MENU_PERMS_TYPE_ENUM.SA_TOKEN.value,
webPerms: undefined,
apiPermsList: undefined,
apiPerms: undefined,
sort: undefined,
visibleFlag: true,
cacheFlag: false,
cacheFlag: true,
component: undefined,
contextMenuId: undefined,
disabledFlag: false,
@@ -237,7 +218,6 @@
{ required: true, message: '路由地址不能为空' },
{ max: 100, message: '路由地址不能大于100个字符', trigger: 'blur' },
],
webPerms: [{ required: true, message: '前端权限字符不能为空' }],
};
function validateForm(formRef) {

View File

@@ -23,9 +23,8 @@
/>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue';
import { menuApi } from '/@/api/system/menu/menu-api';
import _ from 'lodash';
import { onMounted, ref } from 'vue';
import { menuApi } from '/@/api/system/menu-api';
const props = defineProps({
value: Number,

View File

@@ -35,11 +35,6 @@ export const columns = ref([
dataIndex: 'component',
ellipsis: true,
},
{
title: '权限模式',
dataIndex: 'permsType',
width: 100,
},
{
title: '后端权限',
dataIndex: 'apiPerms',
@@ -50,26 +45,6 @@ export const columns = ref([
dataIndex: 'webPerms',
ellipsis: true,
},
{
title: '外链',
dataIndex: 'frameFlag',
width: 45,
},
{
title: '缓存',
dataIndex: 'cacheFlag',
width: 45,
},
{
title: '显示',
dataIndex: 'visibleFlag',
width: 45,
},
{
title: '禁用',
dataIndex: 'disabledFlag',
width: 45,
},
{
title: '顺序',
dataIndex: 'sort',

View File

@@ -31,7 +31,7 @@
查询
</a-button>
<a-button @click="resetQuery">
<a-button @click="resetQuery" class="smart-margin-left10">
<template #icon>
<SearchOutlined />
</template>
@@ -71,7 +71,7 @@
添加菜单
</a-button>
<a-button v-privilege="'system:menu:batch:delete'" type="primary" danger size="small" @click="batchDelete" :disabled="!hasSelected">
<a-button v-privilege="'system:menu:batchDelete'" type="primary" danger size="small" @click="batchDelete" :disabled="!hasSelected">
<template #icon>
<DeleteOutlined />
</template>
@@ -79,7 +79,7 @@
</a-button>
</div>
<div class="smart-table-setting-block">
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.SYSTEM.MENU" :refresh="query" />
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.SYSTEM.MENU" :refresh="query" />
</div>
</a-row>
@@ -130,7 +130,7 @@
<template v-if="column.dataIndex === 'operate'">
<div class="smart-table-operate">
<a-button v-privilege="'system:menu:update'" type="link" size="small" @click="showDrawer(record)">编辑</a-button>
<a-button v-privilege="'system:menu:delete'" danger type="link" @click="singleDelete(record)">删除</a-button>
<a-button v-privilege="'system:menu:batchDelete'" danger type="link" @click="singleDelete(record)">删除</a-button>
</div>
</template>
</template>
@@ -148,7 +148,7 @@
import MenuOperateModal from './components/menu-operate-modal.vue';
import { buildMenuTableTree, filterMenuByQueryForm } from './menu-data-handler';
import { columns } from './menu-list-table-columns';
import { menuApi } from '/@/api/system/menu/menu-api';
import { menuApi } from '/@/api/system/menu-api';
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { smartSentry } from '/@/lib/smart-sentry';