完善授权凭证授权
This commit is contained in:
parent
f4ec963f85
commit
f38c77c202
7
main.go
7
main.go
@ -10,6 +10,7 @@ import (
|
|||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
"gorm.io/driver/sqlite"
|
"gorm.io/driver/sqlite"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
"io"
|
"io"
|
||||||
"next-terminal/pkg/api"
|
"next-terminal/pkg/api"
|
||||||
"next-terminal/pkg/config"
|
"next-terminal/pkg/config"
|
||||||
@ -69,7 +70,7 @@ func Run() error {
|
|||||||
global.Config.Mysql.Database,
|
global.Config.Mysql.Database,
|
||||||
)
|
)
|
||||||
global.DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
|
global.DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
|
||||||
//Logger: logger.Default.LogMode(logger.Info),
|
Logger: logger.Default.LogMode(logger.Info),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
global.DB, err = gorm.Open(sqlite.Open(global.Config.Sqlite.File), &gorm.Config{})
|
global.DB, err = gorm.Open(sqlite.Open(global.Config.Sqlite.File), &gorm.Config{})
|
||||||
@ -118,7 +119,9 @@ func Run() error {
|
|||||||
if err := global.DB.AutoMigrate(&model.Property{}); err != nil {
|
if err := global.DB.AutoMigrate(&model.Property{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := global.DB.AutoMigrate(&model.Resource{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := global.DB.AutoMigrate(&model.Num{}); err != nil {
|
if err := global.DB.AutoMigrate(&model.Num{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
26
pkg/api/resource.go
Normal file
26
pkg/api/resource.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"next-terminal/pkg/model"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ResourceGetAssignEndPoint(c echo.Context) error {
|
||||||
|
resourceId := c.Param("id")
|
||||||
|
userIds, err := model.FindUserIdsByResourceId(resourceId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, userIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceOverwriteAssignEndPoint(c echo.Context) error {
|
||||||
|
resourceId := c.Param("id")
|
||||||
|
userIds := c.QueryParam("userIds")
|
||||||
|
uIds := strings.Split(userIds, ",")
|
||||||
|
|
||||||
|
model.OverwriteUserIdsByResourceId(resourceId, uIds)
|
||||||
|
|
||||||
|
return Success(c, "")
|
||||||
|
}
|
@ -102,15 +102,11 @@ func SetupRoutes() *echo.Echo {
|
|||||||
sessions.GET("/:id", SessionGetEndpoint)
|
sessions.GET("/:id", SessionGetEndpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
//tags := e.Group("/tags")
|
resources := e.Group("/resources")
|
||||||
//{
|
{
|
||||||
// tags.POST("", TagAllEndpoint)
|
resources.GET("/:id/assign", ResourceGetAssignEndPoint)
|
||||||
// tags.GET("/paging", TagPagingEndpoint)
|
resources.POST("/:id/assign", ResourceOverwriteAssignEndPoint)
|
||||||
// tags.POST("", TagCreateEndpoint)
|
}
|
||||||
// tags.PUT("/:id", TagUpdateEndpoint)
|
|
||||||
// tags.DELETE("/:id", TagDeleteEndpoint)
|
|
||||||
// tags.GET("/:id", TagGetEndpoint)
|
|
||||||
//}
|
|
||||||
|
|
||||||
e.GET("/properties", PropertyGetEndpoint)
|
e.GET("/properties", PropertyGetEndpoint)
|
||||||
e.PUT("/properties", PropertyUpdateEndpoint)
|
e.PUT("/properties", PropertyUpdateEndpoint)
|
||||||
|
@ -58,24 +58,32 @@ func FindAssetByConditions(protocol string) (o []Asset, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func FindPageAsset(pageIndex, pageSize int, name, protocol, tags string) (o []AssetVo, total int64, err error) {
|
func FindPageAsset(pageIndex, pageSize int, name, protocol, tags string) (o []AssetVo, total int64, err error) {
|
||||||
db := global.DB
|
db := global.DB.Table("assets").Select("assets.id,assets.name,assets.ip,assets.port,assets.protocol,assets.active,assets.owner,assets.created, users.nickname as owner_name").Joins("left join users on assets.owner = users.id")
|
||||||
db = db.Table("assets").Select("assets.id,assets.name,assets.ip,assets.port,assets.protocol,assets.active,assets.owner,assets.created, users.nickname as creator_name").Joins("left join users on assets.owner = users.id")
|
dbCounter := global.DB.Table("assets").Select("assets.id,assets.name,assets.ip,assets.port,assets.protocol,assets.active,assets.owner,assets.created, users.nickname as owner_name").Joins("left join users on assets.owner = users.id")
|
||||||
|
|
||||||
if len(name) > 0 {
|
if len(name) > 0 {
|
||||||
db = db.Where("assets.name like ?", "%"+name+"%")
|
db = db.Where("assets.name like ?", "%"+name+"%")
|
||||||
|
dbCounter = dbCounter.Where("assets.name like ?", "%"+name+"%")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(protocol) > 0 {
|
if len(protocol) > 0 {
|
||||||
db = db.Where("assets.protocol = ?", protocol)
|
db = db.Where("assets.protocol = ?", protocol)
|
||||||
|
dbCounter = dbCounter.Where("assets.protocol = ?", protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tags) > 0 {
|
if len(tags) > 0 {
|
||||||
tagArr := strings.Split(tags, ",")
|
tagArr := strings.Split(tags, ",")
|
||||||
for i := range tagArr {
|
for i := range tagArr {
|
||||||
db = db.Where("find_in_set(?, assets.tags)", tagArr[i])
|
db = db.Where("find_in_set(?, assets.tags)", tagArr[i])
|
||||||
|
dbCounter = dbCounter.Where("find_in_set(?, assets.tags)", tagArr[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Order("assets.created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Count(&total).Error
|
err = dbCounter.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
err = db.Order("assets.created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
|
||||||
if o == nil {
|
if o == nil {
|
||||||
o = make([]AssetVo, 0)
|
o = make([]AssetVo, 0)
|
||||||
|
@ -35,6 +35,7 @@ type CredentialVo struct {
|
|||||||
Created utils.JsonTime `json:"created"`
|
Created utils.JsonTime `json:"created"`
|
||||||
Owner string `json:"owner"`
|
Owner string `json:"owner"`
|
||||||
OwnerName string `json:"ownerName"`
|
OwnerName string `json:"ownerName"`
|
||||||
|
SharerCount int64 `json:"sharerCount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindAllCredential() (o []Credential, err error) {
|
func FindAllCredential() (o []Credential, err error) {
|
||||||
@ -43,16 +44,24 @@ func FindAllCredential() (o []Credential, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func FindPageCredential(pageIndex, pageSize int, name, owner string) (o []CredentialVo, total int64, err error) {
|
func FindPageCredential(pageIndex, pageSize int, name, owner string) (o []CredentialVo, total int64, err error) {
|
||||||
db := global.DB
|
db := global.DB.Table("credentials").Select("credentials.id,credentials.name,credentials.type,credentials.username,credentials.owner,credentials.created,users.nickname as owner_name,COUNT(resources.user_id) as sharer_count").Joins("left join users on credentials.owner = users.id").Joins("left join resources on credentials.id = resources.resource_id").Group("credentials.id")
|
||||||
db = db.Table("credentials").Select("credentials.id,credentials.name,credentials.type,credentials.username,credentials.owner,credentials.created,users.nickname as owner_name").Joins("left join users on credentials.owner = users.id")
|
dbCounter := global.DB.Table("credentials").Select("DISTINCT credentials.id,credentials.name,credentials.type,credentials.username,credentials.owner,credentials.created,users.nickname as owner_name").Joins("left join users on credentials.owner = users.id").Joins("left join resources on credentials.id = resources.resource_id")
|
||||||
if len(name) > 0 {
|
|
||||||
db = db.Where("credentials.name like ?", "%"+name+"%")
|
|
||||||
}
|
|
||||||
if len(owner) > 0 {
|
if len(owner) > 0 {
|
||||||
db = db.Where("credentials.owner = ?", owner)
|
db = db.Where("credentials.owner = ? or resources.user_id = ?", owner, owner)
|
||||||
|
dbCounter = dbCounter.Where("credentials.owner = ? or resources.user_id = ?", owner, owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Order("credentials.created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Count(&total).Error
|
if len(name) > 0 {
|
||||||
|
db = db.Where("credentials.name like ?", "%"+name+"%")
|
||||||
|
dbCounter = dbCounter.Where("credentials.name like ?", "%"+name+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dbCounter.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
err = db.Order("credentials.created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
if o == nil {
|
if o == nil {
|
||||||
o = make([]CredentialVo, 0)
|
o = make([]CredentialVo, 0)
|
||||||
}
|
}
|
||||||
|
45
pkg/model/resource.go
Normal file
45
pkg/model/resource.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"next-terminal/pkg/global"
|
||||||
|
"next-terminal/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Resource struct {
|
||||||
|
ID string `gorm:"primary_key" json:"name"`
|
||||||
|
ResourceId string `json:"resourceId"`
|
||||||
|
UserId string `json:"userId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resource) TableName() string {
|
||||||
|
return "resources"
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindUserIdsByResourceId(resourceId string) (r []string, err error) {
|
||||||
|
db := global.DB
|
||||||
|
err = db.Table("resources").Select("user_id").Where("resource_id = ?", resourceId).Find(&r).Error
|
||||||
|
if r == nil {
|
||||||
|
r = make([]string, 0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func OverwriteUserIdsByResourceId(resourceId string, userIds []string) {
|
||||||
|
db := global.DB.Begin()
|
||||||
|
db.Where("resource_id = ?", resourceId).Delete(&Resource{})
|
||||||
|
|
||||||
|
for i := range userIds {
|
||||||
|
userId := userIds[i]
|
||||||
|
if len(userId) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
id := utils.Sign([]string{resourceId, userId})
|
||||||
|
resource := &Resource{
|
||||||
|
ID: id,
|
||||||
|
ResourceId: resourceId,
|
||||||
|
UserId: userId,
|
||||||
|
}
|
||||||
|
_ = db.Create(resource).Error
|
||||||
|
}
|
||||||
|
db.Commit()
|
||||||
|
}
|
@ -2,6 +2,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -9,7 +10,9 @@ import (
|
|||||||
"image/png"
|
"image/png"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
@ -121,10 +124,10 @@ func IsFile(path string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 去除重复元素
|
// 去除重复元素
|
||||||
func Distinct(list []string) []string {
|
func Distinct(a []string) []string {
|
||||||
result := make([]string, 0, len(list))
|
result := make([]string, 0, len(a))
|
||||||
temp := map[string]struct{}{}
|
temp := map[string]struct{}{}
|
||||||
for _, item := range list {
|
for _, item := range a {
|
||||||
if _, ok := temp[item]; !ok {
|
if _, ok := temp[item]; !ok {
|
||||||
temp[item] = struct{}{}
|
temp[item] = struct{}{}
|
||||||
result = append(result, item)
|
result = append(result, item)
|
||||||
@ -132,3 +135,11 @@ func Distinct(list []string) []string {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 排序+拼接+摘要
|
||||||
|
func Sign(a []string) string {
|
||||||
|
sort.Strings(a)
|
||||||
|
data := []byte(strings.Join(a, ""))
|
||||||
|
has := md5.Sum(data)
|
||||||
|
return fmt.Sprintf("%x", has)
|
||||||
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import 'antd/dist/antd.css';
|
import 'antd/dist/antd.css';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import {Divider, Layout} from "antd";
|
import {Divider, Layout, Menu} from "antd";
|
||||||
import {Switch, Route, Link} from "react-router-dom";
|
import {Link, Route, Switch} from "react-router-dom";
|
||||||
import {Menu} from 'antd';
|
|
||||||
import Dashboard from "./components/dashboard/Dashboard";
|
import Dashboard from "./components/dashboard/Dashboard";
|
||||||
import Asset from "./components/asset/Asset";
|
import Asset from "./components/asset/Asset";
|
||||||
import Access from "./components/access/Access";
|
import Access from "./components/access/Access";
|
||||||
@ -14,19 +13,20 @@ import Login from "./components/Login";
|
|||||||
import DynamicCommand from "./components/command/DynamicCommand";
|
import DynamicCommand from "./components/command/DynamicCommand";
|
||||||
import Credential from "./components/credential/Credential";
|
import Credential from "./components/credential/Credential";
|
||||||
import {
|
import {
|
||||||
DashboardOutlined,
|
AuditOutlined,
|
||||||
UserOutlined,
|
BlockOutlined,
|
||||||
IdcardOutlined,
|
|
||||||
CloudServerOutlined,
|
CloudServerOutlined,
|
||||||
CodeOutlined,
|
CodeOutlined,
|
||||||
BlockOutlined,
|
DashboardOutlined,
|
||||||
AuditOutlined,
|
|
||||||
DesktopOutlined,
|
DesktopOutlined,
|
||||||
DisconnectOutlined,
|
DisconnectOutlined,
|
||||||
MenuUnfoldOutlined,
|
IdcardOutlined,
|
||||||
|
LinkOutlined,
|
||||||
MenuFoldOutlined,
|
MenuFoldOutlined,
|
||||||
|
MenuUnfoldOutlined,
|
||||||
|
SettingOutlined,
|
||||||
SolutionOutlined,
|
SolutionOutlined,
|
||||||
SettingOutlined, LinkOutlined
|
UserOutlined
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import Info from "./components/user/Info";
|
import Info from "./components/user/Info";
|
||||||
import request from "./common/request";
|
import request from "./common/request";
|
||||||
@ -69,12 +69,13 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let result = await request.get('/info');
|
let result = await request.get('/info');
|
||||||
if (result.code === 1) {
|
if (result['code'] === 1) {
|
||||||
this.setState({
|
this.setState({
|
||||||
user: result.data
|
user: result['data']
|
||||||
})
|
})
|
||||||
|
sessionStorage.setItem('user', JSON.stringify(result['data']));
|
||||||
} else {
|
} else {
|
||||||
message.error(result.message);
|
message.error(result['message']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
Transfer,
|
||||||
Typography
|
Typography
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import qs from "qs";
|
import qs from "qs";
|
||||||
@ -26,13 +27,14 @@ import {message} from "antd/es";
|
|||||||
import {
|
import {
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
DownOutlined,
|
DownOutlined,
|
||||||
ExclamationCircleOutlined, FormOutlined,
|
ExclamationCircleOutlined,
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
SyncOutlined,
|
SyncOutlined,
|
||||||
UndoOutlined
|
UndoOutlined
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import {itemRender} from "../../utils/utils";
|
import {itemRender} from "../../utils/utils";
|
||||||
import Logout from "../user/Logout";
|
import Logout from "../user/Logout";
|
||||||
|
import {hasPermission} from "../../service/permission";
|
||||||
|
|
||||||
const confirm = Modal.confirm;
|
const confirm = Modal.confirm;
|
||||||
const {Search} = Input;
|
const {Search} = Input;
|
||||||
@ -53,6 +55,7 @@ class Credential extends Component {
|
|||||||
|
|
||||||
inputRefOfName = React.createRef();
|
inputRefOfName = React.createRef();
|
||||||
changeOwnerFormRef = React.createRef();
|
changeOwnerFormRef = React.createRef();
|
||||||
|
changeSharerFormRef = React.createRef();
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
items: [],
|
items: [],
|
||||||
@ -69,9 +72,12 @@ class Credential extends Component {
|
|||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
delBtnLoading: false,
|
delBtnLoading: false,
|
||||||
changeOwnerModalVisible: false,
|
changeOwnerModalVisible: false,
|
||||||
|
changeSharerModalVisible: false,
|
||||||
changeOwnerConfirmLoading: false,
|
changeOwnerConfirmLoading: false,
|
||||||
|
changeSharerConfirmLoading: false,
|
||||||
users: [],
|
users: [],
|
||||||
selected: undefined,
|
selected: {},
|
||||||
|
selectedSharers: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -266,8 +272,39 @@ class Credential extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const items = result['data']['items'].map(item => {
|
||||||
|
return {'key': item['id'], ...item}
|
||||||
|
})
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
users: result.data.items
|
users: items
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSharersChange = async targetKeys => {
|
||||||
|
this.setState({
|
||||||
|
selectedSharers: targetKeys
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleShowSharer = async (record, disabled) => {
|
||||||
|
let r1 = this.handleSearchByNickname('');
|
||||||
|
let r2 = request.get(`/resources/${record['id']}/assign`);
|
||||||
|
|
||||||
|
await r1;
|
||||||
|
let result = await r2;
|
||||||
|
|
||||||
|
let selectedSharers = [];
|
||||||
|
if (result['code'] !== 1) {
|
||||||
|
message.error(result['message']);
|
||||||
|
} else {
|
||||||
|
selectedSharers = result['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
selectedSharers: selectedSharers,
|
||||||
|
selected: record,
|
||||||
|
changeSharerModalVisible: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +347,6 @@ class Credential extends Component {
|
|||||||
<Tag color="red">密码</Tag>
|
<Tag color="red">密码</Tag>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
title: '授权账户',
|
title: '授权账户',
|
||||||
@ -334,6 +370,7 @@ class Credential extends Component {
|
|||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item key="1">
|
<Menu.Item key="1">
|
||||||
<Button type="text" size='small'
|
<Button type="text" size='small'
|
||||||
|
disabled={!hasPermission(record['owner'])}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.handleSearchByNickname('')
|
this.handleSearchByNickname('')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -353,12 +390,16 @@ class Credential extends Component {
|
|||||||
|
|
||||||
<Menu.Item key="2">
|
<Menu.Item key="2">
|
||||||
<Button type="text" size='small'
|
<Button type="text" size='small'
|
||||||
onClick={() => this.copy(record.id)}>分享</Button>
|
disabled={!hasPermission(record['owner'])}
|
||||||
|
onClick={async () => {
|
||||||
|
await this.handleShowSharer(record, false);
|
||||||
|
}}>授权</Button>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
|
||||||
<Menu.Divider/>
|
<Menu.Divider/>
|
||||||
<Menu.Item key="3">
|
<Menu.Item key="3">
|
||||||
<Button type="text" size='small' danger
|
<Button type="text" size='small' danger
|
||||||
|
disabled={!hasPermission(record['owner'])}
|
||||||
onClick={() => this.showDeleteConfirm(record.id, record.name)}>删除</Button>
|
onClick={() => this.showDeleteConfirm(record.id, record.name)}>删除</Button>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
@ -367,6 +408,7 @@ class Credential extends Component {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button type="link" size='small' loading={this.state.items[index].updateBtnLoading}
|
<Button type="link" size='small' loading={this.state.items[index].updateBtnLoading}
|
||||||
|
disabled={!hasPermission(record['owner'])}
|
||||||
onClick={() => this.showModal('更新凭证', record.id, index)}>编辑</Button>
|
onClick={() => this.showModal('更新凭证', record.id, index)}>编辑</Button>
|
||||||
<Dropdown overlay={menu}>
|
<Dropdown overlay={menu}>
|
||||||
<Button type="link" size='small'>
|
<Button type="link" size='small'>
|
||||||
@ -379,6 +421,19 @@ class Credential extends Component {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if(hasPermission()){
|
||||||
|
columns.splice(5,0,{
|
||||||
|
title: '授权人数',
|
||||||
|
dataIndex: 'sharerCount',
|
||||||
|
key: 'sharerCount',
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return <Button type='link' onClick={async () => {
|
||||||
|
await this.handleShowSharer(record, true);
|
||||||
|
}}>{text}</Button>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const selectedRowKeys = this.state.selectedRowKeys;
|
const selectedRowKeys = this.state.selectedRowKeys;
|
||||||
const rowSelection = {
|
const rowSelection = {
|
||||||
selectedRowKeys: this.state.selectedRowKeys,
|
selectedRowKeys: this.state.selectedRowKeys,
|
||||||
@ -388,9 +443,6 @@ class Credential extends Component {
|
|||||||
};
|
};
|
||||||
const hasSelected = selectedRowKeys.length > 0;
|
const hasSelected = selectedRowKeys.length > 0;
|
||||||
|
|
||||||
const userOptions = this.state.users.map(d => <Select.Option key={d.id}
|
|
||||||
value={d.id}>{d.nickname}</Select.Option>);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
@ -514,7 +566,8 @@ class Credential extends Component {
|
|||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
||||||
<Modal title="更换所有者" visible={this.state.changeOwnerModalVisible}
|
<Modal title={`更换授权凭证「${this.state.selected['name']}」的所有者`}
|
||||||
|
visible={this.state.changeOwnerModalVisible}
|
||||||
confirmLoading={this.state.changeOwnerConfirmLoading}
|
confirmLoading={this.state.changeOwnerConfirmLoading}
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -560,12 +613,56 @@ class Credential extends Component {
|
|||||||
onSearch={this.handleSearchByNickname}
|
onSearch={this.handleSearchByNickname}
|
||||||
filterOption={false}
|
filterOption={false}
|
||||||
>
|
>
|
||||||
{userOptions}
|
{this.state.users.map(d => <Select.Option key={d.id}
|
||||||
|
value={d.id}>{d.nickname}</Select.Option>)}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<Modal title={`授权凭证「${this.state.selected['name']}」的授权者`}
|
||||||
|
visible={this.state.changeSharerModalVisible}
|
||||||
|
confirmLoading={this.state.changeSharerConfirmLoading}
|
||||||
|
onOk={async () => {
|
||||||
|
this.setState({
|
||||||
|
changeSharerConfirmLoading: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let changeSharerModalVisible = false;
|
||||||
|
|
||||||
|
let result = await request.post(`/resources/${this.state.selected['id']}/assign?userIds=${this.state.selectedSharers.join(',')}`);
|
||||||
|
if (result['code'] === 1) {
|
||||||
|
message.success('操作成功');
|
||||||
|
this.loadTableData();
|
||||||
|
} else {
|
||||||
|
message.success(result['message'], 10);
|
||||||
|
changeSharerModalVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
changeSharerConfirmLoading: false,
|
||||||
|
changeSharerModalVisible: changeSharerModalVisible
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
this.setState({
|
||||||
|
changeSharerModalVisible: false
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
okButtonProps={{disabled: !hasPermission(this.state.selected['owner'])}}
|
||||||
|
>
|
||||||
|
|
||||||
|
<Transfer
|
||||||
|
dataSource={this.state.users}
|
||||||
|
disabled={!hasPermission(this.state.selected['owner'])}
|
||||||
|
showSearch
|
||||||
|
titles={['未授权', '已授权']}
|
||||||
|
operations={['授权', '移除']}
|
||||||
|
targetKeys={this.state.selectedSharers}
|
||||||
|
onChange={this.handleSharersChange}
|
||||||
|
render={item => `${item.nickname}`}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
</Content>
|
</Content>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -6,10 +6,8 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Col,
|
Col,
|
||||||
Divider,
|
Divider,
|
||||||
Dropdown,
|
|
||||||
Input,
|
Input,
|
||||||
Layout,
|
Layout,
|
||||||
Menu,
|
|
||||||
Modal,
|
Modal,
|
||||||
PageHeader,
|
PageHeader,
|
||||||
Row,
|
Row,
|
||||||
@ -271,7 +269,7 @@ class User extends Component {
|
|||||||
key: 'role',
|
key: 'role',
|
||||||
render: (role, record) => {
|
render: (role, record) => {
|
||||||
|
|
||||||
if (role === 'normal') {
|
if (role === 'user') {
|
||||||
return (
|
return (
|
||||||
<Tag>普通用户</Tag>
|
<Tag>普通用户</Tag>
|
||||||
);
|
);
|
||||||
|
9
web/src/service/permission.js
Normal file
9
web/src/service/permission.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export function hasPermission(owner) {
|
||||||
|
let userJsonStr = sessionStorage.getItem('user');
|
||||||
|
let user = JSON.parse(userJsonStr);
|
||||||
|
if (user['role'] === 'admin') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user['id'] === owner;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user