首页、个人中心内容调整

This commit is contained in:
meilin.huang
2021-09-11 14:04:09 +08:00
parent e02079fa72
commit b2d4803fff
64 changed files with 611 additions and 324 deletions

View File

@@ -75,10 +75,8 @@ func getErrMsg(rc *ReqCtx, err interface{}) string {
switch t := err.(type) {
case *biz.BizError:
errMsg = fmt.Sprintf("\n<-e errCode: %d, errMsg: %s", t.Code(), t.Error())
break
case error:
errMsg = fmt.Sprintf("\n<-e errMsg: %s\n%s", t.Error(), string(debug.Stack()))
break
case string:
errMsg = fmt.Sprintf("\n<-e errMsg: %s\n%s", t, string(debug.Stack()))
}

View File

@@ -0,0 +1,6 @@
import Api from '@/common/Api';
export const indexApi = {
getIndexCount: Api.create("/common/index/count", 'get'),
}

View File

@@ -8,25 +8,24 @@
<div class="home-card-first-right ml15">
<div class="flex-margin">
<div class="home-card-first-right-title">{{ `${currentTime}, ${getUserInfos.username}` }}</div>
<!-- <div class="home-card-first-right-msg mt5">超级管理</div> -->
</div>
</div>
</div>
</div>
</el-col>
<el-col :sm="6" class="mb15" v-for="(v, k) in topCardItemList" :key="k">
<el-col :sm="3" class="mb15" v-for="(v, k) in topCardItemList" :key="k">
<div class="home-card-item home-card-item-box" :style="{ background: v.color }">
<div class="home-card-item-flex">
<div class="home-card-item-title pb3">{{ v.title }}</div>
<div class="home-card-item-title-num pb6" :id="`titleNum${k + 1}`"></div>
<div class="home-card-item-tip pb3">{{ v.tip }}</div>
<div class="home-card-item-tip-num" :id="`tipNum${k + 1}`"></div>
<div class="home-card-item-title-num pb6" :id="v.id"></div>
<!-- <div class="home-card-item-tip pb3">{{ v.tip }}</div>
<div class="home-card-item-tip-num" :id="`tipNum${k + 1}`"></div> -->
</div>
<i :class="v.icon" :style="{ color: v.iconColor }"></i>
</div>
</el-col>
</el-row>
<el-row :gutter="15">
<!-- <el-row :gutter="15">
<el-col :xs="24" :sm="14" :md="14" :lg="16" :xl="16" class="mb15">
<el-card shadow="hover" header="商品销售情况">
<div style="height: 200px" ref="homeLaboratoryRef"></div>
@@ -89,7 +88,7 @@
<div style="height: 200px" ref="homeOvertimeRef"></div>
</el-card>
</el-col>
</el-row>
</el-row> -->
</div>
</template>
@@ -99,6 +98,7 @@ import { useStore } from '@/store/index.ts';
import * as echarts from 'echarts';
import { CountUp } from 'countup.js';
import { formatAxis } from '@/common/utils/formatTime.ts';
import { indexApi } from './api';
import { topCardItemList, environmentList, activitiesList } from './mock.ts';
export default {
name: 'Home',
@@ -129,21 +129,23 @@ export default {
],
},
});
// 当前时间提示语
const currentTime = computed(() => {
return formatAxis(new Date());
});
// 初始化数字滚动
const initNumCountUp = () => {
const initNumCountUp = async () => {
const res: any = await indexApi.getIndexCount.request()
nextTick(() => {
new CountUp('titleNum1', Math.random() * 10000).start();
new CountUp('titleNum2', Math.random() * 10000).start();
new CountUp('titleNum3', Math.random() * 10000).start();
new CountUp('tipNum1', Math.random() * 1000).start();
new CountUp('tipNum2', Math.random() * 1000).start();
new CountUp('tipNum3', Math.random() * 1000).start();
new CountUp('projectNum', res.projectNum).start();
new CountUp('machineNum', res.machineNum).start();
new CountUp('dbNum', res.dbNum).start();
new CountUp('redisNum', res.redisNum).start();
});
};
// 实验室使用情况
const initHomeLaboratory = () => {
const myChart = echarts.init(proxy.$refs.homeLaboratoryRef);
@@ -245,8 +247,8 @@ export default {
// 页面加载时
onMounted(() => {
initNumCountUp();
initHomeLaboratory();
initHomeOvertime();
// initHomeLaboratory();
// initHomeOvertime();
});
// 获取用户信息 vuex

View File

@@ -1,80 +1,93 @@
// 最顶部 card
export const topCardItemList = [
{
title: '今日访问人数',
titleNum: '123',
tip: '在场人数',
tipNum: '911',
color: '#F95959',
iconColor: '#F86C6B',
icon: 'iconfont icon-jinridaiban',
},
{
title: '实验室总数',
titleNum: '123',
tip: '使用中',
tipNum: '611',
color: '#8595F4',
iconColor: '#92A1F4',
icon: 'iconfont icon-AIshiyanshi',
},
{
title: '申请人数(月)',
titleNum: '123',
tip: '通过人数',
tipNum: '911',
color: '#FEBB50',
iconColor: '#FDC566',
icon: 'iconfont icon-shenqingkaiban',
},
{
title: '项目数',
id: 'projectNum',
num: '123',
tip: '通过人数',
tipNum: '911',
color: '#FEBB50',
iconColor: '#FDC566',
icon: 'el-icon-histogram',
},
{
title: 'Linux机器数',
id: 'machineNum',
num: '123',
tip: '在场人数',
tipNum: '911',
color: '#F95959',
iconColor: '#F86C6B',
icon: 'iconfont icon-jinridaiban',
},
{
title: '数据库总数',
id: "dbNum",
num: '123',
tip: '使用中',
tipNum: '611',
color: '#8595F4',
iconColor: '#92A1F4',
icon: 'iconfont icon-AIshiyanshi',
},
{
title: 'redis总数',
id: 'redisNum',
num: '123',
tip: '通过人数',
tipNum: '911',
color: '#1abc9c',
iconColor: '#FDC566',
icon: 'iconfont icon-shenqingkaiban',
},
];
// 环境监测
export const environmentList = [
{
icon: 'iconfont icon-yangan',
label: '烟感',
value: '2.1%OBS/M',
iconColor: '#F72B3F',
},
{
icon: 'iconfont icon-wendu',
label: '温度',
value: '30℃',
iconColor: '#91BFF8',
},
{
icon: 'iconfont icon-shidu',
label: '湿度',
value: '57%RH',
iconColor: '#88D565',
},
{
icon: 'iconfont icon-zaosheng',
label: '噪声',
value: '57DB',
iconColor: '#FBD4A0',
},
{
icon: 'iconfont icon-yangan',
label: '烟感',
value: '2.1%OBS/M',
iconColor: '#F72B3F',
},
{
icon: 'iconfont icon-wendu',
label: '温度',
value: '30℃',
iconColor: '#91BFF8',
},
{
icon: 'iconfont icon-shidu',
label: '湿度',
value: '57%RH',
iconColor: '#88D565',
},
{
icon: 'iconfont icon-zaosheng',
label: '噪声',
value: '57DB',
iconColor: '#FBD4A0',
},
];
// 动态信息
export const activitiesList = [
{
time1: '今天',
time2: '12:20:30',
title: '更名',
label: '正式更名为 vue-next-admin',
},
{
time1: '02-17',
time2: '12:20:30',
title: '页面',
label: '完成对首页的开发',
},
{
time1: '02-14',
time2: '12:20:30',
title: '页面',
label: '新增个人中心',
},
{
time1: '今天',
time2: '12:20:30',
title: '更名',
label: '正式更名为 vue-next-admin',
},
{
time1: '02-17',
time2: '12:20:30',
title: '页面',
label: '完成对首页的开发',
},
{
time1: '02-14',
time2: '12:20:30',
title: '页面',
label: '新增个人中心',
},
];

View File

@@ -16,7 +16,7 @@
</template>
<el-empty description="暂无通知" v-else></el-empty>
</div>
<div class="foot-box" @click="onGoToGiteeClick" v-if="newsList.length > 0">前往通知中心</div>
<div class="foot-box" @click="toMsgCenter" v-if="newsList.length > 0">前往通知中心</div>
</div>
</template>
@@ -27,15 +27,10 @@ export default {
setup() {
const state = reactive({
newsList: [
{
label: '关于版本发布的通知',
value: 'vue-next-admin基于 vue3 + CompositionAPI + typescript + vite + element plus正式发布时间2021年02月28日',
time: '2020-12-08',
},
{
label: '关于学习交流的通知',
value: 'QQ群号码 665452019欢迎小伙伴入群学习交流探讨',
time: '2020-12-08',
value: 'QQ群号码 119699946',
time: '2021-09-08',
},
],
});
@@ -44,12 +39,12 @@ export default {
state.newsList = [];
};
// 前往通知中心点击
const onGoToGiteeClick = () => {
window.open('https://gitee.com/lyt-top/vue-next-admin');
const toMsgCenter = () => {
// window.open('https://gitee.com/lyt-top/vue-next-admin');
};
return {
onAllReadClick,
onGoToGiteeClick,
toMsgCenter,
...toRefs(state),
};
},

View File

@@ -127,14 +127,17 @@ export default defineComponent({
getCaptcha();
return;
}
// 用户信息模拟数据
// 用户信息
const userInfos = {
username: state.loginForm.username,
// 头像
photo: letterAvatar(state.loginForm.username),
time: new Date().getTime(),
// // 菜单资源code数组
// menus: loginRes.menus,
permissions: loginRes.permissions,
lastLoginTime: loginRes.lastLoginTime,
lastLoginIp: loginRes.lastLoginIp,
};
// 存储用户信息到浏览器缓存

View File

@@ -0,0 +1,8 @@
import Api from '@/common/Api';
export const personApi = {
accountInfo: Api.create("/sys/accounts/self", 'get'),
updateAccount: Api.create("/sys/accounts/self", 'put'),
getMsgs: Api.create("/sys/accounts/msgs", 'get'),
}

View File

@@ -6,41 +6,36 @@
<el-card shadow="hover" header="个人信息">
<div class="personal-user">
<div class="personal-user-left">
<el-upload
class="h100 personal-user-left-upload"
action="https://jsonplaceholder.typicode.com/posts/"
multiple
:limit="1"
>
<el-upload class="h100 personal-user-left-upload" action="" multiple :limit="1">
<img :src="getUserInfos.photo" />
</el-upload>
</div>
<div class="personal-user-right">
<el-row>
<el-col :span="24" class="personal-title mb18"
>{{ currentTime }}admin生活变的再糟糕也不妨碍我变得更好
>{{ currentTime }}{{ getUserInfos.username }}生活变的再糟糕也不妨碍我变得更好
</el-col>
<el-col :span="24">
<el-row>
<el-col :xs="24" :sm="8" class="personal-item mb6">
<div class="personal-item-label">昵称</div>
<div class="personal-item-value">小柒</div>
<div class="personal-item-label">用户名</div>
<div class="personal-item-value">{{ getUserInfos.username }}</div>
</el-col>
<el-col :xs="24" :sm="16" class="personal-item mb6">
<div class="personal-item-label">身份</div>
<div class="personal-item-value">超级管理</div>
<div class="personal-item-label">角色</div>
<div class="personal-item-value">{{ roleInfo }}</div>
</el-col>
</el-row>
</el-col>
<el-col :span="24">
<el-row>
<el-col :xs="24" :sm="8" class="personal-item mb6">
<div class="personal-item-label">登录IP</div>
<div class="personal-item-value">192.168.1.1</div>
<div class="personal-item-label">上次登录IP</div>
<div class="personal-item-value">{{ getUserInfos.lastLoginIp }}</div>
</el-col>
<el-col :xs="24" :sm="16" class="personal-item mb6">
<div class="personal-item-label">登录时间</div>
<div class="personal-item-value">2021-02-05 18:47:26</div>
<div class="personal-item-label">上次登录时间</div>
<div class="personal-item-value">{{ $filters.dateFormat(getUserInfos.lastLoginTime) }}</div>
</el-col>
</el-row>
</el-col>
@@ -59,8 +54,8 @@
</template>
<div class="personal-info-box">
<ul class="personal-info-ul">
<li v-for="(v, k) in newsInfoList" :key="k" class="personal-info-li">
<a :href="v.link" target="_block" class="personal-info-li-title">{{ v.title }}</a>
<li v-for="(v, k) in msgs" :key="k" class="personal-info-li">
<a class="personal-info-li-title">{{ `[${getMsgTypeDesc(v.type)}] ${v.msg}` }}</a>
</li>
</ul>
</div>
@@ -68,7 +63,7 @@
</el-col>
<!-- 营销推荐 -->
<el-col :span="24">
<!-- <el-col :span="24">
<el-card shadow="hover" class="mt15" header="营销推荐">
<el-row :gutter="15" class="personal-recommend-row">
<el-col :sm="6" v-for="(v, k) in recommendList" :key="k" class="personal-recommend-col">
@@ -82,59 +77,35 @@
</el-col>
</el-row>
</el-card>
</el-col>
</el-col> -->
<!-- 更新信息 -->
<el-col :span="24">
<el-card shadow="hover" class="mt15 personal-edit" header="更新信息">
<div class="personal-edit-title">基本信息</div>
<el-form :model="personalForm" size="small" label-width="40px" class="mt35 mb35">
<el-form :model="accountForm" size="small" label-width="40px" class="mt35 mb35">
<el-row :gutter="35">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="昵称">
<el-input v-model="personalForm.name" placeholder="请输入昵称" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="邮箱">
<el-input v-model="personalForm.email" placeholder="请输入邮箱" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="签名">
<el-input v-model="personalForm.autograph" placeholder="请输入签名" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="职业">
<el-select v-model="personalForm.occupation" placeholder="请选择职业" clearable class="w100">
<el-option label="计算机 / 互联网 / 通信" value="1"></el-option>
<el-option label="生产 / 工艺 / 制造" value="2"></el-option>
<el-option label="医疗 / 护理 / 制药" value="3"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="手机">
<el-input v-model="personalForm.phone" placeholder="请输入手机" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="性别">
<el-select v-model="personalForm.sex" placeholder="请选择性别" clearable class="w100">
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
</el-select>
<el-form-item label="密码">
<el-input
type="password"
show-password
v-model="accountForm.password"
placeholder="请输入新密码"
clearable
></el-input>
</el-form-item>
</el-col>
<!-- -->
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<el-form-item>
<el-button type="primary" icon="el-icon-position">更新个人信息</el-button>
<el-button @click="updateAccount" type="primary" icon="el-icon-position">更新个人信息</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="personal-edit-title mb15">账号安全</div>
<!-- <div class="personal-edit-title mb15">账号安全</div>
<div class="personal-edit-safe-box">
<div class="personal-edit-safe-item">
<div class="personal-edit-safe-item-left">
@@ -178,7 +149,7 @@
<el-button type="text">立即设置</el-button>
</div>
</div>
</div>
</div> -->
</el-card>
</el-col>
</el-row>
@@ -186,26 +157,24 @@
</template>
<script lang="ts">
import { toRefs, reactive, computed } from 'vue';
import { toRefs, reactive, computed, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { formatAxis } from '@/common/utils/formatTime.ts';
import { newsInfoList, recommendList } from './mock.ts';
import { recommendList } from './mock.ts';
import { useStore } from '@/store/index.ts';
import { useRouter } from 'vue-router';
import { personApi } from './api';
export default {
name: 'personal',
setup() {
const store = useStore();
const router = useRouter();
const state = reactive({
newsInfoList,
accountInfo: {
roles: [],
},
msgs: [],
recommendList,
personalForm: {
name: '',
email: '',
autograph: '',
occupation: '',
phone: '',
sex: '',
accountForm: {
password: '',
},
});
// 当前时间提示语
@@ -218,9 +187,46 @@ export default {
return store.state.userInfos.userInfos;
});
const roleInfo = computed(() => {
if (state.accountInfo.roles.length == 0) {
return '';
}
return state.accountInfo.roles.map((val: any) => val.name).join('、');
});
onMounted(() => {
getAccountInfo();
getMsgs();
});
const getAccountInfo = async () => {
state.accountInfo = await personApi.accountInfo.request();
};
const updateAccount = async () => {
await personApi.updateAccount.request(state.accountForm);
ElMessage.success('更新成功');
};
const getMsgs = async () => {
const res = await personApi.getMsgs.request();
state.msgs = res.list;
};
const getMsgTypeDesc = (type: number) => {
if (type == 1) {
return '登录';
}
};
return {
getUserInfos,
currentTime,
roleInfo,
getAccountInfo,
getMsgs,
getMsgTypeDesc,
updateAccount,
...toRefs(state),
};
},

View File

@@ -1,31 +1,3 @@
// 消息通知
export const newsInfoList: Array<object> = [
{
title: '[发布] 2021年02月28日发布基于 vue3.x + vite v1.0.0 版本',
date: '02/28',
link: 'https://gitee.com/lyt-top/vue-next-admin'
},
{
title: '[发布] 2021年04月15日发布 vue2.x + webpack 重构版本',
date: '04/15',
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/'
},
{
title: '[重构] 2021年04月10日 重构 vue2.x + webpack v1.0.0 版本',
date: '04/10',
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/'
},
{
title: '[预览] 2020年12月08日基于 vue3.x 版本后台模板的预览',
date: '12/08',
link: 'http://lyt-top.gitee.io/vue-next-admin-preview/#/login'
},
{
title: '[预览] 2020年11月15日基于 vue2.x 版本后台模板的预览',
date: '11/15',
link: 'https://lyt-top.gitee.io/vue-prev-admin-preview/#/login'
}
];
// 营销推荐
export const recommendList: Array<object> = [

View File

@@ -144,7 +144,6 @@
<script lang='ts'>
import { toRefs, reactive, onMounted, defineComponent } from 'vue';
import { accountPermission } from '../permissions';
import RoleEdit from './RoleEdit.vue';
import AccountEdit from './AccountEdit.vue';
import enums from '../enums';

View File

@@ -1,64 +1,85 @@
<template>
<div class="menu-dialog">
<el-dialog :title="title" :destroy-on-close="true" v-model="dialogVisible" width="700px">
<el-dialog :title="title" :destroy-on-close="true" v-model="dialogVisible" width="850px">
<el-form :model="form" :inline="true" ref="menuForm" :rules="rules" label-width="95px" size="small">
<el-form-item prop="type" label="类型" required>
<el-select v-model="form.type" :disabled="typeDisabled" placeholder="请选择" width="50px">
<el-option v-for="item in enums.ResourceTypeEnum" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item prop="name" label="名称" required>
<el-input v-model.trim="form.name" placeholder="资源名[菜单名]" auto-complete="off"></el-input>
</el-form-item>
<el-form-item prop="code" label="path|code">
<el-input v-model.trim="form.code" placeholder="菜单不带/自动拼接父路径"></el-input>
</el-form-item>
<el-form-item label="序号" prop="weight" required>
<el-input v-model.trim="form.weight" type="number" placeholder="请输入序号"></el-input>
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" label="图标">
<icon-selector v-model="form.meta.icon" :isAllOn="true" />
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="路由名">
<el-input v-model.trim="form.meta.routeName" placeholder="请输入路由名称"></el-input>
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="组件">
<el-input v-model.trim="form.meta.component" placeholder="请输入组件名"></el-input>
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="是否缓存">
<el-select v-model="form.meta.isKeepAlive" placeholder="请选择">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="是否隐藏">
<el-select v-model="form.meta.isHide" placeholder="请选择" width="50px">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="tag不可删除">
<el-select v-model="form.meta.isAffix" placeholder="请选择">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="是否iframe">
<el-select @change="changeIsIframe" v-model="form.meta.isIframe" placeholder="请选择">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value && form.meta.isIframe" prop="code" label="iframe地址">
<el-input v-model.trim="form.meta.link" placeholder="请输入iframe url"></el-input>
</el-form-item>
<el-row :gutter="10">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item prop="type" label="类型" required>
<el-select v-model="form.type" :disabled="typeDisabled" placeholder="请选择" width="w100">
<el-option v-for="item in enums.ResourceTypeEnum" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item prop="name" label="名称" required>
<el-input v-model.trim="form.name" placeholder="资源名[菜单名]" auto-complete="off"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item prop="code" label="path|code">
<el-input v-model.trim="form.code" placeholder="菜单不带/自动拼接父路径"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="序号" prop="weight" required>
<el-input v-model.trim="form.weight" type="number" placeholder="请输入序号"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" label="图标">
<icon-selector v-model="form.meta.icon" :isAllOn="true" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="路由名">
<el-input v-model.trim="form.meta.routeName" placeholder="请输入路由名称"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="组件">
<el-input v-model.trim="form.meta.component" placeholder="请输入组件名"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="是否缓存">
<el-select v-model="form.meta.isKeepAlive" placeholder="请选择" width="w100">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="是否隐藏">
<el-select v-model="form.meta.isHide" placeholder="请选择" width="w100">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="tag不可删除">
<el-select v-model="form.meta.isAffix" placeholder="请选择" width="w100">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item v-if="form.type === enums.ResourceTypeEnum.MENU.value" prop="code" label="是否iframe">
<el-select @change="changeIsIframe" v-model="form.meta.isIframe" placeholder="请选择" width="w100">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item
v-if="form.type === enums.ResourceTypeEnum.MENU.value && form.meta.isIframe"
prop="code"
label="iframe地址"
width="w100"
>
<el-input v-model.trim="form.meta.link" placeholder="请输入iframe url"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div style="text-align: center" class="dialog-footer mt10">

View File

@@ -0,0 +1,23 @@
package api
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
)
type Index struct {
ProjectApp application.Project
MachineApp application.Machine
DbApp application.Db
RedisApp application.Redis
}
func (i *Index) Count(rc *ctx.ReqCtx) {
rc.ResData = map[string]interface{}{
"projectNum": i.ProjectApp.Count(new(entity.Project)),
"machineNum": i.MachineApp.Count(new(entity.Machine)),
"dbNum": i.DbApp.Count(new(entity.Db)),
"redisNum": i.RedisApp.Count(new(entity.Redis)),
}
}

View File

@@ -0,0 +1,26 @@
package router
import (
"mayfly-go/base/ctx"
"mayfly-go/server/common/api"
devops_app "mayfly-go/server/devops/application"
"github.com/gin-gonic/gin"
)
func InitIndexRouter(router *gin.RouterGroup) {
index := router.Group("common/index")
i := &api.Index{
ProjectApp: devops_app.ProjectApp,
MachineApp: devops_app.MachineApp,
DbApp: devops_app.DbApp,
RedisApp: devops_app.RedisApp,
}
{
// 首页基本信息统计
index.GET("count", func(g *gin.Context) {
ctx.NewReqCtxWithGin(g).
Handle(i.Count)
})
}
}

View File

@@ -1,4 +1,4 @@
package apis
package api
import (
"fmt"
@@ -7,8 +7,8 @@ import (
"mayfly-go/base/ginx"
"mayfly-go/base/model"
"mayfly-go/base/utils"
"mayfly-go/server/devops/apis/form"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/api/form"
"mayfly-go/server/devops/api/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
"strconv"

View File

@@ -1,12 +1,12 @@
package apis
package api
import (
"mayfly-go/base/biz"
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/utils"
"mayfly-go/server/devops/apis/form"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/api/form"
"mayfly-go/server/devops/api/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/infrastructure/machine"
@@ -78,6 +78,10 @@ func (m *Machine) WsSSH(g *gin.Context) {
if err = ctx.PermissionHandler(rc); err != nil {
panic(biz.NewBizErr("没有权限"))
}
// 演示环境禁止非admin用户执行
if rc.LoginAccount.Username != "admin" {
panic(biz.NewBizErrCode(401, "非admin用户无权该操作"))
}
cols := ginx.QueryInt(g, "cols", 80)
rows := ginx.QueryInt(g, "rows", 40)

View File

@@ -1,4 +1,4 @@
package apis
package api
import (
"fmt"
@@ -8,8 +8,8 @@ import (
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/utils"
"mayfly-go/server/devops/apis/form"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/api/form"
"mayfly-go/server/devops/api/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
"strconv"

View File

@@ -1,4 +1,4 @@
package apis
package api
import (
"fmt"
@@ -6,8 +6,8 @@ import (
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/utils"
"mayfly-go/server/devops/apis/form"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/api/form"
"mayfly-go/server/devops/api/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
"strconv"

View File

@@ -1,11 +1,11 @@
package apis
package api
import (
"fmt"
"mayfly-go/base/biz"
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/api/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
sys_applicaiton "mayfly-go/server/sys/application"

View File

@@ -1,12 +1,12 @@
package apis
package api
import (
"mayfly-go/base/biz"
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/utils"
"mayfly-go/server/devops/apis/form"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/api/form"
"mayfly-go/server/devops/api/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
"strconv"

View File

@@ -20,6 +20,8 @@ type Db interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Count(condition *entity.Db) int64
// 根据条件获取
GetDbBy(condition *entity.Db, cols ...string) error
@@ -50,6 +52,10 @@ func (d *dbAppImpl) GetPageList(condition *entity.Db, pageParam *model.PageParam
return d.dbRepo.GetDbList(condition, pageParam, toEntity, orderBy...)
}
func (d *dbAppImpl) Count(condition *entity.Db) int64 {
return d.dbRepo.Count(condition)
}
// 根据条件获取
func (d *dbAppImpl) GetDbBy(condition *entity.Db, cols ...string) error {
return d.dbRepo.GetDb(condition, cols...)

View File

@@ -17,6 +17,8 @@ type Machine interface {
Save(entity *entity.Machine)
Count(condition *entity.Machine) int64
Delete(id uint64)
// 根据id获取
@@ -40,6 +42,10 @@ func (m *machineAppImpl) GetMachineList(condition *entity.Machine, pageParam *mo
return m.machineRepo.GetMachineList(condition, pageParam, toEntity, orderBy...)
}
func (m *machineAppImpl) Count(condition *entity.Machine) int64 {
return m.machineRepo.Count(condition)
}
// 根据条件获取机器信息
func (m *machineAppImpl) Save(me *entity.Machine) {
biz.ErrIsNilAppendErr(machine.TestConn(me), "该机器无法连接: %s")

View File

@@ -12,6 +12,8 @@ type Project interface {
// 分页获取项目信息列表
GetPageList(condition *entity.Project, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Count(condition *entity.Project) int64
ListProjectByIds(ids []uint64, toEntity interface{}, orderBy ...string)
SaveProject(project *entity.Project)
@@ -52,6 +54,10 @@ func (p *projectAppImpl) GetPageList(condition *entity.Project, pageParam *model
return p.projectRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
func (p *projectAppImpl) Count(condition *entity.Project) int64 {
return p.projectRepo.Count(condition)
}
func (p *projectAppImpl) ListProjectByIds(ids []uint64, toEntity interface{}, orderBy ...string) {
p.projectRepo.GetByIdIn(ids, toEntity, orderBy...)
}

View File

@@ -18,6 +18,8 @@ type Redis interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.Redis, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Count(condition *entity.Redis) int64
// 根据id获取
GetById(id uint64, cols ...string) *entity.Redis
@@ -46,6 +48,10 @@ func (r *redisAppImpl) GetPageList(condition *entity.Redis, pageParam *model.Pag
return r.redisRepo.GetRedisList(condition, pageParam, toEntity, orderBy...)
}
func (r *redisAppImpl) Count(condition *entity.Redis) int64 {
return r.redisRepo.Count(condition)
}
// 根据id获取
func (r *redisAppImpl) GetById(id uint64, cols ...string) *entity.Redis {
return r.redisRepo.GetById(id, cols...)

View File

@@ -9,6 +9,8 @@ type Db interface {
// 分页获取机器信息列表
GetDbList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Count(condition *entity.Db) int64
// 根据条件获取账号信息
GetDb(condition *entity.Db, cols ...string) error

View File

@@ -9,6 +9,8 @@ type Machine interface {
// 分页获取机器信息列表
GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Count(condition *entity.Machine) int64
// 根据条件获取账号信息
GetMachine(condition *entity.Machine, cols ...string) error

View File

@@ -8,6 +8,8 @@ import (
type Project interface {
GetPageList(condition *entity.Project, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Count(condition *entity.Project) int64
GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string)
Save(p *entity.Project)

View File

@@ -9,6 +9,8 @@ type Redis interface {
// 分页获取机器信息列表
GetRedisList(condition *entity.Redis, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Count(condition *entity.Redis) int64
// 根据id获取
GetById(id uint64, cols ...string) *entity.Redis

View File

@@ -16,6 +16,10 @@ func (d *dbRepo) GetDbList(condition *entity.Db, pageParam *model.PageParam, toE
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
func (d *dbRepo) Count(condition *entity.Db) int64 {
return model.CountBy(condition)
}
// 根据条件获取账号信息
func (d *dbRepo) GetDb(condition *entity.Db, cols ...string) error {
return model.GetBy(condition, cols...)

View File

@@ -15,6 +15,10 @@ func (m *machineRepo) GetMachineList(condition *entity.Machine, pageParam *model
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
func (m *machineRepo) Count(condition *entity.Machine) int64 {
return model.CountBy(condition)
}
// 根据条件获取账号信息
func (m *machineRepo) GetMachine(condition *entity.Machine, cols ...string) error {
return model.GetBy(condition, cols...)

View File

@@ -15,6 +15,10 @@ func (p *projectRepo) GetPageList(condition *entity.Project, pageParam *model.Pa
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
func (p *projectRepo) Count(condition *entity.Project) int64 {
return model.CountBy(condition)
}
func (p *projectRepo) GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string) {
model.GetByIdIn(new(entity.Project), toEntity, ids, orderBy...)
}

View File

@@ -16,6 +16,10 @@ func (r *redisRepo) GetRedisList(condition *entity.Redis, pageParam *model.PageP
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
func (r *redisRepo) Count(condition *entity.Redis) int64 {
return model.CountBy(condition)
}
// 根据id获取
func (r *redisRepo) GetById(id uint64, cols ...string) *entity.Redis {
rd := new(entity.Redis)

View File

@@ -2,7 +2,7 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/api"
"mayfly-go/server/devops/application"
"github.com/gin-gonic/gin"
@@ -11,7 +11,7 @@ import (
func InitDbRouter(router *gin.RouterGroup) {
db := router.Group("dbs")
{
d := &apis.Db{DbApp: application.DbApp}
d := &api.Db{DbApp: application.DbApp}
// 获取所有数据库列表
db.GET("", func(c *gin.Context) {
rc := ctx.NewReqCtxWithGin(c)

View File

@@ -2,14 +2,14 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/api"
"mayfly-go/server/devops/application"
"github.com/gin-gonic/gin"
)
func InitMachineRouter(router *gin.RouterGroup) {
m := &apis.Machine{MachineApp: application.MachineApp}
m := &api.Machine{MachineApp: application.MachineApp}
db := router.Group("machines")
{
db.GET("", func(c *gin.Context) {

View File

@@ -2,7 +2,7 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/api"
"mayfly-go/server/devops/application"
"github.com/gin-gonic/gin"
@@ -11,7 +11,7 @@ import (
func InitMachineFileRouter(router *gin.RouterGroup) {
machineFile := router.Group("machines")
{
mf := &apis.MachineFile{
mf := &api.MachineFile{
MachineFileApp: application.MachineFileApp,
MachineApp: application.MachineApp}

View File

@@ -2,7 +2,7 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/api"
"mayfly-go/server/devops/application"
"github.com/gin-gonic/gin"
@@ -11,7 +11,7 @@ import (
func InitMachineScriptRouter(router *gin.RouterGroup) {
machines := router.Group("machines")
{
ms := &apis.MachineScript{
ms := &api.MachineScript{
MachineScriptApp: application.MachineScriptApp,
MachineApp: application.MachineApp}

View File

@@ -2,7 +2,7 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/api"
"mayfly-go/server/devops/application"
sys_applicaiton "mayfly-go/server/sys/application"
@@ -10,7 +10,7 @@ import (
)
func InitProjectRouter(router *gin.RouterGroup) {
m := &apis.Project{
m := &api.Project{
ProjectApp: application.ProjectApp,
AccountApp: sys_applicaiton.AccountApp}

View File

@@ -2,7 +2,7 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/api"
"mayfly-go/server/devops/application"
"github.com/gin-gonic/gin"
@@ -11,7 +11,7 @@ import (
func InitRedisRouter(router *gin.RouterGroup) {
redis := router.Group("redis")
{
rs := &apis.Redis{
rs := &api.Redis{
RedisApp: application.RedisApp,
}

View File

@@ -4,8 +4,10 @@ import (
"fmt"
"mayfly-go/base/config"
"mayfly-go/base/middleware"
devops_routers "mayfly-go/server/devops/routers"
sys_routers "mayfly-go/server/sys/routers"
common_index_router "mayfly-go/server/common/router"
devops_router "mayfly-go/server/devops/router"
gw_router "mayfly-go/server/gateway/router"
sys_router "mayfly-go/server/sys/router"
"net/http"
"github.com/gin-gonic/gin"
@@ -45,18 +47,21 @@ func InitRouter() *gin.Engine {
// 设置路由组
api := router.Group("/api")
{
sys_routers.InitCaptchaRouter(api)
common_index_router.InitIndexRouter(api)
sys_routers.InitAccountRouter(api) // 注册account路由
sys_routers.InitResourceRouter(api)
sys_routers.InitRoleRouter(api)
sys_router.InitCaptchaRouter(api)
sys_router.InitAccountRouter(api) // 注册account路由
sys_router.InitResourceRouter(api)
sys_router.InitRoleRouter(api)
devops_routers.InitProjectRouter(api)
devops_routers.InitDbRouter(api)
devops_routers.InitRedisRouter(api)
devops_routers.InitMachineRouter(api)
devops_routers.InitMachineScriptRouter(api)
devops_routers.InitMachineFileRouter(api)
devops_router.InitProjectRouter(api)
devops_router.InitDbRouter(api)
devops_router.InitRedisRouter(api)
devops_router.InitMachineRouter(api)
devops_router.InitMachineScriptRouter(api)
devops_router.InitMachineFileRouter(api)
gw_router.InitServiceRouter(api)
}
return router

View File

@@ -1,4 +1,4 @@
package apis
package api
import (
"fmt"
@@ -9,8 +9,8 @@ import (
"mayfly-go/base/global"
"mayfly-go/base/httpclient"
"mayfly-go/base/utils"
"mayfly-go/server/sys/apis/form"
"mayfly-go/server/sys/apis/vo"
"mayfly-go/server/sys/api/form"
"mayfly-go/server/sys/api/vo"
"mayfly-go/server/sys/application"
"mayfly-go/server/sys/domain/entity"
"strconv"
@@ -22,8 +22,11 @@ type Account struct {
AccountApp application.Account
ResourceApp application.Resource
RoleApp application.Role
MsgApp application.Msg
}
/** 登录者个人相关操作 **/
// @router /accounts/login [post]
func (a *Account) Login(rc *ctx.ReqCtx) {
loginForm := &form.LoginForm{}
@@ -34,7 +37,7 @@ func (a *Account) Login(rc *ctx.ReqCtx) {
biz.IsTrue(captcha.Verify(loginForm.Cid, loginForm.Captcha), "验证码错误")
account := &entity.Account{Username: loginForm.Username, Password: utils.Md5(loginForm.Password)}
biz.ErrIsNil(a.AccountApp.GetAccount(account, "Id", "Username", "Password", "Status"), "用户名或密码错误")
biz.ErrIsNil(a.AccountApp.GetAccount(account, "Id", "Username", "Status", "LastLoginTime", "LastLoginIp"), "用户名或密码错误")
biz.IsTrue(account.IsEnable(), "该账号不可用")
var resources vo.AccountResourceVOList
@@ -57,10 +60,12 @@ func (a *Account) Login(rc *ctx.ReqCtx) {
go a.saveLogin(account, rc.GinCtx.ClientIP())
rc.ResData = map[string]interface{}{
"token": ctx.CreateToken(account.Id, account.Username),
"username": account.Username,
"menus": menus.ToTrees(0),
"permissions": permissions,
"token": ctx.CreateToken(account.Id, account.Username),
"username": account.Username,
"lastLoginTime": account.LastLoginTime,
"lastLoginIp": account.LastLoginIp,
"menus": menus.ToTrees(0),
"permissions": permissions,
}
}
@@ -70,8 +75,20 @@ func (a *Account) saveLogin(account *entity.Account, ip string) {
now := time.Now()
updateAccount := &entity.Account{LastLoginTime: &now}
updateAccount.Id = account.Id
updateAccount.LastLoginIp = ip
a.AccountApp.Update(updateAccount)
// 创建登录消息
loginMsg := &entity.Msg{
RecipientId: int64(account.Id),
Msg: fmt.Sprintf("于%s登录", now.Format("2006-01-02 15:04:05")),
Type: 1,
}
loginMsg.CreateTime = &now
loginMsg.Creator = account.Username
loginMsg.CreatorId = account.Id
a.MsgApp.Create(loginMsg)
bodyMap, err := httpclient.NewRequest(fmt.Sprintf("http://ip-api.com/json/%s?lang=zh-CN", ip)).Get().BodyToMap()
if err != nil {
global.Log.Errorf("获取客户端ip地址信息失败%s", err.Error())
@@ -80,10 +97,47 @@ func (a *Account) saveLogin(account *entity.Account, ip string) {
if bodyMap["status"].(string) == "fail" {
return
}
msg := fmt.Sprintf("%s-%s登录", bodyMap["regionName"], bodyMap["city"])
fmt.Printf(msg)
msg := fmt.Sprintf("%s于%s-%s登录", account.Username, bodyMap["regionName"], bodyMap["city"])
global.Log.Info(msg)
}
// 获取个人账号信息
func (a Account) AccountInfo(rc *ctx.ReqCtx) {
ap := new(vo.AccountPersonVO)
// 角色信息
roles := new([]vo.AccountRoleVO)
a.RoleApp.GetAccountRoles(rc.LoginAccount.Id, roles)
ap.Roles = *roles
rc.ResData = ap
}
// 更新个人账号信息
func (a Account) UpdateAccount(rc *ctx.ReqCtx) {
updateForm := &form.AccountUpdateForm{}
ginx.BindJsonAndValid(rc.GinCtx, updateForm)
updateAccount := new(entity.Account)
utils.Copy(updateAccount, updateForm)
// 账号id为登录者账号
updateAccount.Id = rc.LoginAccount.Id
if updateAccount.Password != "" {
updateAccount.Password = utils.Md5(updateAccount.Password)
}
a.AccountApp.Update(updateAccount)
}
// 获取账号接受的消息列表
func (a Account) GetMsgs(rc *ctx.ReqCtx) {
condition := &entity.Msg{
RecipientId: int64(rc.LoginAccount.Id),
}
rc.ResData = a.MsgApp.GetPageList(condition, ginx.GetPageParam(rc.GinCtx), new([]entity.Msg))
}
/** 后台账号操作 **/
// @router /accounts [get]
func (a *Account) Accounts(rc *ctx.ReqCtx) {
condition := &entity.Account{}

View File

@@ -1,4 +1,4 @@
package apis
package api
import (
"mayfly-go/base/captcha"

View File

@@ -5,7 +5,5 @@ type AccountCreateForm struct {
}
type AccountUpdateForm struct {
Password *string `json:"password" binding:"required,min=6,max=16"`
RePassword *string `json:"rePassword" binding:"required,min=4,max=16"`
Password *string `json:"password" binding:"min=6,max=16"`
}

View File

@@ -1,12 +1,12 @@
package apis
package api
import (
"encoding/json"
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/utils"
"mayfly-go/server/sys/apis/form"
"mayfly-go/server/sys/apis/vo"
"mayfly-go/server/sys/api/form"
"mayfly-go/server/sys/api/vo"
"mayfly-go/server/sys/application"
"mayfly-go/server/sys/domain/entity"
)

View File

@@ -1,11 +1,11 @@
package apis
package api
import (
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/utils"
"mayfly-go/server/sys/apis/form"
"mayfly-go/server/sys/apis/vo"
"mayfly-go/server/sys/api/form"
"mayfly-go/server/sys/api/vo"
"mayfly-go/server/sys/application"
"mayfly-go/server/sys/domain/entity"
"strconv"

View File

@@ -12,9 +12,15 @@ type AccountManageVO struct {
LastLoginTime *time.Time `json:"lastLoginTime"`
}
// 账号角色信息
type AccountRoleVO struct {
Name *string `json:"name"`
Status int `json:"status"`
CreateTime *time.Time `json:"createTime"`
Creator string `json:"creator"`
}
// 账号个人信息
type AccountPersonVO struct {
Roles []AccountRoleVO `json:"roles"` // 角色信息
}

View File

@@ -0,0 +1,30 @@
package application
import (
"mayfly-go/base/model"
"mayfly-go/server/sys/domain/entity"
"mayfly-go/server/sys/domain/repository"
"mayfly-go/server/sys/infrastructure/persistence"
)
type Msg interface {
GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Create(msg *entity.Msg)
}
type msgAppImpl struct {
msgRepo repository.Msg
}
var MsgApp Msg = &msgAppImpl{
msgRepo: persistence.MsgDao,
}
func (a *msgAppImpl) GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return a.msgRepo.GetPageList(condition, pageParam, toEntity)
}
func (a *msgAppImpl) Create(msg *entity.Msg) {
a.msgRepo.Insert(msg)
}

View File

@@ -12,6 +12,7 @@ type Account struct {
Password string `json:"-"`
Status int8 `json:"status"`
LastLoginTime *time.Time `json:"lastLoginTime"`
LastLoginIp string `json:"lastLoginIp"`
}
func (a *Account) TableName() string {

View File

@@ -0,0 +1,20 @@
package entity
import (
"time"
)
type Msg struct {
Id uint64 `json:"id"`
CreateTime *time.Time `json:"createTime"`
CreatorId uint64 `json:"creatorId"`
Creator string `json:"creator"`
Type int `json:"type"`
Msg string `json:"msg"`
RecipientId int64 `json:"recipientId"` // 接受者id
}
func (a *Msg) TableName() string {
return "t_sys_msg"
}

View File

@@ -0,0 +1,12 @@
package repository
import (
"mayfly-go/base/model"
"mayfly-go/server/sys/domain/entity"
)
type Msg interface {
GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Insert(msg *entity.Msg)
}

View File

@@ -0,0 +1,20 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/sys/domain/entity"
"mayfly-go/server/sys/domain/repository"
)
type msgRepo struct{}
var MsgDao repository.Msg = &msgRepo{}
func (m *msgRepo) GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity)
}
func (m *msgRepo) Insert(account *entity.Msg) {
biz.ErrIsNil(model.Insert(account), "新增消息记录失败")
}

View File

@@ -2,7 +2,7 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/sys/apis"
"mayfly-go/server/sys/api"
"mayfly-go/server/sys/application"
"github.com/gin-gonic/gin"
@@ -10,10 +10,11 @@ import (
func InitAccountRouter(router *gin.RouterGroup) {
account := router.Group("sys/accounts")
a := &apis.Account{
a := &api.Account{
AccountApp: application.AccountApp,
ResourceApp: application.ResourceApp,
RoleApp: application.RoleApp,
MsgApp: application.MsgApp,
}
{
// 用户登录
@@ -22,6 +23,22 @@ func InitAccountRouter(router *gin.RouterGroup) {
rc.Handle(a.Login)
})
// 获取个人账号信息
account.GET("/self", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(a.AccountInfo)
})
// 更新个人账号信息
account.PUT("/self", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(a.UpdateAccount)
})
account.GET("/msgs", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(a.GetMsgs)
})
/** 后台管理接口 **/
// 获取所有用户列表
account.GET("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(a.Accounts)

View File

@@ -2,7 +2,7 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/sys/apis"
"mayfly-go/server/sys/api"
"github.com/gin-gonic/gin"
)
@@ -11,7 +11,7 @@ func InitCaptchaRouter(router *gin.RouterGroup) {
captcha := router.Group("sys/captcha")
{
captcha.GET("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithNeedToken(false).Handle(apis.GenerateCaptcha)
ctx.NewReqCtxWithGin(c).WithNeedToken(false).Handle(api.GenerateCaptcha)
})
}
}

View File

@@ -2,14 +2,14 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/sys/apis"
"mayfly-go/server/sys/api"
"mayfly-go/server/sys/application"
"github.com/gin-gonic/gin"
)
func InitResourceRouter(router *gin.RouterGroup) {
r := &apis.Resource{ResourceApp: application.ResourceApp}
r := &api.Resource{ResourceApp: application.ResourceApp}
db := router.Group("sys/resources")
{
// db.GET("/account", func(c *gin.Context) {

View File

@@ -2,14 +2,14 @@ package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/sys/apis"
"mayfly-go/server/sys/api"
"mayfly-go/server/sys/application"
"github.com/gin-gonic/gin"
)
func InitRoleRouter(router *gin.RouterGroup) {
r := &apis.Role{
r := &api.Role{
RoleApp: application.RoleApp,
ResourceApp: application.ResourceApp,
}