mirror of
https://github.com/veops/cmdb.git
synced 2025-09-08 06:22:45 +08:00
Compare commits
27 Commits
2.3.9
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
|
e5fe2bffaa | ||
|
9ec105ca37 | ||
|
1e1c92a3ef | ||
|
0b3cad8215 | ||
|
ed41a72900 | ||
|
27854d4e0a | ||
|
0372459f9d | ||
|
f56378e2b5 | ||
|
00b276d5e7 | ||
|
3faefbe8d3 | ||
|
4261f6fb57 | ||
|
c98199e98e | ||
|
82ea1ddc79 | ||
|
995e581315 | ||
|
ec8f626b8f | ||
|
ec884c92e1 | ||
|
9ee2776bdd | ||
|
7186bdac9c | ||
|
0a9964375a | ||
|
bff45d00b6 | ||
|
e429ad59ff | ||
|
ace160ae19 | ||
|
7036fe023c | ||
|
341f5dba53 | ||
|
5883c1616e | ||
|
bee0a3a3e5 | ||
|
7a79a8bbf7 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -43,7 +43,8 @@ cmdb-api/api/uploaded_files
|
||||
cmdb-api/migrations/versions
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
#*.mo
|
||||
messages.pot
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
@@ -25,8 +25,10 @@ Flask-Login = ">=0.6.2"
|
||||
Flask-Bcrypt = "==1.0.1"
|
||||
Flask-Cors = ">=3.0.8"
|
||||
ldap3 = "==2.9.1"
|
||||
pycryptodome = "==3.12.0"
|
||||
pycryptodome = "==3.19.1"
|
||||
cryptography = ">=41.0.2"
|
||||
# i18n
|
||||
flask-babel = "==4.0.0"
|
||||
# Caching
|
||||
Flask-Caching = ">=1.0.0"
|
||||
# Environment variable parsing
|
||||
|
@@ -12,12 +12,14 @@ from pathlib import Path
|
||||
from flask import Flask
|
||||
from flask import jsonify
|
||||
from flask import make_response
|
||||
from flask import request
|
||||
from flask.blueprints import Blueprint
|
||||
from flask.cli import click
|
||||
from flask.json.provider import DefaultJSONProvider
|
||||
from flask_babel.speaklater import LazyString
|
||||
|
||||
import api.views.entry
|
||||
from api.extensions import (bcrypt, cache, celery, cors, db, es, login_manager, migrate, rd)
|
||||
from api.extensions import (bcrypt, babel, cache, celery, cors, db, es, login_manager, migrate, rd)
|
||||
from api.extensions import inner_secrets
|
||||
from api.lib.perm.authentication.cas import CAS
|
||||
from api.lib.perm.authentication.oauth2 import OAuth2
|
||||
@@ -72,7 +74,7 @@ class ReverseProxy(object):
|
||||
|
||||
class MyJSONEncoder(DefaultJSONProvider):
|
||||
def default(self, o):
|
||||
if isinstance(o, (decimal.Decimal, datetime.date, datetime.time)):
|
||||
if isinstance(o, (decimal.Decimal, datetime.date, datetime.time, LazyString)):
|
||||
return str(o)
|
||||
|
||||
if isinstance(o, datetime.datetime):
|
||||
@@ -117,7 +119,13 @@ def configure_upload_dir(app):
|
||||
|
||||
def register_extensions(app):
|
||||
"""Register Flask extensions."""
|
||||
|
||||
def get_locale():
|
||||
accept_languages = app.config.get('ACCEPT_LANGUAGES', ['en', 'zh'])
|
||||
return request.accept_languages.best_match(accept_languages)
|
||||
|
||||
bcrypt.init_app(app)
|
||||
babel.init_app(app, locale_selector=get_locale)
|
||||
cache.init_app(app)
|
||||
db.init_app(app)
|
||||
cors.init_app(app)
|
||||
|
@@ -35,8 +35,22 @@ def add_user():
|
||||
|
||||
"""
|
||||
|
||||
from api.models.acl import App
|
||||
from api.lib.perm.acl.cache import AppCache
|
||||
from api.lib.perm.acl.cache import RoleCache
|
||||
from api.lib.perm.acl.role import RoleCRUD
|
||||
from api.lib.perm.acl.role import RoleRelationCRUD
|
||||
|
||||
username = click.prompt('Enter username', confirmation_prompt=False)
|
||||
password = click.prompt('Enter password', hide_input=True, confirmation_prompt=True)
|
||||
email = click.prompt('Enter email ', confirmation_prompt=False)
|
||||
is_admin = click.prompt('Admin (Y/N) ', confirmation_prompt=False, type=bool, default=False)
|
||||
|
||||
UserCRUD.add(username=username, password=password, email=email)
|
||||
|
||||
if is_admin:
|
||||
app = AppCache.get('acl') or App.create(name='acl')
|
||||
acl_admin = RoleCache.get('acl_admin') or RoleCRUD.add_role('acl_admin', app.id, True)
|
||||
rid = RoleCache.get_by_name(None, username).id
|
||||
|
||||
RoleRelationCRUD.add(acl_admin, acl_admin.id, [rid], app.id)
|
||||
|
@@ -5,6 +5,7 @@ import copy
|
||||
import datetime
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
|
||||
import click
|
||||
import requests
|
||||
@@ -176,6 +177,11 @@ def cmdb_counter():
|
||||
from api.lib.cmdb.cache import CMDBCounterCache
|
||||
|
||||
current_app.test_request_context().push()
|
||||
if not UserCache.get('worker'):
|
||||
from api.lib.perm.acl.user import UserCRUD
|
||||
|
||||
UserCRUD.add(username='worker', password=uuid.uuid4().hex, email='worker@xxx.com')
|
||||
|
||||
login_user(UserCache.get('worker'))
|
||||
while True:
|
||||
try:
|
||||
|
@@ -5,9 +5,7 @@ from glob import glob
|
||||
from subprocess import call
|
||||
|
||||
import click
|
||||
from flask import current_app
|
||||
from flask.cli import with_appcontext
|
||||
from werkzeug.exceptions import MethodNotAllowed, NotFound
|
||||
|
||||
from api.extensions import db
|
||||
|
||||
@@ -90,3 +88,40 @@ def db_setup():
|
||||
"""create tables
|
||||
"""
|
||||
db.create_all()
|
||||
|
||||
|
||||
@click.group()
|
||||
def translate():
|
||||
"""Translation and localization commands."""
|
||||
|
||||
|
||||
@translate.command()
|
||||
@click.argument('lang')
|
||||
def init(lang):
|
||||
"""Initialize a new language."""
|
||||
|
||||
if os.system('pybabel extract -F babel.cfg -k _l -o messages.pot .'):
|
||||
raise RuntimeError('extract command failed')
|
||||
if os.system(
|
||||
'pybabel init -i messages.pot -d api/translations -l ' + lang):
|
||||
raise RuntimeError('init command failed')
|
||||
os.remove('messages.pot')
|
||||
|
||||
|
||||
@translate.command()
|
||||
def update():
|
||||
"""Update all languages."""
|
||||
|
||||
if os.system('pybabel extract -F babel.cfg -k _l -o messages.pot .'):
|
||||
raise RuntimeError('extract command failed')
|
||||
if os.system('pybabel update -i messages.pot -d api/translations'):
|
||||
raise RuntimeError('update command failed')
|
||||
os.remove('messages.pot')
|
||||
|
||||
|
||||
@translate.command()
|
||||
def compile():
|
||||
"""Compile all languages."""
|
||||
|
||||
if os.system('pybabel compile -d api/translations'):
|
||||
raise RuntimeError('compile command failed')
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
from celery import Celery
|
||||
from flask_babel import Babel
|
||||
from flask_bcrypt import Bcrypt
|
||||
from flask_caching import Cache
|
||||
from flask_cors import CORS
|
||||
@@ -14,6 +15,7 @@ from api.lib.utils import ESHandler
|
||||
from api.lib.utils import RedisHandler
|
||||
|
||||
bcrypt = Bcrypt()
|
||||
babel = Babel()
|
||||
login_manager = LoginManager()
|
||||
db = SQLAlchemy(session_options={"autoflush": False})
|
||||
migrate = Migrate()
|
||||
|
@@ -1,647 +1,386 @@
|
||||
[
|
||||
{
|
||||
"name": "CreationTime",
|
||||
"type": "文本",
|
||||
"example": "2017-12-10T04:04Z",
|
||||
"desc": "\u5b9e\u4f8b\u521b\u5efa\u65f6\u95f4\u3002\u4ee5ISO 8601\u4e3a\u6807\u51c6\uff0c\u5e76\u4f7f\u7528UTC+0\u65f6\u95f4\uff0c\u683c\u5f0f\u4e3ayyyy-MM-ddTHH:mmZ\u3002\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1[ISO 8601](~~25696~~)\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例创建时间。以ISO 8601为标准,并使用UTC+0时间,格式为yyyy-MM-ddTHH:mmZ。更多信息,请参见[ISO 8601](~~25696~~)。",
|
||||
"example": "2017-12-10T04:04Z"
|
||||
},
|
||||
{
|
||||
"name": "SerialNumber",
|
||||
"type": "文本",
|
||||
"example": "51d1353b-22bf-4567-a176-8b3e12e4****",
|
||||
"desc": "\u5b9e\u4f8b\u5e8f\u5217\u53f7\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例序列号。",
|
||||
"example": "51d1353b-22bf-4567-a176-8b3e12e4****"
|
||||
},
|
||||
{
|
||||
"name": "Status",
|
||||
"type": "文本",
|
||||
"example": "Running",
|
||||
"desc": "\u5b9e\u4f8b\u72b6\u6001\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例状态。",
|
||||
"example": "Running"
|
||||
},
|
||||
{
|
||||
"name": "DeploymentSetId",
|
||||
"type": "文本",
|
||||
"example": "ds-bp67acfmxazb4p****",
|
||||
"desc": "\u90e8\u7f72\u96c6ID\u3002"
|
||||
"type": "string",
|
||||
"desc": "部署集ID。",
|
||||
"example": "ds-bp67acfmxazb4p****"
|
||||
},
|
||||
{
|
||||
"name": "KeyPairName",
|
||||
"type": "文本",
|
||||
"example": "testKeyPairName",
|
||||
"desc": "\u5bc6\u94a5\u5bf9\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "密钥对名称。",
|
||||
"example": "testKeyPairName"
|
||||
},
|
||||
{
|
||||
"name": "SaleCycle",
|
||||
"type": "文本",
|
||||
"example": "month",
|
||||
"desc": "> \u8be5\u53c2\u6570\u5df2\u5f03\u7528\uff0c\u4e0d\u518d\u8fd4\u56de\u6709\u610f\u4e49\u7684\u6570\u636e\u3002"
|
||||
"type": "string",
|
||||
"desc": "> 该参数已弃用,不再返回有意义的数据。",
|
||||
"example": "month"
|
||||
},
|
||||
{
|
||||
"name": "SpotStrategy",
|
||||
"type": "文本",
|
||||
"example": "NoSpot",
|
||||
"desc": "\u6309\u91cf\u5b9e\u4f8b\u7684\u7ade\u4ef7\u7b56\u7565\u3002\u53ef\u80fd\u503c\uff1a\n\n- NoSpot\uff1a\u6b63\u5e38\u6309\u91cf\u4ed8\u8d39\u5b9e\u4f8b\u3002\n- SpotWithPriceLimit\uff1a\u8bbe\u7f6e\u4e0a\u9650\u4ef7\u683c\u7684\u62a2\u5360\u5f0f\u5b9e\u4f8b\u3002\n- SpotAsPriceGo\uff1a\u7cfb\u7edf\u81ea\u52a8\u51fa\u4ef7\uff0c\u6700\u9ad8\u6309\u91cf\u4ed8\u8d39\u4ef7\u683c\u7684\u62a2\u5360\u5f0f\u5b9e\u4f8b\u3002"
|
||||
"type": "string",
|
||||
"desc": "按量实例的竞价策略。可能值:\n\n- NoSpot:正常按量付费实例。\n- SpotWithPriceLimit:设置上限价格的抢占式实例。\n- SpotAsPriceGo:系统自动出价,最高按量付费价格的抢占式实例。",
|
||||
"example": "NoSpot"
|
||||
},
|
||||
{
|
||||
"name": "DeviceAvailable",
|
||||
"type": "boolean",
|
||||
"example": "true",
|
||||
"desc": "\u5b9e\u4f8b\u662f\u5426\u53ef\u4ee5\u6302\u8f7d\u6570\u636e\u76d8\u3002"
|
||||
"desc": "实例是否可以挂载数据盘。\n\n- true:可以挂载数据盘。\n- false:不可以挂载数据盘。",
|
||||
"example": "true"
|
||||
},
|
||||
{
|
||||
"name": "LocalStorageCapacity",
|
||||
"type": "整数",
|
||||
"example": "1000",
|
||||
"desc": "\u5b9e\u4f8b\u6302\u8f7d\u7684\u672c\u5730\u5b58\u50a8\u5bb9\u91cf\u3002"
|
||||
"type": "integer",
|
||||
"desc": "实例挂载的本地存储容量。单位:GiB。",
|
||||
"example": "1000"
|
||||
},
|
||||
{
|
||||
"name": "Description",
|
||||
"type": "文本",
|
||||
"example": "testDescription",
|
||||
"desc": "\u5b9e\u4f8b\u63cf\u8ff0\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例描述。",
|
||||
"example": "testDescription"
|
||||
},
|
||||
{
|
||||
"name": "SpotDuration",
|
||||
"type": "整数",
|
||||
"example": "1",
|
||||
"desc": "\u62a2\u5360\u5f0f\u5b9e\u4f8b\u7684\u4fdd\u7559\u65f6\u957f\uff0c\u5355\u4f4d\u4e3a\u5c0f\u65f6\u3002\u53ef\u80fd\u503c\u4e3a0~6\u3002\n\n- \u4fdd\u7559\u65f6\u957f2~6\u6b63\u5728\u9080\u6d4b\u4e2d\uff0c\u5982\u9700\u5f00\u901a\u8bf7\u63d0\u4ea4\u5de5\u5355\u3002\n- \u503c\u4e3a0\uff0c\u5219\u4e3a\u65e0\u4fdd\u62a4\u671f\u6a21\u5f0f\u3002\n\n>\u5f53SpotStrategy\u503c\u4e3aSpotWithPriceLimit\u6216SpotAsPriceGo\u65f6\u8fd4\u56de\u8be5\u53c2\u6570\u3002"
|
||||
"type": "integer",
|
||||
"desc": "抢占式实例的保留时长,单位为小时。可能值:\n\n- 1:创建后阿里云会保证实例运行1小时不会被自动释放;超过1小时后,系统会自动比较出价与市场价格、检查资源库存,来决定实例的持有和回收。\n- 0:创建后,阿里云不保证实例运行1小时,系统会自动比较出价与市场价格、检查资源库存,来决定实例的持有和回收。\n\n实例回收前5分钟阿里云会通过ECS系统事件向您发送通知。抢占式实例按秒计费,建议您结合具体任务执行耗时来选择合适的保留时长。\n\n>当SpotStrategy值为SpotWithPriceLimit或SpotAsPriceGo时返回该参数。",
|
||||
"example": "1"
|
||||
},
|
||||
{
|
||||
"name": "InstanceNetworkType",
|
||||
"type": "文本",
|
||||
"example": "vpc",
|
||||
"desc": "\u5b9e\u4f8b\u7f51\u7edc\u7c7b\u578b\u3002\u53ef\u80fd\u503c\uff1a\n\n- classic\uff1a\u7ecf\u5178\u7f51\u7edc\u3002\n- vpc\uff1a\u4e13\u6709\u7f51\u7edcVPC\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例网络类型。可能值:\n\n- classic:经典网络。\n- vpc:专有网络VPC。",
|
||||
"example": "vpc"
|
||||
},
|
||||
{
|
||||
"name": "InstanceName",
|
||||
"type": "文本",
|
||||
"example": "InstanceNameTest",
|
||||
"desc": "\u5b9e\u4f8b\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例名称。",
|
||||
"example": "InstanceNameTest"
|
||||
},
|
||||
{
|
||||
"name": "OSNameEn",
|
||||
"type": "文本",
|
||||
"example": "CentOS 7.4 64 bit",
|
||||
"desc": "\u5b9e\u4f8b\u64cd\u4f5c\u7cfb\u7edf\u7684\u82f1\u6587\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例操作系统的英文名称。",
|
||||
"example": "CentOS 7.4 64 bit"
|
||||
},
|
||||
{
|
||||
"name": "HpcClusterId",
|
||||
"type": "文本",
|
||||
"example": "hpc-bp67acfmxazb4p****",
|
||||
"desc": "\u5b9e\u4f8b\u6240\u5c5e\u7684HPC\u96c6\u7fa4ID\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例所属的HPC集群ID。",
|
||||
"example": "hpc-bp67acfmxazb4p****"
|
||||
},
|
||||
{
|
||||
"name": "SpotPriceLimit",
|
||||
"type": "float",
|
||||
"example": "0.98",
|
||||
"desc": "\u5b9e\u4f8b\u7684\u6bcf\u5c0f\u65f6\u6700\u9ad8\u4ef7\u683c\u3002\u652f\u6301\u6700\u59273\u4f4d\u5c0f\u6570\uff0c\u53c2\u6570SpotStrategy=SpotWithPriceLimit\u65f6\uff0c\u8be5\u53c2\u6570\u751f\u6548\u3002"
|
||||
"type": "number",
|
||||
"desc": "实例的每小时最高价格。支持最大3位小数,参数SpotStrategy=SpotWithPriceLimit时,该参数生效。",
|
||||
"example": "0.98"
|
||||
},
|
||||
{
|
||||
"name": "Memory",
|
||||
"type": "整数",
|
||||
"example": "16384",
|
||||
"desc": "\u5185\u5b58\u5927\u5c0f\uff0c\u5355\u4f4d\u4e3aMiB\u3002"
|
||||
"type": "integer",
|
||||
"desc": "内存大小,单位为MiB。",
|
||||
"example": "16384"
|
||||
},
|
||||
{
|
||||
"name": "OSName",
|
||||
"type": "文本",
|
||||
"example": "CentOS 7.4 64 \u4f4d",
|
||||
"desc": "\u5b9e\u4f8b\u7684\u64cd\u4f5c\u7cfb\u7edf\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例的操作系统名称。",
|
||||
"example": "CentOS 7.4 64 位"
|
||||
},
|
||||
{
|
||||
"name": "DeploymentSetGroupNo",
|
||||
"type": "整数",
|
||||
"example": "1",
|
||||
"desc": "ECS\u5b9e\u4f8b\u7ed1\u5b9a\u90e8\u7f72\u96c6\u5206\u6563\u90e8\u7f72\u65f6\uff0c\u5b9e\u4f8b\u5728\u90e8\u7f72\u96c6\u4e2d\u7684\u5206\u7ec4\u4f4d\u7f6e\u3002"
|
||||
"type": "integer",
|
||||
"desc": "ECS实例绑定部署集分散部署时,实例在部署集中的分组位置。",
|
||||
"example": "1"
|
||||
},
|
||||
{
|
||||
"name": "ImageId",
|
||||
"type": "文本",
|
||||
"example": "m-bp67acfmxazb4p****",
|
||||
"desc": "\u5b9e\u4f8b\u8fd0\u884c\u7684\u955c\u50cfID\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例运行的镜像ID。",
|
||||
"example": "m-bp67acfmxazb4p****"
|
||||
},
|
||||
{
|
||||
"name": "VlanId",
|
||||
"type": "文本",
|
||||
"example": "10",
|
||||
"desc": "\u5b9e\u4f8b\u7684VLAN ID\u3002\n\n>\u8be5\u53c2\u6570\u5373\u5c06\u88ab\u5f03\u7528\uff0c\u4e3a\u63d0\u9ad8\u517c\u5bb9\u6027\uff0c\u8bf7\u5c3d\u91cf\u4f7f\u7528\u5176\u4ed6\u53c2\u6570\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例的VLAN ID。\n\n>该参数即将被弃用,为提高兼容性,请尽量使用其他参数。",
|
||||
"example": "10"
|
||||
},
|
||||
{
|
||||
"name": "ClusterId",
|
||||
"type": "文本",
|
||||
"example": "c-bp67acfmxazb4p****",
|
||||
"desc": "\u5b9e\u4f8b\u6240\u5728\u7684\u96c6\u7fa4ID\u3002\n\n>\u8be5\u53c2\u6570\u5373\u5c06\u88ab\u5f03\u7528\uff0c\u4e3a\u63d0\u9ad8\u517c\u5bb9\u6027\uff0c\u8bf7\u5c3d\u91cf\u4f7f\u7528\u5176\u4ed6\u53c2\u6570\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例所在的集群ID。\n\n>该参数即将被弃用,为提高兼容性,请尽量使用其他参数。",
|
||||
"example": "c-bp67acfmxazb4p****"
|
||||
},
|
||||
{
|
||||
"name": "GPUSpec",
|
||||
"type": "文本",
|
||||
"example": "NVIDIA V100",
|
||||
"desc": "\u5b9e\u4f8b\u89c4\u683c\u9644\u5e26\u7684GPU\u7c7b\u578b\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例规格附带的GPU类型。",
|
||||
"example": "NVIDIA V100"
|
||||
},
|
||||
{
|
||||
"name": "AutoReleaseTime",
|
||||
"type": "文本",
|
||||
"example": "2017-12-10T04:04Z",
|
||||
"desc": "\u6309\u91cf\u4ed8\u8d39\u5b9e\u4f8b\u7684\u81ea\u52a8\u91ca\u653e\u65f6\u95f4\u3002"
|
||||
"type": "string",
|
||||
"desc": "按量付费实例的自动释放时间。",
|
||||
"example": "2017-12-10T04:04Z"
|
||||
},
|
||||
{
|
||||
"name": "DeletionProtection",
|
||||
"type": "boolean",
|
||||
"example": "false",
|
||||
"desc": "\u5b9e\u4f8b\u91ca\u653e\u4fdd\u62a4\u5c5e\u6027\uff0c\u6307\u5b9a\u662f\u5426\u652f\u6301\u901a\u8fc7\u63a7\u5236\u53f0\u6216API\uff08DeleteInstance\uff09\u91ca\u653e\u5b9e\u4f8b\u3002\n\n- true\uff1a\u5df2\u5f00\u542f\u5b9e\u4f8b\u91ca\u653e\u4fdd\u62a4\u3002\n- false\uff1a\u672a\u5f00\u542f\u5b9e\u4f8b\u91ca\u653e\u4fdd\u62a4\u3002\n\n> \u8be5\u5c5e\u6027\u4ec5\u9002\u7528\u4e8e\u6309\u91cf\u4ed8\u8d39\u5b9e\u4f8b\uff0c\u4e14\u53ea\u80fd\u9650\u5236\u624b\u52a8\u91ca\u653e\u64cd\u4f5c\uff0c\u5bf9\u7cfb\u7edf\u91ca\u653e\u64cd\u4f5c\u4e0d\u751f\u6548\u3002"
|
||||
"desc": "实例释放保护属性,指定是否支持通过控制台或API(DeleteInstance)释放实例。\n\n- true:已开启实例释放保护。\n- false:未开启实例释放保护。\n\n> 该属性仅适用于按量付费实例,且只能限制手动释放操作,对系统释放操作不生效。",
|
||||
"example": "false"
|
||||
},
|
||||
{
|
||||
"name": "StoppedMode",
|
||||
"type": "文本",
|
||||
"example": "KeepCharging",
|
||||
"desc": "\u5b9e\u4f8b\u505c\u673a\u540e\u662f\u5426\u7ee7\u7eed\u6536\u8d39\u3002\u53ef\u80fd\u503c\uff1a\n\n- KeepCharging\uff1a\u505c\u673a\u540e\u7ee7\u7eed\u6536\u8d39\uff0c\u4e3a\u60a8\u7ee7\u7eed\u4fdd\u7559\u5e93\u5b58\u8d44\u6e90\u3002\n- StopCharging\uff1a\u505c\u673a\u540e\u4e0d\u6536\u8d39\u3002\u505c\u673a\u540e\uff0c\u6211\u4eec\u91ca\u653e\u5b9e\u4f8b\u5bf9\u5e94\u7684\u8d44\u6e90\uff0c\u4f8b\u5982vCPU\u3001\u5185\u5b58\u548c\u516c\u7f51IP\u7b49\u8d44\u6e90\u3002\u91cd\u542f\u662f\u5426\u6210\u529f\u4f9d\u8d56\u4e8e\u5f53\u524d\u5730\u57df\u4e2d\u662f\u5426\u4ecd\u6709\u8d44\u6e90\u5e93\u5b58\u3002\n- Not-applicable\uff1a\u672c\u5b9e\u4f8b\u4e0d\u652f\u6301\u505c\u673a\u4e0d\u6536\u8d39\u529f\u80fd\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例停机后是否继续收费。可能值:\n\n- KeepCharging:停机后继续收费,为您继续保留库存资源。\n- StopCharging:停机后不收费。停机后,我们释放实例对应的资源,例如vCPU、内存和公网IP等资源。重启是否成功依赖于当前地域中是否仍有资源库存。\n- Not-applicable:本实例不支持停机不收费功能。",
|
||||
"example": "KeepCharging"
|
||||
},
|
||||
{
|
||||
"name": "GPUAmount",
|
||||
"type": "整数",
|
||||
"example": "4",
|
||||
"desc": "\u5b9e\u4f8b\u89c4\u683c\u9644\u5e26\u7684GPU\u6570\u91cf\u3002"
|
||||
"type": "integer",
|
||||
"desc": "实例规格附带的GPU数量。",
|
||||
"example": "4"
|
||||
},
|
||||
{
|
||||
"name": "HostName",
|
||||
"type": "文本",
|
||||
"example": "testHostName",
|
||||
"desc": "\u5b9e\u4f8b\u4e3b\u673a\u540d\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例主机名。",
|
||||
"example": "testHostName"
|
||||
},
|
||||
{
|
||||
"name": "InstanceId",
|
||||
"type": "文本",
|
||||
"example": "i-bp67acfmxazb4p****",
|
||||
"desc": "\u5b9e\u4f8bID\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例ID。",
|
||||
"example": "i-bp67acfmxazb4p****"
|
||||
},
|
||||
{
|
||||
"name": "InternetMaxBandwidthOut",
|
||||
"type": "整数",
|
||||
"example": "5",
|
||||
"desc": "\u516c\u7f51\u51fa\u5e26\u5bbd\u6700\u5927\u503c\uff0c\u5355\u4f4d\u4e3aMbit/s\u3002"
|
||||
"type": "integer",
|
||||
"desc": "公网出带宽最大值,单位:Mbit/s。",
|
||||
"example": "5"
|
||||
},
|
||||
{
|
||||
"name": "InternetMaxBandwidthIn",
|
||||
"type": "整数",
|
||||
"example": "50",
|
||||
"desc": "\u516c\u7f51\u5165\u5e26\u5bbd\u6700\u5927\u503c\uff0c\u5355\u4f4d\u4e3aMbit/s\u3002"
|
||||
"type": "integer",
|
||||
"desc": "公网入带宽最大值,单位:Mbit/s。",
|
||||
"example": "50"
|
||||
},
|
||||
{
|
||||
"name": "InstanceType",
|
||||
"type": "文本",
|
||||
"example": "ecs.g5.large",
|
||||
"desc": "\u5b9e\u4f8b\u89c4\u683c\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例规格。",
|
||||
"example": "ecs.g5.large"
|
||||
},
|
||||
{
|
||||
"name": "InstanceChargeType",
|
||||
"type": "文本",
|
||||
"example": "PostPaid",
|
||||
"desc": "\u5b9e\u4f8b\u7684\u8ba1\u8d39\u65b9\u5f0f\u3002\u53ef\u80fd\u503c\uff1a\n\n- PrePaid\uff1a\u5305\u5e74\u5305\u6708\u3002\n- PostPaid\uff1a\u6309\u91cf\u4ed8\u8d39\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例的计费方式。可能值:\n\n- PrePaid:包年包月。\n- PostPaid:按量付费。",
|
||||
"example": "PostPaid"
|
||||
},
|
||||
{
|
||||
"name": "RegionId",
|
||||
"type": "文本",
|
||||
"example": "cn-hangzhou",
|
||||
"desc": "\u5b9e\u4f8b\u6240\u5c5e\u5730\u57dfID\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例所属地域ID。",
|
||||
"example": "cn-hangzhou"
|
||||
},
|
||||
{
|
||||
"name": "IoOptimized",
|
||||
"type": "boolean",
|
||||
"example": "true",
|
||||
"desc": "\u662f\u5426\u4e3aI/O\u4f18\u5316\u578b\u5b9e\u4f8b\u3002"
|
||||
"desc": "是否为I/O优化型实例。\n\n- true:是。\n- false:否。",
|
||||
"example": "true"
|
||||
},
|
||||
{
|
||||
"name": "StartTime",
|
||||
"type": "文本",
|
||||
"example": "2017-12-10T04:04Z",
|
||||
"desc": "\u5b9e\u4f8b\u6700\u8fd1\u4e00\u6b21\u7684\u542f\u52a8\u65f6\u95f4\u3002\u4ee5ISO8601\u4e3a\u6807\u51c6\uff0c\u5e76\u4f7f\u7528UTC+0\u65f6\u95f4\uff0c\u683c\u5f0f\u4e3ayyyy-MM-ddTHH:mmZ\u3002\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1[ISO8601](~~25696~~)\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例最近一次的启动时间。以ISO 8601为标准,并使用UTC+0时间,格式为yyyy-MM-ddTHH:mmZ。更多信息,请参见[ISO 8601](~~25696~~)。",
|
||||
"example": "2017-12-10T04:04Z"
|
||||
},
|
||||
{
|
||||
"name": "Cpu",
|
||||
"type": "整数",
|
||||
"example": "8",
|
||||
"desc": "vCPU\u6570\u3002"
|
||||
"type": "integer",
|
||||
"desc": "vCPU数。",
|
||||
"example": "8"
|
||||
},
|
||||
{
|
||||
"name": "LocalStorageAmount",
|
||||
"type": "整数",
|
||||
"example": "2",
|
||||
"desc": "\u5b9e\u4f8b\u6302\u8f7d\u7684\u672c\u5730\u5b58\u50a8\u6570\u91cf\u3002"
|
||||
"type": "integer",
|
||||
"desc": "实例挂载的本地存储数量。",
|
||||
"example": "2"
|
||||
},
|
||||
{
|
||||
"name": "ExpiredTime",
|
||||
"type": "文本",
|
||||
"example": "2017-12-10T04:04Z",
|
||||
"desc": "\u8fc7\u671f\u65f6\u95f4\u3002\u4ee5ISO8601\u4e3a\u6807\u51c6\uff0c\u5e76\u4f7f\u7528UTC+0\u65f6\u95f4\uff0c\u683c\u5f0f\u4e3ayyyy-MM-ddTHH:mmZ\u3002\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1[ISO8601](~~25696~~)\u3002"
|
||||
"type": "string",
|
||||
"desc": "过期时间。以ISO 8601为标准,并使用UTC+0时间,格式为yyyy-MM-ddTHH:mmZ。更多信息,请参见[ISO 8601](~~25696~~)。",
|
||||
"example": "2017-12-10T04:04Z"
|
||||
},
|
||||
{
|
||||
"name": "ResourceGroupId",
|
||||
"type": "文本",
|
||||
"example": "rg-bp67acfmxazb4p****",
|
||||
"desc": "\u5b9e\u4f8b\u6240\u5c5e\u7684\u4f01\u4e1a\u8d44\u6e90\u7ec4ID\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例所属的企业资源组ID。",
|
||||
"example": "rg-bp67acfmxazb4p****"
|
||||
},
|
||||
{
|
||||
"name": "InternetChargeType",
|
||||
"type": "文本",
|
||||
"example": "PayByTraffic",
|
||||
"desc": "\u7f51\u7edc\u8ba1\u8d39\u7c7b\u578b\u3002\u53ef\u80fd\u503c\uff1a\n\n- PayByBandwidth\uff1a\u6309\u56fa\u5b9a\u5e26\u5bbd\u8ba1\u8d39\u3002\n- PayByTraffic\uff1a\u6309\u4f7f\u7528\u6d41\u91cf\u8ba1\u8d39\u3002"
|
||||
"type": "string",
|
||||
"desc": "网络计费类型。可能值:\n\n- PayByBandwidth:按固定带宽计费。\n- PayByTraffic:按使用流量计费。",
|
||||
"example": "PayByTraffic"
|
||||
},
|
||||
{
|
||||
"name": "ZoneId",
|
||||
"type": "文本",
|
||||
"example": "cn-hangzhou-g",
|
||||
"desc": "\u5b9e\u4f8b\u6240\u5c5e\u53ef\u7528\u533a\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例所属可用区。",
|
||||
"example": "cn-hangzhou-g"
|
||||
},
|
||||
{
|
||||
"name": "Recyclable",
|
||||
"type": "boolean",
|
||||
"example": "false",
|
||||
"desc": "\u5b9e\u4f8b\u662f\u5426\u53ef\u4ee5\u56de\u6536\u3002"
|
||||
"desc": "实例是否可以回收。",
|
||||
"example": "false"
|
||||
},
|
||||
{
|
||||
"name": "ISP",
|
||||
"type": "文本",
|
||||
"example": "null",
|
||||
"desc": "> \u8be5\u53c2\u6570\u6b63\u5728\u9080\u6d4b\u4e2d\uff0c\u6682\u672a\u5f00\u653e\u4f7f\u7528\u3002"
|
||||
"type": "string",
|
||||
"desc": "> 该参数正在邀测中,暂未开放使用。",
|
||||
"example": "null"
|
||||
},
|
||||
{
|
||||
"name": "CreditSpecification",
|
||||
"type": "文本",
|
||||
"example": "Standard",
|
||||
"desc": "\u4fee\u6539\u7a81\u53d1\u6027\u80fd\u5b9e\u4f8b\u7684\u8fd0\u884c\u6a21\u5f0f\u3002\u53ef\u80fd\u503c\uff1a\n\n- Standard\uff1a\u6807\u51c6\u6a21\u5f0f\u3002\u6709\u5173\u5b9e\u4f8b\u6027\u80fd\u7684\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1[\u4ec0\u4e48\u662f\u7a81\u53d1\u6027\u80fd\u5b9e\u4f8b](~~59977~~)\u4e2d\u7684\u6027\u80fd\u7ea6\u675f\u6a21\u5f0f\u7ae0\u8282\u3002\n- Unlimited\uff1a\u65e0\u6027\u80fd\u7ea6\u675f\u6a21\u5f0f\uff0c\u6709\u5173\u5b9e\u4f8b\u6027\u80fd\u7684\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1[\u4ec0\u4e48\u662f\u7a81\u53d1\u6027\u80fd\u5b9e\u4f8b](~~59977~~)\u4e2d\u7684\u65e0\u6027\u80fd\u7ea6\u675f\u6a21\u5f0f\u7ae0\u8282\u3002"
|
||||
"type": "string",
|
||||
"desc": "突发性能实例的运行模式。可能值:\n\n- Standard:标准模式。有关实例性能的更多信息,请参见[什么是突发性能实例](~~59977~~)中的性能约束模式章节。\n- Unlimited:无性能约束模式,有关实例性能的更多信息,请参见[什么是突发性能实例](~~59977~~)中的无性能约束模式章节。",
|
||||
"example": "Standard"
|
||||
},
|
||||
{
|
||||
"name": "InstanceTypeFamily",
|
||||
"type": "文本",
|
||||
"example": "ecs.g5",
|
||||
"desc": "\u5b9e\u4f8b\u89c4\u683c\u65cf\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例规格族。",
|
||||
"example": "ecs.g5"
|
||||
},
|
||||
{
|
||||
"name": "OSType",
|
||||
"type": "文本",
|
||||
"example": "linux",
|
||||
"desc": "\u5b9e\u4f8b\u7684\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b\uff0c\u5206\u4e3aWindows Server\u548cLinux\u4e24\u79cd\u3002\u53ef\u80fd\u503c\uff1a\n\n- windows\u3002\n- linux\u3002"
|
||||
"type": "string",
|
||||
"desc": "实例的操作系统类型,分为Windows Server和Linux两种。可能值:\n\n- windows。\n- linux。",
|
||||
"example": "linux"
|
||||
},
|
||||
{
|
||||
"name": "NetworkInterfaces",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"type": "json",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"description": "\u5f39\u6027\u7f51\u5361\u7c7b\u578b\u3002\u53ef\u80fd\u503c\uff1a\n- Primary\uff1a\u4e3b\u7f51\u5361\u3002\n- Secondary\uff1a\u8f85\u52a9\u5f39\u6027\u7f51\u5361\u3002",
|
||||
"type": "文本",
|
||||
"example": "Primary"
|
||||
},
|
||||
"MacAddress": {
|
||||
"description": "\u5f39\u6027\u7f51\u5361\u7684MAC\u5730\u5740\u3002",
|
||||
"type": "文本",
|
||||
"example": "00:16:3e:32:b4:**"
|
||||
},
|
||||
"PrimaryIpAddress": {
|
||||
"description": "\u5f39\u6027\u7f51\u5361\u4e3b\u79c1\u6709IP\u5730\u5740\u3002",
|
||||
"type": "文本",
|
||||
"example": "172.17.**.***"
|
||||
},
|
||||
"NetworkInterfaceId": {
|
||||
"description": "\u5f39\u6027\u7f51\u5361\u7684ID\u3002",
|
||||
"type": "文本",
|
||||
"example": "eni-2zeh9atclduxvf1z****"
|
||||
},
|
||||
"PrivateIpSets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "json",
|
||||
"properties": {
|
||||
"PrivateIpAddress": {
|
||||
"description": "\u5b9e\u4f8b\u7684\u79c1\u7f51IP\u5730\u5740\u3002",
|
||||
"type": "文本",
|
||||
"example": "172.17.**.**"
|
||||
},
|
||||
"Primary": {
|
||||
"description": "\u662f\u5426\u662f\u4e3b\u79c1\u7f51IP\u5730\u5740\u3002",
|
||||
"type": "boolean",
|
||||
"example": "true"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "PrivateIpSet\u7ec4\u6210\u7684\u96c6\u5408\u3002"
|
||||
},
|
||||
"Ipv6Sets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "json",
|
||||
"properties": {
|
||||
"Ipv6Address": {
|
||||
"description": "\u4e3a\u5f39\u6027\u7f51\u5361\u6307\u5b9a\u7684IPv6\u5730\u5740\u3002",
|
||||
"type": "文本",
|
||||
"example": "2408:4321:180:1701:94c7:bc38:3bfa:***"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "\u4e3a\u5f39\u6027\u7f51\u5361\u5206\u914d\u7684IPv6\u5730\u5740\u96c6\u5408\u3002\u4ec5\u5f53\u8bf7\u6c42\u53c2\u6570`AdditionalAttributes.N`\u53d6\u503c\u4e3a`NETWORK_PRIMARY_ENI_IP`\u65f6\uff0c\u624d\u4f1a\u8fd4\u56de\u8be5\u53c2\u6570\u503c\u3002"
|
||||
},
|
||||
"Ipv4PrefixSets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "json",
|
||||
"properties": {
|
||||
"Ipv4Prefix": {
|
||||
"description": "IPv4\u524d\u7f00\u3002",
|
||||
"type": "文本",
|
||||
"example": "47.122.*.*/19"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "IPv4\u524d\u7f00\u96c6\u5408\u3002"
|
||||
},
|
||||
"Ipv6PrefixSets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "json",
|
||||
"properties": {
|
||||
"Ipv6Prefix": {
|
||||
"description": "IPv6\u524d\u7f00\u3002",
|
||||
"type": "文本",
|
||||
"example": "2001:1111:*:*::/64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "IPv6\u524d\u7f00\u96c6\u5408\u3002"
|
||||
}
|
||||
},
|
||||
"description": "\u5b9e\u4f8b\u5305\u542b\u7684\u5f39\u6027\u7f51\u5361\u96c6\u5408\u3002"
|
||||
},
|
||||
"desc": "\u5b9e\u4f8b\u5305\u542b\u7684\u5f39\u6027\u7f51\u5361\u96c6\u5408\u3002"
|
||||
"desc": "实例包含的弹性网卡集合。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "OperationLocks",
|
||||
"type": "文本、多值",
|
||||
"example": {
|
||||
"type": "json",
|
||||
"properties": {
|
||||
"LockMsg": {
|
||||
"description": "\u5b9e\u4f8b\u88ab\u9501\u5b9a\u7684\u63cf\u8ff0\u4fe1\u606f\u3002",
|
||||
"type": "文本",
|
||||
"example": "The specified instance is locked due to financial reason."
|
||||
},
|
||||
"LockReason": {
|
||||
"description": "\u9501\u5b9a\u7c7b\u578b\u3002\u53ef\u80fd\u503c\uff1a\n\n- financial\uff1a\u56e0\u6b20\u8d39\u88ab\u9501\u5b9a\u3002\n- security\uff1a\u56e0\u5b89\u5168\u539f\u56e0\u88ab\u9501\u5b9a\u3002\n- Recycling\uff1a\u62a2\u5360\u5f0f\u5b9e\u4f8b\u7684\u5f85\u91ca\u653e\u9501\u5b9a\u72b6\u6001\u3002\n- dedicatedhostfinancial\uff1a\u56e0\u4e3a\u4e13\u6709\u5bbf\u4e3b\u673a\u6b20\u8d39\u5bfc\u81f4ECS\u5b9e\u4f8b\u88ab\u9501\u5b9a\u3002\n- refunded\uff1a\u56e0\u9000\u6b3e\u88ab\u9501\u5b9a\u3002",
|
||||
"type": "文本",
|
||||
"example": "Recycling"
|
||||
}
|
||||
}
|
||||
},
|
||||
"desc": "\u5b9e\u4f8b\u7684\u9501\u5b9a\u539f\u56e0\u3002"
|
||||
"type": "array",
|
||||
"desc": "实例的锁定原因。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "Tags",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"type": "json",
|
||||
"properties": {
|
||||
"TagValue": {
|
||||
"description": "\u5b9e\u4f8b\u7684\u6807\u7b7e\u503c\u3002",
|
||||
"type": "文本",
|
||||
"example": "TestValue"
|
||||
},
|
||||
"TagKey": {
|
||||
"description": "\u5b9e\u4f8b\u7684\u6807\u7b7e\u952e\u3002",
|
||||
"type": "文本",
|
||||
"example": "TestKey"
|
||||
}
|
||||
}
|
||||
},
|
||||
"desc": "\u5b9e\u4f8b\u7684\u6807\u7b7e\u96c6\u5408\u3002"
|
||||
"type": "array",
|
||||
"desc": "实例的标签集合。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "RdmaIpAddress",
|
||||
"type": "文本、多值",
|
||||
"example": {
|
||||
"description": "HPC\u5b9e\u4f8b\u7684Rdma\u7f51\u7edcIP\u3002",
|
||||
"type": "文本",
|
||||
"example": "10.10.10.102"
|
||||
},
|
||||
"desc": "HPC\u5b9e\u4f8b\u7684Rdma\u7f51\u7edcIP\u5217\u8868\u3002"
|
||||
"type": "array",
|
||||
"desc": "HPC实例的RDMA网络IP列表。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "SecurityGroupIds",
|
||||
"type": "文本、多值",
|
||||
"example": {
|
||||
"description": "\u5b89\u5168\u7ec4ID\u3002",
|
||||
"type": "文本",
|
||||
"example": "sg-bp67acfmxazb4p****"
|
||||
},
|
||||
"desc": "\u5b9e\u4f8b\u6240\u5c5e\u5b89\u5168\u7ec4ID\u5217\u8868\u3002"
|
||||
"type": "array",
|
||||
"desc": "实例所属安全组ID列表。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "PublicIpAddress",
|
||||
"type": "文本、多值",
|
||||
"example": {
|
||||
"description": "\u5b9e\u4f8b\u516c\u7f51IP\u5730\u5740\u3002",
|
||||
"type": "文本",
|
||||
"example": "121.40.**.**"
|
||||
},
|
||||
"desc": "\u5b9e\u4f8b\u516c\u7f51IP\u5730\u5740\u5217\u8868\u3002"
|
||||
"type": "array",
|
||||
"desc": "实例公网IP地址列表。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "InnerIpAddress",
|
||||
"type": "文本、多值",
|
||||
"example": {
|
||||
"description": "\u7ecf\u5178\u7f51\u7edc\u7c7b\u578b\u5b9e\u4f8b\u7684\u5185\u7f51IP\u5730\u5740\u3002",
|
||||
"type": "文本",
|
||||
"example": "10.170.**.**"
|
||||
},
|
||||
"desc": "\u7ecf\u5178\u7f51\u7edc\u7c7b\u578b\u5b9e\u4f8b\u7684\u5185\u7f51IP\u5730\u5740\u5217\u8868\u3002"
|
||||
"type": "array",
|
||||
"desc": "经典网络类型实例的内网IP地址列表。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "VpcAttributes",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"VpcId": {
|
||||
"description": "\u4e13\u6709\u7f51\u7edcVPC ID\u3002",
|
||||
"type": "文本",
|
||||
"example": "vpc-2zeuphj08tt7q3brd****"
|
||||
},
|
||||
"NatIpAddress": {
|
||||
"description": "\u4e91\u4ea7\u54c1\u7684IP\uff0c\u7528\u4e8eVPC\u4e91\u4ea7\u54c1\u4e4b\u95f4\u7684\u7f51\u7edc\u4e92\u901a\u3002",
|
||||
"type": "文本",
|
||||
"example": "172.17.**.**"
|
||||
},
|
||||
"VSwitchId": {
|
||||
"description": "\u865a\u62df\u4ea4\u6362\u673aID\u3002",
|
||||
"type": "文本",
|
||||
"example": "vsw-2zeh0r1pabwtg6wcs****"
|
||||
},
|
||||
"PrivateIpAddress": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "\u79c1\u6709IP\u5730\u5740\u3002",
|
||||
"type": "文本",
|
||||
"example": "172.17.**.**"
|
||||
},
|
||||
"description": "\u79c1\u6709IP\u5730\u5740\u5217\u8868\u3002"
|
||||
}
|
||||
},
|
||||
"desc": "\u4e13\u6709\u7f51\u7edcVPC\u5c5e\u6027\u3002"
|
||||
"type": "object",
|
||||
"desc": "专有网络VPC属性。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "EipAddress",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"IsSupportUnassociate": {
|
||||
"description": "\u662f\u5426\u53ef\u4ee5\u89e3\u7ed1\u5f39\u6027\u516c\u7f51IP\u3002",
|
||||
"type": "boolean",
|
||||
"example": "true"
|
||||
},
|
||||
"InternetChargeType": {
|
||||
"description": "\u5f39\u6027\u516c\u7f51IP\u7684\u8ba1\u8d39\u65b9\u5f0f\u3002\n\n- PayByBandwidth\uff1a\u6309\u5e26\u5bbd\u8ba1\u8d39\u3002\n\n- PayByTraffic\uff1a\u6309\u6d41\u91cf\u8ba1\u8d39\u3002",
|
||||
"type": "文本",
|
||||
"example": "PayByTraffic"
|
||||
},
|
||||
"IpAddress": {
|
||||
"description": "\u5f39\u6027\u516c\u7f51IP\u3002",
|
||||
"type": "文本",
|
||||
"example": "42.112.**.**"
|
||||
},
|
||||
"Bandwidth": {
|
||||
"description": "\u5f39\u6027\u516c\u7f51IP\u7684\u516c\u7f51\u5e26\u5bbd\u9650\u901f\uff0c\u5355\u4f4d\u4e3aMbit/s\u3002",
|
||||
"type": "整数",
|
||||
"format": "int32",
|
||||
"example": "5"
|
||||
},
|
||||
"AllocationId": {
|
||||
"description": "\u5f39\u6027\u516c\u7f51IP\u7684ID\u3002",
|
||||
"type": "文本",
|
||||
"example": "eip-2ze88m67qx5z****"
|
||||
}
|
||||
},
|
||||
"desc": "\u5f39\u6027\u516c\u7f51IP\u7ed1\u5b9a\u4fe1\u606f\u3002"
|
||||
"type": "object",
|
||||
"desc": "弹性公网IP绑定信息。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "HibernationOptions",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"Configured": {
|
||||
"description": "> \u8be5\u53c2\u6570\u6b63\u5728\u9080\u6d4b\u4e2d\uff0c\u6682\u672a\u5f00\u653e\u4f7f\u7528\u3002",
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
}
|
||||
},
|
||||
"desc": "> \u8be5\u53c2\u6570\u6b63\u5728\u9080\u6d4b\u4e2d\uff0c\u6682\u672a\u5f00\u653e\u4f7f\u7528\u3002"
|
||||
"type": "object",
|
||||
"desc": "> 该参数正在邀测中,暂未开放使用。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "DedicatedHostAttribute",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"DedicatedHostId": {
|
||||
"description": "\u4e13\u6709\u5bbf\u4e3b\u673aID\u3002",
|
||||
"type": "文本",
|
||||
"example": "dh-bp67acfmxazb4p****"
|
||||
},
|
||||
"DedicatedHostName": {
|
||||
"description": "\u4e13\u6709\u5bbf\u4e3b\u673a\u540d\u79f0\u3002",
|
||||
"type": "文本",
|
||||
"example": "testDedicatedHostName"
|
||||
},
|
||||
"DedicatedHostClusterId": {
|
||||
"description": "\u4e13\u6709\u5bbf\u4e3b\u673a\u96c6\u7fa4ID\u3002",
|
||||
"type": "文本",
|
||||
"example": "dc-bp67acfmxazb4h****"
|
||||
}
|
||||
},
|
||||
"desc": "\u7531\u4e13\u6709\u5bbf\u4e3b\u673a\u96c6\u7fa4ID\uff08DedicatedHostClusterId\uff09\u3001\u4e13\u6709\u5bbf\u4e3b\u673aID\uff08DedicatedHostId\uff09\u548c\u540d\u79f0\uff08DedicatedHostName\uff09\u7ec4\u6210\u7684\u5bbf\u4e3b\u673a\u5c5e\u6027\u6570\u7ec4\u3002"
|
||||
"type": "object",
|
||||
"desc": "由专有宿主机集群ID(DedicatedHostClusterId)、专有宿主机ID(DedicatedHostId)和名称(DedicatedHostName)组成的宿主机属性数组。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "EcsCapacityReservationAttr",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"CapacityReservationPreference": {
|
||||
"description": "\u5bb9\u91cf\u9884\u7559\u504f\u597d\u3002",
|
||||
"type": "文本",
|
||||
"example": "cr-bp67acfmxazb4p****"
|
||||
},
|
||||
"CapacityReservationId": {
|
||||
"description": "\u5bb9\u91cf\u9884\u7559ID\u3002",
|
||||
"type": "文本",
|
||||
"example": "cr-bp67acfmxazb4p****"
|
||||
}
|
||||
},
|
||||
"desc": "\u4e91\u670d\u52a1\u5668ECS\u7684\u5bb9\u91cf\u9884\u7559\u76f8\u5173\u53c2\u6570\u3002"
|
||||
"type": "object",
|
||||
"desc": "云服务器ECS的容量预留相关参数。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "DedicatedInstanceAttribute",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"Affinity": {
|
||||
"description": "\u4e13\u6709\u5bbf\u4e3b\u673a\u5b9e\u4f8b\u662f\u5426\u4e0e\u4e13\u6709\u5bbf\u4e3b\u673a\u5173\u8054\u3002\u53ef\u80fd\u503c\uff1a\n\n- default\uff1a\u4e13\u6709\u5bbf\u4e3b\u673a\u5b9e\u4f8b\u4e0d\u4e0e\u4e13\u6709\u5bbf\u4e3b\u673a\u5173\u8054\u3002\u505c\u673a\u4e0d\u6536\u8d39\u5b9e\u4f8b\u91cd\u542f\u540e\uff0c\u53ef\u80fd\u4f1a\u653e\u7f6e\u5728\u81ea\u52a8\u8d44\u6e90\u90e8\u7f72\u6c60\u4e2d\u7684\u5176\u5b83\u4e13\u6709\u5bbf\u4e3b\u673a\u4e0a\u3002\n\n- host\uff1a\u4e13\u6709\u5bbf\u4e3b\u673a\u5b9e\u4f8b\u4e0e\u4e13\u6709\u5bbf\u4e3b\u673a\u5173\u8054\u3002\u505c\u673a\u4e0d\u6536\u8d39\u5b9e\u4f8b\u91cd\u542f\u540e\uff0c\u4ecd\u653e\u7f6e\u5728\u539f\u4e13\u6709\u5bbf\u4e3b\u673a\u4e0a\u3002",
|
||||
"type": "文本",
|
||||
"example": "default"
|
||||
},
|
||||
"Tenancy": {
|
||||
"description": "\u5b9e\u4f8b\u7684\u5bbf\u4e3b\u673a\u7c7b\u578b\u662f\u5426\u4e3a\u4e13\u6709\u5bbf\u4e3b\u673a\u3002\u53ef\u80fd\u503c\uff1a\n\n- default\uff1a\u5b9e\u4f8b\u7684\u5bbf\u4e3b\u673a\u7c7b\u578b\u4e0d\u662f\u4e13\u6709\u5bbf\u4e3b\u673a\u3002\n\n- host\uff1a\u5b9e\u4f8b\u7684\u5bbf\u4e3b\u673a\u7c7b\u578b\u4e3a\u4e13\u6709\u5bbf\u4e3b\u673a\u3002",
|
||||
"type": "文本",
|
||||
"example": "default"
|
||||
}
|
||||
},
|
||||
"desc": "\u4e13\u6709\u5bbf\u4e3b\u673a\u5b9e\u4f8b\u7684\u5c5e\u6027\u3002"
|
||||
"type": "object",
|
||||
"desc": "专有宿主机实例的属性。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "CpuOptions",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"Numa": {
|
||||
"description": "\u5206\u914d\u7684\u7ebf\u7a0b\u6570\u3002\u53ef\u80fd\u503c\u4e3a2\u3002",
|
||||
"type": "文本",
|
||||
"example": "2"
|
||||
},
|
||||
"CoreCount": {
|
||||
"description": "\u7269\u7406CPU\u6838\u5fc3\u6570\u3002",
|
||||
"type": "整数",
|
||||
"format": "int32",
|
||||
"example": "2"
|
||||
},
|
||||
"ThreadsPerCore": {
|
||||
"description": "CPU\u7ebf\u7a0b\u6570\u3002",
|
||||
"type": "整数",
|
||||
"format": "int32",
|
||||
"example": "4"
|
||||
}
|
||||
},
|
||||
"desc": "CPU\u914d\u7f6e\u8be6\u60c5\u3002"
|
||||
"type": "object",
|
||||
"desc": "CPU配置详情。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "MetadataOptions",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"HttpEndpoint": {
|
||||
"description": "\u662f\u5426\u542f\u7528\u5b9e\u4f8b\u5143\u6570\u636e\u7684\u8bbf\u95ee\u901a\u9053\u3002\u53ef\u80fd\u503c\uff1a\n- enabled\uff1a\u542f\u7528\u3002\n- disabled\uff1a\u7981\u7528\u3002",
|
||||
"type": "文本",
|
||||
"example": "enabled"
|
||||
},
|
||||
"HttpPutResponseHopLimit": {
|
||||
"description": "> \u8be5\u53c2\u6570\u6682\u672a\u5f00\u653e\u4f7f\u7528\u3002",
|
||||
"type": "整数",
|
||||
"format": "int32",
|
||||
"example": "0"
|
||||
},
|
||||
"HttpTokens": {
|
||||
"description": "\u8bbf\u95ee\u5b9e\u4f8b\u5143\u6570\u636e\u65f6\u662f\u5426\u5f3a\u5236\u4f7f\u7528\u52a0\u56fa\u6a21\u5f0f\uff08IMDSv2\uff09\u3002\u53ef\u80fd\u503c\uff1a\n- optional\uff1a\u4e0d\u5f3a\u5236\u4f7f\u7528\u3002\n- required\uff1a\u5f3a\u5236\u4f7f\u7528\u3002",
|
||||
"type": "文本",
|
||||
"example": "optional"
|
||||
}
|
||||
},
|
||||
"desc": "\u5143\u6570\u636e\u9009\u9879\u96c6\u5408\u3002"
|
||||
"type": "object",
|
||||
"desc": "元数据选项集合。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "ImageOptions",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"LoginAsNonRoot": {
|
||||
"description": "\u4f7f\u7528\u8be5\u955c\u50cf\u7684\u5b9e\u4f8b\u662f\u5426\u652f\u6301\u4f7f\u7528ecs-user\u7528\u6237\u767b\u5f55\u3002\u53ef\u80fd\u503c\uff1a\n\n- true\uff1a\u662f\n\n- false\uff1a\u5426",
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
}
|
||||
"type": "object",
|
||||
"desc": "镜像相关属性信息。",
|
||||
"example": ""
|
||||
},
|
||||
"desc": "\u955c\u50cf\u76f8\u5173\u5c5e\u6027\u4fe1\u606f\u3002"
|
||||
{
|
||||
"name": "SpotInterruptionBehavior",
|
||||
"type": "string",
|
||||
"desc": "平台发起抢占式实例中断时,抢占式实例的中断模式。可能值:\n\n- Terminate:释放。\n\n- Stop:节省停机。",
|
||||
"example": "Terminate"
|
||||
}
|
||||
]
|
@@ -1,355 +1,277 @@
|
||||
[
|
||||
{
|
||||
"name": "amiLaunchIndex",
|
||||
"type": "整数",
|
||||
"type": "Integer",
|
||||
"desc": "The AMI launch index, which can be used to find this instance in the launch group.",
|
||||
"example": "0"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "architecture",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The architecture of the image.",
|
||||
"example": "x86_64"
|
||||
"example": "i386"
|
||||
},
|
||||
{
|
||||
"name": "blockDeviceMapping",
|
||||
"type": "json",
|
||||
"type": "Array of InstanceBlockDeviceMapping objects",
|
||||
"desc": "Any block device mapping entries for the instance.",
|
||||
"example": {
|
||||
"item": {
|
||||
"deviceName": "/dev/xvda",
|
||||
"ebs": {
|
||||
"volumeId": "vol-1234567890abcdef0",
|
||||
"status": "attached",
|
||||
"attachTime": "2015-12-22T10:44:09.000Z",
|
||||
"deleteOnTermination": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "bootMode",
|
||||
"type": "文本",
|
||||
"desc": "The boot mode that was specified by the AMI. If the value is uefi-preferred, the AMI supports both UEFI and Legacy BIOS. The currentInstanceBootMode parameter is the boot mode that is used to boot the instance at launch or start.",
|
||||
"example": null
|
||||
"type": "String",
|
||||
"desc": "The boot mode that was specified by the AMI. If the value is uefi-preferred, the AMI supports both UEFI and Legacy BIOS. The currentInstanceBootMode parameter is the boot mode that is used to boot the instance at launch or start. For more information, see Boot modes in the Amazon EC2 User Guide.",
|
||||
"example": "legacy-bios"
|
||||
},
|
||||
{
|
||||
"name": "capacityReservationId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The ID of the Capacity Reservation.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "capacityReservationSpecification",
|
||||
"type": "json",
|
||||
"type": "CapacityReservationSpecificationResponse object",
|
||||
"desc": "Information about the Capacity Reservation targeting option.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "clientToken",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The idempotency token you provided when you launched the instance, if applicable.",
|
||||
"example": "xMcwG14507example"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "cpuOptions",
|
||||
"type": "json",
|
||||
"type": "CpuOptions object",
|
||||
"desc": "The CPU options for the instance.",
|
||||
"example": {
|
||||
"coreCount": "1",
|
||||
"threadsPerCore": "1"
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "currentInstanceBootMode",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The boot mode that is used to boot the instance at launch or start. For more information, see Boot modes in the Amazon EC2 User Guide.",
|
||||
"example": null
|
||||
"example": "legacy-bios"
|
||||
},
|
||||
{
|
||||
"name": "dnsName",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "[IPv4 only] The public DNS name assigned to the instance. This name is not available until the instance enters the running state. This name is only available if you've enabled DNS hostnames for your VPC.",
|
||||
"example": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "ebsOptimized",
|
||||
"type": "Boolean",
|
||||
"desc": "Indicates whether the instance is optimized for Amazon EBS I/O. This optimization provides dedicated throughput to Amazon EBS and an optimized configuration stack to provide optimal I/O performance. This optimization isn't available with all instance types. Additional usage charges apply when using an EBS Optimized instance.",
|
||||
"example": "false"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "elasticGpuAssociationSet",
|
||||
"type": "json",
|
||||
"type": "Array of ElasticGpuAssociation objects",
|
||||
"desc": "The Elastic GPU associated with the instance.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "elasticInferenceAcceleratorAssociationSet",
|
||||
"type": "json",
|
||||
"type": "Array of ElasticInferenceAcceleratorAssociation objects",
|
||||
"desc": "The elastic inference accelerator associated with the instance.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "enaSupport",
|
||||
"type": "Boolean",
|
||||
"desc": "Specifies whether enhanced networking with ENA is enabled.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "enclaveOptions",
|
||||
"type": "json",
|
||||
"type": "EnclaveOptions object",
|
||||
"desc": "Indicates whether the instance is enabled for AWS Nitro Enclaves.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "groupSet",
|
||||
"type": "json",
|
||||
"type": "Array of GroupIdentifier objects",
|
||||
"desc": "The security groups for the instance.",
|
||||
"example": {
|
||||
"item": {
|
||||
"groupId": "sg-e4076980",
|
||||
"groupName": "SecurityGroup1"
|
||||
}
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "hibernationOptions",
|
||||
"type": "json",
|
||||
"type": "HibernationOptions object",
|
||||
"desc": "Indicates whether the instance is enabled for hibernation.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "hypervisor",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The hypervisor type of the instance. The value xen is used for both Xen and Nitro hypervisors.",
|
||||
"example": "xen"
|
||||
"example": "ovm"
|
||||
},
|
||||
{
|
||||
"name": "iamInstanceProfile",
|
||||
"type": "json",
|
||||
"type": "IamInstanceProfile object",
|
||||
"desc": "The IAM instance profile associated with the instance, if applicable.",
|
||||
"example": {
|
||||
"arn": "arn:aws:iam::123456789012:instance-profile/AdminRole",
|
||||
"id": "ABCAJEDNCAA64SSD123AB"
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "imageId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The ID of the AMI used to launch the instance.",
|
||||
"example": "ami-bff32ccc"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "instanceId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The ID of the instance.",
|
||||
"example": "i-1234567890abcdef0"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "instanceLifecycle",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "Indicates whether this is a Spot Instance or a Scheduled Instance.",
|
||||
"example": null
|
||||
"example": "spot"
|
||||
},
|
||||
{
|
||||
"name": "instanceState",
|
||||
"type": "json",
|
||||
"type": "InstanceState object",
|
||||
"desc": "The current state of the instance.",
|
||||
"example": {
|
||||
"code": "16",
|
||||
"name": "running"
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "instanceType",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The instance type.",
|
||||
"example": "t2.micro"
|
||||
"example": "a1.medium"
|
||||
},
|
||||
{
|
||||
"name": "ipAddress",
|
||||
"type": "文本",
|
||||
"desc": "The public IPv4 address, or the Carrier IP address assigned to the instance, if applicable.",
|
||||
"example": "54.194.252.215"
|
||||
"type": "String",
|
||||
"desc": "The public IPv4 address, or the Carrier IP address assigned to the instance, if applicable. A Carrier IP address only applies to an instance launched in a subnet associated with a Wavelength Zone.",
|
||||
"example": "Required: No"
|
||||
},
|
||||
{
|
||||
"name": "ipv6Address",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The IPv6 address assigned to the instance.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "kernelId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The kernel associated with this instance, if applicable.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "keyName",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The name of the key pair, if this instance was launched with an associated key pair.",
|
||||
"example": "my_keypair"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "launchTime",
|
||||
"type": "Time",
|
||||
"type": "Timestamp",
|
||||
"desc": "The time the instance was launched.",
|
||||
"example": "2018-05-08T16:46:19.000Z"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "licenseSet",
|
||||
"type": "json",
|
||||
"type": "Array of LicenseConfiguration objects",
|
||||
"desc": "The license configurations for the instance.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "maintenanceOptions",
|
||||
"type": "json",
|
||||
"type": "InstanceMaintenanceOptions object",
|
||||
"desc": "Provides information on the recovery and maintenance options of your instance.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "metadataOptions",
|
||||
"type": "json",
|
||||
"type": "InstanceMetadataOptionsResponse object",
|
||||
"desc": "The metadata options for the instance.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "monitoring",
|
||||
"type": "json",
|
||||
"type": "Monitoring object",
|
||||
"desc": "The monitoring for the instance.",
|
||||
"example": {
|
||||
"state": "disabled"
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "networkInterfaceSet",
|
||||
"type": "json",
|
||||
"type": "Array of InstanceNetworkInterface objects",
|
||||
"desc": "The network interfaces for the instance.",
|
||||
"example": {
|
||||
"item": {
|
||||
"networkInterfaceId": "eni-551ba033",
|
||||
"subnetId": "subnet-56f5f633",
|
||||
"vpcId": "vpc-11112222",
|
||||
"description": "Primary network interface",
|
||||
"ownerId": "123456789012",
|
||||
"status": "in-use",
|
||||
"macAddress": "02:dd:2c:5e:01:69",
|
||||
"privateIpAddress": "192.168.1.88",
|
||||
"privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
|
||||
"sourceDestCheck": "true",
|
||||
"groupSet": {
|
||||
"item": {
|
||||
"groupId": "sg-e4076980",
|
||||
"groupName": "SecurityGroup1"
|
||||
}
|
||||
},
|
||||
"attachment": {
|
||||
"attachmentId": "eni-attach-39697adc",
|
||||
"deviceIndex": "0",
|
||||
"status": "attached",
|
||||
"attachTime": "2018-05-08T16:46:19.000Z",
|
||||
"deleteOnTermination": "true"
|
||||
},
|
||||
"association": {
|
||||
"publicIp": "54.194.252.215",
|
||||
"publicDnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
|
||||
"ipOwnerId": "amazon"
|
||||
},
|
||||
"privateIpAddressesSet": {
|
||||
"item": {
|
||||
"privateIpAddress": "192.168.1.88",
|
||||
"privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
|
||||
"primary": "true",
|
||||
"association": {
|
||||
"publicIp": "54.194.252.215",
|
||||
"publicDnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
|
||||
"ipOwnerId": "amazon"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ipv6AddressesSet": {
|
||||
"item": {
|
||||
"ipv6Address": "2001:db8:1234:1a2b::123"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "outpostArn",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The Amazon Resource Name (ARN) of the Outpost.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "placement",
|
||||
"type": "json",
|
||||
"type": "Placement object",
|
||||
"desc": "The location where the instance launched, if applicable.",
|
||||
"example": {
|
||||
"availabilityZone": "eu-west-1c",
|
||||
"groupName": null,
|
||||
"tenancy": "default"
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "platform",
|
||||
"type": "文本",
|
||||
"desc": "The value is Windows for Windows instances; otherwise blank.",
|
||||
"example": null
|
||||
"type": "String",
|
||||
"desc": "The platform. This value is windows for Windows instances; otherwise, it is empty.",
|
||||
"example": "windows"
|
||||
},
|
||||
{
|
||||
"name": "platformDetails",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The platform details value for the instance. For more information, see AMI billing information fields in the Amazon EC2 User Guide.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "privateDnsName",
|
||||
"type": "文本",
|
||||
"desc": "[IPv4 only] The private DNS hostname name assigned to the instance. This DNS hostname can only be used inside the Amazon EC2 network. This name is not available until the instance enters the running state.",
|
||||
"example": "ip-192-168-1-88.eu-west-1.compute.internal"
|
||||
"type": "String",
|
||||
"desc": "[IPv4 only] The private DNS hostname name assigned to the instance. This DNS hostname can only be used inside the Amazon EC2 network. This name is not available until the instance enters the running state. The Amazon-provided DNS server resolves Amazon-provided private DNS hostnames if you've enabled DNS resolution and DNS hostnames in your VPC. If you are not using the Amazon-provided DNS server in your VPC, your custom domain name servers must resolve the hostname as appropriate.",
|
||||
"example": "Required: No"
|
||||
},
|
||||
{
|
||||
"name": "privateDnsNameOptions",
|
||||
"type": "json",
|
||||
"type": "PrivateDnsNameOptionsResponse object",
|
||||
"desc": "The options for the instance hostname.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "privateIpAddress",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The private IPv4 address assigned to the instance.",
|
||||
"example": "192.168.1.88"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "productCodes",
|
||||
"type": "json",
|
||||
"type": "Array of ProductCode objects",
|
||||
"desc": "The product codes attached to this instance, if applicable.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "ramdiskId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The RAM disk associated with this instance, if applicable.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "reason",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The reason for the most recent state transition. This might be an empty string.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "rootDeviceName",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The device name of the root device volume (for example, /dev/sda1).",
|
||||
"example": "/dev/xvda"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "rootDeviceType",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The root device type used by the AMI. The AMI can use an EBS volume or an instance store volume.",
|
||||
"example": "ebs"
|
||||
},
|
||||
@@ -357,71 +279,66 @@
|
||||
"name": "sourceDestCheck",
|
||||
"type": "Boolean",
|
||||
"desc": "Indicates whether source/destination checking is enabled.",
|
||||
"example": "true"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "spotInstanceRequestId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "If the request is a Spot Instance request, the ID of the request.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "sriovNetSupport",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "Specifies whether enhanced networking with the Intel 82599 Virtual Function interface is enabled.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "stateReason",
|
||||
"type": "json",
|
||||
"type": "StateReason object",
|
||||
"desc": "The reason for the most recent state transition.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "subnetId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The ID of the subnet in which the instance is running.",
|
||||
"example": "subnet-56f5f633"
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "tagSet",
|
||||
"type": "json",
|
||||
"type": "Array of Tag objects",
|
||||
"desc": "Any tags assigned to the instance.",
|
||||
"example": {
|
||||
"item": {
|
||||
"key": "Name",
|
||||
"value": "Server_1"
|
||||
}
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "tpmSupport",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "If the instance is configured for NitroTPM support, the value is v2.0. For more information, see NitroTPM in the Amazon EC2 User Guide.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "usageOperation",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The usage operation value for the instance. For more information, see AMI billing information fields in the Amazon EC2 User Guide.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "usageOperationUpdateTime",
|
||||
"type": "Time",
|
||||
"type": "Timestamp",
|
||||
"desc": "The time that the usage operation was last updated.",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "virtualizationType",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The virtualization type of the instance.",
|
||||
"example": "hvm"
|
||||
},
|
||||
{
|
||||
"name": "vpcId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "The ID of the VPC in which the instance is running.",
|
||||
"example": "vpc-11112222"
|
||||
"example": ""
|
||||
}
|
||||
]
|
@@ -1,292 +1,284 @@
|
||||
[
|
||||
{
|
||||
"name": "status",
|
||||
"type": "文本",
|
||||
"example": "ACTIVE",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u72b6\u6001\u3002\n\n\u53d6\u503c\u8303\u56f4:\n\nACTIVE\u3001BUILD\u3001DELETED\u3001ERROR\u3001HARD_REBOOT\u3001MIGRATING\u3001PAUSED\u3001REBOOT\u3001REBUILD\u3001RESIZE\u3001REVERT_RESIZE\u3001SHUTOFF\u3001SHELVED\u3001SHELVED_OFFLOADED\u3001SOFT_DELETED\u3001SUSPENDED\u3001VERIFY_RESIZE\n\n\u5f39\u6027\u4e91\u670d\u52a1\u5668\u72b6\u6001\u8bf4\u660e\u8bf7\u53c2\u8003[\u4e91\u670d\u52a1\u5668\u72b6\u6001](https://support.huaweicloud.com/api-ecs/ecs_08_0002.html)"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器状态。\n\n取值范围:\n\nACTIVE、BUILD、DELETED、ERROR、HARD_REBOOT、MIGRATING、PAUSED、REBOOT、REBUILD、RESIZE、REVERT_RESIZE、SHUTOFF、SHELVED、SHELVED_OFFLOADED、SOFT_DELETED、SUSPENDED、VERIFY_RESIZE\n\n弹性云服务器状态说明请参考[云服务器状态](https://support.huaweicloud.com/api-ecs/ecs_08_0002.html)",
|
||||
"example": "ACTIVE"
|
||||
},
|
||||
{
|
||||
"name": "updated",
|
||||
"type": "文本",
|
||||
"example": "2019-05-22T03:30:52Z",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u66f4\u65b0\u65f6\u95f4\u3002\n\n\u65f6\u95f4\u683c\u5f0f\u4f8b\u5982:2019-05-22T03:30:52Z"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器更新时间。\n\n时间格式例如:2019-05-22T03:30:52Z",
|
||||
"example": "2019-05-22T03:30:52Z"
|
||||
},
|
||||
{
|
||||
"name": "auto_terminate_time",
|
||||
"type": "文本",
|
||||
"example": "2020-01-19T03:30:52Z",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u81ea\u52a8\u91ca\u653e\u65f6\u95f4\u3002\n\n\u65f6\u95f4\u683c\u5f0f\u4f8b\u5982:2020-01-19T03:30:52Z"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器定时删除时间。\n\n时间格式例如:2020-01-19T03:30:52Z",
|
||||
"example": "2020-01-19T03:30:52Z"
|
||||
},
|
||||
{
|
||||
"name": "hostId",
|
||||
"type": "文本",
|
||||
"example": "c7145889b2e3202cd295ceddb1742ff8941b827b586861fd0acedf64",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6240\u5728\u4e3b\u673a\u7684\u4e3b\u673aID\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器所在主机的主机ID。",
|
||||
"example": "c7145889b2e3202cd295ceddb1742ff8941b827b586861fd0acedf64"
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:host",
|
||||
"type": "文本",
|
||||
"example": "pod01.cn-north-1c",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6240\u5728\u4e3b\u673a\u7684\u4e3b\u673a\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器所在主机的主机名称。",
|
||||
"example": "pod01.cn-north-1c"
|
||||
},
|
||||
{
|
||||
"name": "addresses",
|
||||
"type": "json",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u7f51\u7edc\u5c5e\u6027\u3002"
|
||||
"type": "object",
|
||||
"desc": "弹性云服务器的网络属性。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "key_name",
|
||||
"type": "文本",
|
||||
"example": "KeyPair-test",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u4f7f\u7528\u7684\u5bc6\u94a5\u5bf9\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器使用的密钥对名称。",
|
||||
"example": "KeyPair-test"
|
||||
},
|
||||
{
|
||||
"name": "image",
|
||||
"type": "json",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u955c\u50cf\u4fe1\u606f\u3002"
|
||||
"type": "",
|
||||
"desc": "弹性云服务器镜像信息。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-STS:task_state",
|
||||
"type": "文本",
|
||||
"example": "rebooting",
|
||||
"desc": "\u6269\u5c55\u5c5e\u6027,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u5f53\u524d\u4efb\u52a1\u7684\u72b6\u6001\u3002\n\n\u53d6\u503c\u8303\u56f4\u8bf7\u53c2\u8003[\u4e91\u670d\u52a1\u5668\u72b6\u6001](https://support.huaweicloud.com/api-ecs/ecs_08_0002.html)\u88683\u3002"
|
||||
"type": "string",
|
||||
"desc": "扩展属性,弹性云服务器当前任务的状态。\n\n取值范围请参考[云服务器状态](https://support.huaweicloud.com/api-ecs/ecs_08_0002.html)表3。",
|
||||
"example": "rebooting"
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-STS:vm_state",
|
||||
"type": "文本",
|
||||
"example": "active",
|
||||
"desc": "\u6269\u5c55\u5c5e\u6027,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u5f53\u524d\u72b6\u6001\u3002\n\n\u4e91\u670d\u52a1\u5668\u72b6\u6001\u8bf4\u660e\u8bf7\u53c2\u8003[\u4e91\u670d\u52a1\u5668\u72b6\u6001](https://support.huaweicloud.com/api-ecs/ecs_08_0002.html)\u3002"
|
||||
"type": "string",
|
||||
"desc": "扩展属性,弹性云服务器当前状态。\n\n云服务器状态说明请参考[云服务器状态](https://support.huaweicloud.com/api-ecs/ecs_08_0002.html)。",
|
||||
"example": "active"
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:instance_name",
|
||||
"type": "文本",
|
||||
"example": "instance-0048a91b",
|
||||
"desc": "\u6269\u5c55\u5c5e\u6027,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u522b\u540d\u3002"
|
||||
"type": "string",
|
||||
"desc": "扩展属性,弹性云服务器别名。",
|
||||
"example": "instance-0048a91b"
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:hypervisor_hostname",
|
||||
"type": "文本",
|
||||
"example": "nova022@36",
|
||||
"desc": "\u6269\u5c55\u5c5e\u6027,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6240\u5728\u865a\u62df\u5316\u4e3b\u673a\u540d\u3002"
|
||||
"type": "string",
|
||||
"desc": "扩展属性,弹性云服务器所在虚拟化主机名。",
|
||||
"example": "nova022@36"
|
||||
},
|
||||
{
|
||||
"name": "flavor",
|
||||
"type": "json",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u89c4\u683c\u4fe1\u606f\u3002"
|
||||
"type": "",
|
||||
"desc": "弹性云服务器规格信息。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"type": "文本",
|
||||
"example": "4f4b3dfa-eb70-47cf-a60a-998a53bd6666",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668ID,\u683c\u5f0f\u4e3aUUID\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器ID,格式为UUID。",
|
||||
"example": "4f4b3dfa-eb70-47cf-a60a-998a53bd6666"
|
||||
},
|
||||
{
|
||||
"name": "security_groups",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"$ref": "#/definitions/ServerSecurityGroup"
|
||||
},
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6240\u5c5e\u5b89\u5168\u7ec4\u5217\u8868\u3002"
|
||||
"type": "array",
|
||||
"desc": "弹性云服务器所属安全组列表。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-AZ:availability_zone",
|
||||
"type": "文本",
|
||||
"example": "cn-north-1c",
|
||||
"desc": "\u6269\u5c55\u5c5e\u6027,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6240\u5728\u53ef\u7528\u533a\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "扩展属性,弹性云服务器所在可用区名称。",
|
||||
"example": "cn-north-1c"
|
||||
},
|
||||
{
|
||||
"name": "user_id",
|
||||
"type": "文本",
|
||||
"example": "05498fe56b8010d41f7fc01e280b6666",
|
||||
"desc": "\u521b\u5efa\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u7528\u6237ID,\u683c\u5f0f\u4e3aUUID\u3002"
|
||||
"type": "string",
|
||||
"desc": "创建弹性云服务器的用户ID,格式为UUID。",
|
||||
"example": "05498fe56b8010d41f7fc01e280b6666"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "文本",
|
||||
"example": "ecs-test-server",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器名称。",
|
||||
"example": "ecs-test-server"
|
||||
},
|
||||
{
|
||||
"name": "created",
|
||||
"type": "文本",
|
||||
"example": "2017-07-15T11:30:52Z",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u521b\u5efa\u65f6\u95f4\u3002\n\n\u65f6\u95f4\u683c\u5f0f\u4f8b\u5982:2019-05-22T03:19:19Z"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器创建时间。\n\n时间格式例如:2019-05-22T03:19:19Z",
|
||||
"example": "2017-07-15T11:30:52Z"
|
||||
},
|
||||
{
|
||||
"name": "tenant_id",
|
||||
"type": "文本",
|
||||
"example": "743b4c0428d94531b9f2add666646666",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6240\u5c5e\u79df\u6237ID,\u5373\u9879\u76eeid,\u548cproject_id\u8868\u793a\u76f8\u540c\u7684\u6982\u5ff5,\u683c\u5f0f\u4e3aUUID\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器所属租户ID,即项目id,和project_id表示相同的概念,格式为UUID。",
|
||||
"example": "743b4c0428d94531b9f2add666646666"
|
||||
},
|
||||
{
|
||||
"name": "OS-DCF:diskConfig",
|
||||
"type": "文本",
|
||||
"example": "AUTO",
|
||||
"desc": "\u6269\u5c55\u5c5e\u6027, diskConfig\u7684\u7c7b\u578b\u3002\n\n- MANUAL,\u955c\u50cf\u7a7a\u95f4\u4e0d\u4f1a\u6269\u5c55\u3002\n- AUTO,\u7cfb\u7edf\u76d8\u955c\u50cf\u7a7a\u95f4\u4f1a\u81ea\u52a8\u6269\u5c55\u4e3a\u4e0eflavor\u5927\u5c0f\u4e00\u81f4\u3002"
|
||||
"type": "string",
|
||||
"desc": "扩展属性, diskConfig的类型。\n\n- MANUAL,镜像空间不会扩展。\n- AUTO,系统盘镜像空间会自动扩展为与flavor大小一致。",
|
||||
"example": "AUTO"
|
||||
},
|
||||
{
|
||||
"name": "accessIPv4",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "\u9884\u7559\u5c5e\u6027\u3002"
|
||||
"type": "string",
|
||||
"desc": "预留属性。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "accessIPv6",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "\u9884\u7559\u5c5e\u6027\u3002"
|
||||
"type": "string",
|
||||
"desc": "预留属性。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "fault",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6545\u969c\u4fe1\u606f\u3002\n\n\u53ef\u9009\u53c2\u6570,\u5728\u5f39\u6027\u4e91\u670d\u52a1\u5668\u72b6\u6001\u4e3aERROR\u4e14\u5b58\u5728\u5f02\u5e38\u7684\u60c5\u51b5\u4e0b\u8fd4\u56de\u3002"
|
||||
"type": "",
|
||||
"desc": "弹性云服务器故障信息。\n\n可选参数,在弹性云服务器状态为ERROR且存在异常的情况下返回。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "progress",
|
||||
"type": "整数",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u8fdb\u5ea6\u3002"
|
||||
"type": "integer",
|
||||
"desc": "弹性云服务器进度。",
|
||||
"example": 0
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-STS:power_state",
|
||||
"type": "整数",
|
||||
"example": 4,
|
||||
"desc": "\u6269\u5c55\u5c5e\u6027,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7535\u6e90\u72b6\u6001\u3002"
|
||||
"type": "integer",
|
||||
"desc": "扩展属性,弹性云服务器电源状态。",
|
||||
"example": 4
|
||||
},
|
||||
{
|
||||
"name": "config_drive",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "config drive\u4fe1\u606f\u3002"
|
||||
"type": "string",
|
||||
"desc": "config drive信息。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "metadata",
|
||||
"type": "json",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u5143\u6570\u636e\u3002\n\n> \u8bf4\u660e:\n> \n> \u5143\u6570\u636e\u5305\u542b\u7cfb\u7edf\u9ed8\u8ba4\u6dfb\u52a0\u5b57\u6bb5\u548c\u7528\u6237\u8bbe\u7f6e\u7684\u5b57\u6bb5\u3002\n\n\u7cfb\u7edf\u9ed8\u8ba4\u6dfb\u52a0\u5b57\u6bb5\n\n1. charging_mode\n\u4e91\u670d\u52a1\u5668\u7684\u8ba1\u8d39\u7c7b\u578b\u3002\n\n- \u201c0\u201d:\u6309\u9700\u8ba1\u8d39(\u5373postPaid-\u540e\u4ed8\u8d39\u65b9\u5f0f)\u3002\n- \u201c1\u201d:\u6309\u5305\u5e74\u5305\u6708\u8ba1\u8d39(\u5373prePaid-\u9884\u4ed8\u8d39\u65b9\u5f0f)\u3002\"2\":\u7ade\u4ef7\u5b9e\u4f8b\u8ba1\u8d39\n\n2. metering.order_id\n\u6309\u201c\u5305\u5e74/\u5305\u6708\u201d\u8ba1\u8d39\u7684\u4e91\u670d\u52a1\u5668\u5bf9\u5e94\u7684\u8ba2\u5355ID\u3002\n\n3. metering.product_id\n\u6309\u201c\u5305\u5e74/\u5305\u6708\u201d\u8ba1\u8d39\u7684\u4e91\u670d\u52a1\u5668\u5bf9\u5e94\u7684\u4ea7\u54c1ID\u3002\n\n4. vpc_id\n\u4e91\u670d\u52a1\u5668\u6240\u5c5e\u7684\u865a\u62df\u79c1\u6709\u4e91ID\u3002\n\n5. EcmResStatus\n\u4e91\u670d\u52a1\u5668\u7684\u51bb\u7ed3\u72b6\u6001\u3002\n\n- normal:\u4e91\u670d\u52a1\u5668\u6b63\u5e38\u72b6\u6001(\u672a\u88ab\u51bb\u7ed3)\u3002\n- freeze:\u4e91\u670d\u52a1\u5668\u88ab\u51bb\u7ed3\u3002\n\n> \u5f53\u4e91\u670d\u52a1\u5668\u88ab\u51bb\u7ed3\u6216\u8005\u89e3\u51bb\u540e,\u7cfb\u7edf\u9ed8\u8ba4\u6dfb\u52a0\u8be5\u5b57\u6bb5,\u4e14\u8be5\u5b57\u6bb5\u5fc5\u9009\u3002\n\n6. metering.image_id\n\u4e91\u670d\u52a1\u5668\u64cd\u4f5c\u7cfb\u7edf\u5bf9\u5e94\u7684\u955c\u50cfID\n\n7. metering.imagetype\n\u955c\u50cf\u7c7b\u578b,\u76ee\u524d\u652f\u6301:\n\n- \u516c\u5171\u955c\u50cf(gold)\n- \u79c1\u6709\u955c\u50cf(private)\n- \u5171\u4eab\u955c\u50cf(shared)\n\n8. metering.resourcespeccode\n\u4e91\u670d\u52a1\u5668\u5bf9\u5e94\u7684\u8d44\u6e90\u89c4\u683c\u3002\n\n9. image_name\n\u4e91\u670d\u52a1\u5668\u64cd\u4f5c\u7cfb\u7edf\u5bf9\u5e94\u7684\u955c\u50cf\u540d\u79f0\u3002\n\n10. os_bit\n\u64cd\u4f5c\u7cfb\u7edf\u4f4d\u6570,\u4e00\u822c\u53d6\u503c\u4e3a\u201c32\u201d\u6216\u8005\u201c64\u201d\u3002\n\n11. lockCheckEndpoint\n\u56de\u8c03URL,\u7528\u4e8e\u68c0\u67e5\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u52a0\u9501\u662f\u5426\u6709\u6548\u3002\n\n- \u5982\u679c\u6709\u6548,\u5219\u4e91\u670d\u52a1\u5668\u4fdd\u6301\u9501\u5b9a\u72b6\u6001\u3002\n- \u5982\u679c\u65e0\u6548,\u89e3\u9664\u9501\u5b9a\u72b6\u6001,\u5220\u9664\u5931\u6548\u7684\u9501\u3002\n\n12. lockSource\n\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6765\u81ea\u54ea\u4e2a\u670d\u52a1\u3002\u8ba2\u5355\u52a0\u9501(ORDER)\n\n13. lockSourceId\n\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u52a0\u9501\u6765\u81ea\u54ea\u4e2aID\u3002lockSource\u4e3a\u201cORDER\u201d\u65f6,lockSourceId\u4e3a\u8ba2\u5355ID\u3002\n\n14. lockScene\n\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u52a0\u9501\u7c7b\u578b\u3002\n\n- \u6309\u9700\u8f6c\u5305\u5468\u671f(TO_PERIOD_LOCK)\n\n15. virtual_env_type\n\n- IOS\u955c\u50cf\u521b\u5efa\u865a\u62df\u673a,\"virtual_env_type\": \"IsoImage\" \u5c5e\u6027;\n- \u975eIOS\u955c\u50cf\u521b\u5efa\u865a\u62df\u673a,\u572819.5.0\u7248\u672c\u4ee5\u540e\u521b\u5efa\u7684\u865a\u62df\u673a\u5c06\u4e0d\u4f1a\u6dfb\u52a0virtual_env_type \u5c5e\u6027,\u800c\u5728\u6b64\u4e4b\u524d\u7684\u7248\u672c\u521b\u5efa\u7684\u865a\u62df\u673a\u53ef\u80fd\u4f1a\u8fd4\u56de\"virtual_env_type\": \"FusionCompute\"\u5c5e\u6027 \u3002\n\n> virtual_env_type\u5c5e\u6027\u4e0d\u5141\u8bb8\u7528\u6237\u589e\u52a0\u3001\u5220\u9664\u548c\u4fee\u6539\u3002\n\n16. metering.resourcetype\n\u4e91\u670d\u52a1\u5668\u5bf9\u5e94\u7684\u8d44\u6e90\u7c7b\u578b\u3002\n\n17. os_type\n\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b,\u53d6\u503c\u4e3a:Linux\u3001Windows\u3002\n\n18. cascaded.instance_extrainfo\n\u7cfb\u7edf\u5185\u90e8\u865a\u62df\u673a\u6269\u5c55\u4fe1\u606f\u3002\n\n19. __support_agent_list\n\u4e91\u670d\u52a1\u5668\u662f\u5426\u652f\u6301\u4f01\u4e1a\u4e3b\u673a\u5b89\u5168\u3001\u4e3b\u673a\u76d1\u63a7\u3002\n\n- \u201chss\u201d:\u4f01\u4e1a\u4e3b\u673a\u5b89\u5168\n- \u201cces\u201d:\u4e3b\u673a\u76d1\u63a7\n\n20. agency_name\n\u59d4\u6258\u7684\u540d\u79f0\u3002\n\n\u59d4\u6258\u662f\u7531\u79df\u6237\u7ba1\u7406\u5458\u5728\u7edf\u4e00\u8eab\u4efd\u8ba4\u8bc1\u670d\u52a1(Identity and Access Management,IAM)\u4e0a\u521b\u5efa\u7684,\u53ef\u4ee5\u4e3a\u5f39\u6027\u4e91\u670d\u52a1\u5668\u63d0\u4f9b\u8bbf\u95ee\u4e91\u670d\u52a1\u7684\u4e34\u65f6\u51ed\u8bc1\u3002"
|
||||
"type": "object",
|
||||
"desc": "弹性云服务器元数据。\n\n> 说明:\n> \n> 元数据包含系统默认添加字段和用户设置的字段。\n\n系统默认添加字段\n\n1. charging_mode\n云服务器的计费类型。\n\n- “0”:按需计费(即postPaid-后付费方式)。\n- “1”:按包年包月计费(即prePaid-预付费方式)。\"2\":竞价实例计费\n\n2. metering.order_id\n按“包年/包月”计费的云服务器对应的订单ID。\n\n3. metering.product_id\n按“包年/包月”计费的云服务器对应的产品ID。\n\n4. vpc_id\n云服务器所属的虚拟私有云ID。\n\n5. EcmResStatus\n云服务器的冻结状态。\n\n- normal:云服务器正常状态(未被冻结)。\n- freeze:云服务器被冻结。\n\n> 当云服务器被冻结或者解冻后,系统默认添加该字段,且该字段必选。\n\n6. metering.image_id\n云服务器操作系统对应的镜像ID\n\n7. metering.imagetype\n镜像类型,目前支持:\n\n- 公共镜像(gold)\n- 私有镜像(private)\n- 共享镜像(shared)\n\n8. metering.resourcespeccode\n云服务器对应的资源规格。\n\n9. image_name\n云服务器操作系统对应的镜像名称。\n\n10. os_bit\n操作系统位数,一般取值为“32”或者“64”。\n\n11. lockCheckEndpoint\n回调URL,用于检查弹性云服务器的加锁是否有效。\n\n- 如果有效,则云服务器保持锁定状态。\n- 如果无效,解除锁定状态,删除失效的锁。\n\n12. lockSource\n弹性云服务器来自哪个服务。订单加锁(ORDER)\n\n13. lockSourceId\n弹性云服务器的加锁来自哪个ID。lockSource为“ORDER”时,lockSourceId为订单ID。\n\n14. lockScene\n弹性云服务器的加锁类型。\n\n- 按需转包周期(TO_PERIOD_LOCK)\n\n15. virtual_env_type\n\n- IOS镜像创建虚拟机,\"virtual_env_type\": \"IsoImage\" 属性;\n- 非IOS镜像创建虚拟机,在19.5.0版本以后创建的虚拟机将不会添加virtual_env_type 属性,而在此之前的版本创建的虚拟机可能会返回\"virtual_env_type\": \"FusionCompute\"属性 。\n\n> virtual_env_type属性不允许用户增加、删除和修改。\n\n16. metering.resourcetype\n云服务器对应的资源类型。\n\n17. os_type\n操作系统类型,取值为:Linux、Windows。\n\n18. cascaded.instance_extrainfo\n系统内部虚拟机扩展信息。\n\n19. __support_agent_list\n云服务器是否支持企业主机安全、主机监控。\n\n- “hss”:企业主机安全\n- “ces”:主机监控\n\n20. agency_name\n委托的名称。\n\n委托是由租户管理员在统一身份认证服务(Identity and Access Management,IAM)上创建的,可以为弹性云服务器提供访问云服务的临时凭证。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "OS-SRV-USG:launched_at",
|
||||
"type": "文本",
|
||||
"example": "2018-08-15T14:21:22.000000",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u542f\u52a8\u65f6\u95f4\u3002\u65f6\u95f4\u683c\u5f0f\u4f8b\u5982:2019-05-22T03:23:59.000000"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器启动时间。时间格式例如:2019-05-22T03:23:59.000000",
|
||||
"example": "2018-08-15T14:21:22.000000"
|
||||
},
|
||||
{
|
||||
"name": "OS-SRV-USG:terminated_at",
|
||||
"type": "文本",
|
||||
"example": "2019-05-22T03:23:59.000000",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u5220\u9664\u65f6\u95f4\u3002\n\n\u65f6\u95f4\u683c\u5f0f\u4f8b\u5982:2019-05-22T03:23:59.000000"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器删除时间。\n\n时间格式例如:2019-05-22T03:23:59.000000",
|
||||
"example": "2019-05-22T03:23:59.000000"
|
||||
},
|
||||
{
|
||||
"name": "os-extended-volumes:volumes_attached",
|
||||
"type": "json",
|
||||
"example": {
|
||||
"$ref": "#/definitions/ServerExtendVolumeAttachment"
|
||||
},
|
||||
"desc": "\u6302\u8f7d\u5230\u5f39\u6027\u4e91\u670d\u52a1\u5668\u4e0a\u7684\u78c1\u76d8\u3002"
|
||||
"type": "array",
|
||||
"desc": "挂载到弹性云服务器上的磁盘。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"type": "文本",
|
||||
"example": "ecs description",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u63cf\u8ff0\u4fe1\u606f\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器的描述信息。",
|
||||
"example": "ecs description"
|
||||
},
|
||||
{
|
||||
"name": "host_status",
|
||||
"type": "文本",
|
||||
"example": "UP",
|
||||
"desc": "nova-compute\u72b6\u6001\u3002\n\n- UP:\u670d\u52a1\u6b63\u5e38\n- UNKNOWN:\u72b6\u6001\u672a\u77e5\n- DOWN:\u670d\u52a1\u5f02\u5e38\n- MAINTENANCE:\u7ef4\u62a4\u72b6\u6001\n- \u7a7a\u5b57\u7b26\u4e32:\u5f39\u6027\u4e91\u670d\u52a1\u5668\u65e0\u4e3b\u673a\u4fe1\u606f"
|
||||
"type": "string",
|
||||
"desc": "nova-compute状态。\n\n- UP:服务正常\n- UNKNOWN:状态未知\n- DOWN:服务异常\n- MAINTENANCE:维护状态\n- 空字符串:弹性云服务器无主机信息",
|
||||
"example": "UP"
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:hostname",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u4e3b\u673a\u540d\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器的主机名。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:reservation_id",
|
||||
"type": "文本",
|
||||
"example": "r-f06p3js8",
|
||||
"desc": "\u6279\u91cf\u521b\u5efa\u573a\u666f,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u9884\u7559ID\u3002"
|
||||
"type": "string",
|
||||
"desc": "批量创建场景,弹性云服务器的预留ID。",
|
||||
"example": "r-f06p3js8"
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:launch_index",
|
||||
"type": "整数",
|
||||
"example": null,
|
||||
"desc": "\u6279\u91cf\u521b\u5efa\u573a\u666f,\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7684\u542f\u52a8\u987a\u5e8f\u3002"
|
||||
"type": "integer",
|
||||
"desc": "批量创建场景,弹性云服务器的启动顺序。",
|
||||
"example": 0
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:kernel_id",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "\u82e5\u4f7f\u7528AMI\u683c\u5f0f\u7684\u955c\u50cf,\u5219\u8868\u793akernel image\u7684UUID;\u5426\u5219,\u7559\u7a7a\u3002"
|
||||
"type": "string",
|
||||
"desc": "若使用AMI格式的镜像,则表示kernel image的UUID;否则,留空。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:ramdisk_id",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "\u82e5\u4f7f\u7528AMI\u683c\u5f0f\u955c\u50cf,\u5219\u8868\u793aramdisk image\u7684UUID;\u5426\u5219,\u7559\u7a7a\u3002"
|
||||
"type": "string",
|
||||
"desc": "若使用AMI格式镜像,则表示ramdisk image的UUID;否则,留空。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:root_device_name",
|
||||
"type": "文本",
|
||||
"example": "/dev/vda",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7cfb\u7edf\u76d8\u7684\u8bbe\u5907\u540d\u79f0\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器系统盘的设备名称。",
|
||||
"example": "/dev/vda"
|
||||
},
|
||||
{
|
||||
"name": "OS-EXT-SRV-ATTR:user_data",
|
||||
"type": "文本",
|
||||
"example": "IyEvYmluL2Jhc2gKZWNobyAncm9vdDokNiRjcGRkSjckWm5WZHNiR253Z0l0SGlxUjZxbWtLTlJaeU9lZUtKd3dPbG9XSFdUeGFzWjA1STYwdnJYRTdTUTZGbEpFbWlXZ21WNGNmZ1pac1laN1BkMTBLRndyeC8nIHwgY2hwYXNzd2Q6666",
|
||||
"desc": "\u521b\u5efa\u5f39\u6027\u4e91\u670d\u52a1\u5668\u65f6\u6307\u5b9a\u7684user_data\u3002"
|
||||
"type": "string",
|
||||
"desc": "创建弹性云服务器时指定的user_data。",
|
||||
"example": "IyEvYmluL2Jhc2gKZWNobyAncm9vdDokNiRjcGRkSjckWm5WZHNiR253Z0l0SGlxUjZxbWtLTlJaeU9lZUtKd3dPbG9XSFdUeGFzWjA1STYwdnJYRTdTUTZGbEpFbWlXZ21WNGNmZ1pac1laN1BkMTBLRndyeC8nIHwgY2hwYXNzd2Q6666"
|
||||
},
|
||||
{
|
||||
"name": "locked",
|
||||
"type": "boolean",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u662f\u5426\u4e3a\u9501\u5b9a\u72b6\u6001\u3002\n\n- true:\u9501\u5b9a\n- false:\u672a\u9501\u5b9a"
|
||||
"desc": "弹性云服务器是否为锁定状态。\n\n- true:锁定\n- false:未锁定",
|
||||
"example": false
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"type": "文本、多值",
|
||||
"example": {
|
||||
"type": "文本"
|
||||
},
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6807\u7b7e\u3002"
|
||||
"type": "array",
|
||||
"desc": "弹性云服务器标签。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "os:scheduler_hints",
|
||||
"type": "json",
|
||||
"example": null,
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u8c03\u5ea6\u4fe1\u606f"
|
||||
"type": "",
|
||||
"desc": "弹性云服务器调度信息",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "enterprise_project_id",
|
||||
"type": "文本",
|
||||
"example": "0",
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u6240\u5c5e\u7684\u4f01\u4e1a\u9879\u76eeID\u3002"
|
||||
"type": "string",
|
||||
"desc": "弹性云服务器所属的企业项目ID。",
|
||||
"example": "0"
|
||||
},
|
||||
{
|
||||
"name": "sys_tags",
|
||||
"type": "文本、多值",
|
||||
"example": {
|
||||
"$ref": "#/definitions/ServerSystemTag"
|
||||
},
|
||||
"desc": "\u5f39\u6027\u4e91\u670d\u52a1\u5668\u7cfb\u7edf\u6807\u7b7e\u3002"
|
||||
"type": "array",
|
||||
"desc": "弹性云服务器系统标签。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "cpu_options",
|
||||
"type": "json",
|
||||
"example": null,
|
||||
"desc": "\u81ea\u5b9a\u4e49CPU\u9009\u9879\u3002"
|
||||
"type": "",
|
||||
"desc": "自定义CPU选项。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "hypervisor",
|
||||
"type": "文本",
|
||||
"example": null,
|
||||
"desc": "hypervisor\u4fe1\u606f\u3002"
|
||||
"type": "",
|
||||
"desc": "hypervisor信息。",
|
||||
"example": ""
|
||||
}
|
||||
]
|
@@ -1,297 +1,248 @@
|
||||
[
|
||||
{
|
||||
"name": "Placement",
|
||||
"type": "json",
|
||||
"type": "Placement",
|
||||
"desc": "实例所在的位置。",
|
||||
"example": {
|
||||
"HostId": "host-h3m57oik",
|
||||
"ProjectId": 1174660,
|
||||
"HostIds": [],
|
||||
"Zone": "ap-guangzhou-1",
|
||||
"HostIps": []
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "InstanceId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例ID。",
|
||||
"example": "ins-xlsyru2j"
|
||||
"example": "ins-9bxebleo"
|
||||
},
|
||||
{
|
||||
"name": "InstanceType",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例机型。",
|
||||
"example": "S2.SMALL2"
|
||||
"example": "S1.SMALL1"
|
||||
},
|
||||
{
|
||||
"name": "CPU",
|
||||
"type": "整数",
|
||||
"type": "Integer",
|
||||
"desc": "实例的CPU核数,单位:核。",
|
||||
"example": 1
|
||||
"example": "1"
|
||||
},
|
||||
{
|
||||
"name": "Memory",
|
||||
"type": "整数",
|
||||
"type": "Integer",
|
||||
"desc": "实例内存容量,单位:GB。",
|
||||
"example": 1
|
||||
"example": "1"
|
||||
},
|
||||
{
|
||||
"name": "RestrictState",
|
||||
"type": "文本",
|
||||
"desc": "实例业务状态。取值范围: NORMAL:表示正常状态的实例 EXPIRED:表示过期的实例 PROTECTIVELY_ISOLATED:表示被安全隔离的实例。",
|
||||
"example": "PROTECTIVELY_ISOLATED"
|
||||
"type": "String",
|
||||
"desc": "NORMAL:表示正常状态的实例\nEXPIRED:表示过期的实例\nPROTECTIVELY_ISOLATED:表示被安全隔离的实例。",
|
||||
"example": "NORMAL"
|
||||
},
|
||||
{
|
||||
"name": "InstanceName",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例名称。",
|
||||
"example": "test"
|
||||
"example": "测试实例"
|
||||
},
|
||||
{
|
||||
"name": "InstanceChargeType",
|
||||
"type": "文本",
|
||||
"desc": "实例计费模式。取值范围: PREPAID:表示预付费,即包年包月 POSTPAID_BY_HOUR:表示后付费,即按量计费 CDHPAID:专用宿主机付费,即只对专用宿主机计费,不对专用宿主机上的实例计费。 SPOTPAID:表示竞价实例付费。",
|
||||
"example": "POSTPAID_BY_HOUR"
|
||||
"type": "String",
|
||||
"desc": "PREPAID:表示预付费,即包年包月\nPOSTPAID_BY_HOUR:表示后付费,即按量计费\nCDHPAID:专用宿主机付费,即只对专用宿主机计费,不对专用宿主机上的实例计费。\nSPOTPAID:表示竞价实例付费。",
|
||||
"example": "PREPAID"
|
||||
},
|
||||
{
|
||||
"name": "SystemDisk",
|
||||
"type": "json",
|
||||
"type": "SystemDisk",
|
||||
"desc": "实例系统盘信息。",
|
||||
"example": {
|
||||
"DiskSize": 50,
|
||||
"CdcId": null,
|
||||
"DiskId": "disk-czsodtl1",
|
||||
"DiskType": "CLOUD_SSD"
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "DataDisks",
|
||||
"type": "json",
|
||||
"type": "Array of DataDisk",
|
||||
"desc": "实例数据盘信息。",
|
||||
"example": [
|
||||
{
|
||||
"DeleteWithInstance": true,
|
||||
"Encrypt": true,
|
||||
"CdcId": null,
|
||||
"DiskType": "CLOUD_SSD",
|
||||
"ThroughputPerformance": 0,
|
||||
"KmsKeyId": null,
|
||||
"DiskSize": 50,
|
||||
"SnapshotId": null,
|
||||
"DiskId": "disk-bzsodtn1"
|
||||
}
|
||||
]
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "PrivateIpAddresses",
|
||||
"type": "文本、多值",
|
||||
"type": "Array of String",
|
||||
"desc": "实例主网卡的内网IP列表。",
|
||||
"example": [
|
||||
"172.16.32.78"
|
||||
]
|
||||
"example": "[\"172.16.32.78\"]"
|
||||
},
|
||||
{
|
||||
"name": "PublicIpAddresses",
|
||||
"type": "文本、多值",
|
||||
"type": "Array of String",
|
||||
"desc": "实例主网卡的公网IP列表。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": [
|
||||
"123.207.11.190"
|
||||
]
|
||||
"example": "[\"123.207.11.190\"]"
|
||||
},
|
||||
{
|
||||
"name": "InternetAccessible",
|
||||
"type": "json",
|
||||
"type": "InternetAccessible",
|
||||
"desc": "实例带宽信息。",
|
||||
"example": {
|
||||
"PublicIpAssigned": true,
|
||||
"InternetChargeType": "TRAFFIC_POSTPAID_BY_HOUR",
|
||||
"BandwidthPackageId": null,
|
||||
"InternetMaxBandwidthOut": 1
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "VirtualPrivateCloud",
|
||||
"type": "json",
|
||||
"type": "VirtualPrivateCloud",
|
||||
"desc": "实例所属虚拟私有网络信息。",
|
||||
"example": {
|
||||
"SubnetId": "subnet-mv4sn55k",
|
||||
"AsVpcGateway": false,
|
||||
"Ipv6AddressCount": 1,
|
||||
"VpcId": "vpc-m0cnatxj",
|
||||
"PrivateIpAddresses": [
|
||||
"172.16.3.59"
|
||||
]
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "ImageId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "生产实例所使用的镜像ID。",
|
||||
"example": "img-8toqc6s3"
|
||||
"example": "img-9qabwvbn"
|
||||
},
|
||||
{
|
||||
"name": "RenewFlag",
|
||||
"type": "文本",
|
||||
"desc": "自动续费标识。取值范围: NOTIFY_AND_MANUAL_RENEW:表示通知即将过期,但不自动续费 NOTIFY_AND_AUTO_RENEW:表示通知即将过期,而且自动续费 DISABLE_NOTIFY_AND_MANUAL_RENEW:表示不通知即将过期,也不自动续费。 注意:后付费模式本项为null",
|
||||
"type": "String",
|
||||
"desc": "NOTIFY_AND_MANUAL_RENEW:表示通知即将过期,但不自动续费\nNOTIFY_AND_AUTO_RENEW:表示通知即将过期,而且自动续费\nDISABLE_NOTIFY_AND_MANUAL_RENEW:表示不通知即将过期,也不自动续费。\n注意:后付费模式本项为null",
|
||||
"example": "NOTIFY_AND_MANUAL_RENEW"
|
||||
},
|
||||
{
|
||||
"name": "CreatedTime",
|
||||
"type": "json",
|
||||
"type": "Timestamp ISO8601",
|
||||
"desc": "创建时间。按照ISO8601标准表示,并且使用UTC时间。格式为:YYYY-MM-DDThh:mm:ssZ。",
|
||||
"example": "2020-09-22T00:00:00+00:00"
|
||||
"example": "2020-03-10T02:43:51Z"
|
||||
},
|
||||
{
|
||||
"name": "ExpiredTime",
|
||||
"type": "json",
|
||||
"type": "Timestamp ISO8601",
|
||||
"desc": "到期时间。按照ISO8601标准表示,并且使用UTC时间。格式为:YYYY-MM-DDThh:mm:ssZ。注意:后付费模式本项为null",
|
||||
"example": "2020-09-22T00:00:00+00:00"
|
||||
"example": "2020-04-10T02:47:36Z"
|
||||
},
|
||||
{
|
||||
"name": "OsName",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "操作系统名称。",
|
||||
"example": "CentOS 7.4 64bit"
|
||||
"example": "CentOS 7.6 64bit"
|
||||
},
|
||||
{
|
||||
"name": "SecurityGroupIds",
|
||||
"type": "文本、多值",
|
||||
"type": "Array of String",
|
||||
"desc": "实例所属安全组。该参数可以通过调用 DescribeSecurityGroups 的返回值中的sgId字段来获取。",
|
||||
"example": [
|
||||
"sg-p1ezv4wz"
|
||||
]
|
||||
"example": "[\"sg-p1ezv4wz\"]"
|
||||
},
|
||||
{
|
||||
"name": "LoginSettings",
|
||||
"type": "json",
|
||||
"type": "LoginSettings",
|
||||
"desc": "实例登录设置。目前只返回实例所关联的密钥。",
|
||||
"example": {
|
||||
"Password": "123qwe!@#QWE",
|
||||
"KeepImageLogin": "False",
|
||||
"KeyIds": [
|
||||
"skey-b4vakk62"
|
||||
]
|
||||
}
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "InstanceState",
|
||||
"type": "文本",
|
||||
"desc": "实例状态。取值范围: PENDING:表示创建中 LAUNCH_FAILED:表示创建失败 RUNNING:表示运行中 STOPPED:表示关机 STARTING:表示开机中 STOPPING:表示关机中 REBOOTING:表示重启中 SHUTDOWN:表示停止待销毁 TERMINATING:表示销毁中。",
|
||||
"example": "RUNNING"
|
||||
"type": "String",
|
||||
"desc": "PENDING:表示创建中\nLAUNCH_FAILED:表示创建失败\nRUNNING:表示运行中\nSTOPPED:表示关机\nSTARTING:表示开机中\nSTOPPING:表示关机中\nREBOOTING:表示重启中\nSHUTDOWN:表示停止待销毁\nTERMINATING:表示销毁中。",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "Tags",
|
||||
"type": "json",
|
||||
"type": "Array of Tag",
|
||||
"desc": "实例关联的标签列表。",
|
||||
"example": [
|
||||
{
|
||||
"Value": "test",
|
||||
"Key": "test"
|
||||
}
|
||||
]
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "StopChargingMode",
|
||||
"type": "文本",
|
||||
"desc": "实例的关机计费模式。 取值范围: KEEP_CHARGING:关机继续收费 STOP_CHARGING:关机停止收费NOT_APPLICABLE:实例处于非关机状态或者不适用关机停止计费的条件",
|
||||
"type": "String",
|
||||
"desc": "KEEP_CHARGING:关机继续收费\nSTOP_CHARGING:关机停止收费\nNOT_APPLICABLE:实例处于非关机状态或者不适用关机停止计费的条件",
|
||||
"example": "NOT_APPLICABLE"
|
||||
},
|
||||
{
|
||||
"name": "Uuid",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例全局唯一ID",
|
||||
"example": "e85f1388-0422-410d-8e50-bef540e78c18"
|
||||
"example": "68b510db-b4c1-4630-a62b-73d0c7c970f9"
|
||||
},
|
||||
{
|
||||
"name": "LatestOperation",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例的最新操作。例:StopInstances、ResetInstance。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": "ResetInstancesType"
|
||||
"example": "RenewInstances"
|
||||
},
|
||||
{
|
||||
"name": "LatestOperationState",
|
||||
"type": "文本",
|
||||
"desc": "实例的最新操作状态。取值范围: SUCCESS:表示操作成功 OPERATING:表示操作执行中 FAILED:表示操作失败 注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"type": "String",
|
||||
"desc": "SUCCESS:表示操作成功\nOPERATING:表示操作执行中\nFAILED:表示操作失败注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": "SUCCESS"
|
||||
},
|
||||
{
|
||||
"name": "LatestOperationRequestId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例最新操作的唯一请求 ID。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": "c7de1287-061d-4ace-8caf-6ad8e5a2f29a"
|
||||
"example": "3554eb5b-1cfa-471a-ae76-dc436c9d43e8"
|
||||
},
|
||||
{
|
||||
"name": "DisasterRecoverGroupId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "分散置放群组ID。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": ""
|
||||
"example": "null"
|
||||
},
|
||||
{
|
||||
"name": "IPv6Addresses",
|
||||
"type": "文本、多值",
|
||||
"type": "Array of String",
|
||||
"desc": "实例的IPv6地址。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": [
|
||||
"2001:0db8:86a3:08d3:1319:8a2e:0370:7344"
|
||||
]
|
||||
"example": "null"
|
||||
},
|
||||
{
|
||||
"name": "CamRoleName",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "CAM角色名。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": ""
|
||||
"example": "null"
|
||||
},
|
||||
{
|
||||
"name": "HpcClusterId",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "高性能计算集群ID。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": ""
|
||||
"example": "null"
|
||||
},
|
||||
{
|
||||
"name": "RdmaIpAddresses",
|
||||
"type": "文本、多值",
|
||||
"type": "Array of String",
|
||||
"desc": "高性能计算集群IP列表。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": []
|
||||
"example": "null"
|
||||
},
|
||||
{
|
||||
"name": "DedicatedClusterId",
|
||||
"type": "String",
|
||||
"desc": "实例所在的专用集群ID。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": "cluster-du3jken"
|
||||
},
|
||||
{
|
||||
"name": "IsolatedSource",
|
||||
"type": "文本",
|
||||
"desc": "实例隔离类型。取值范围: ARREAR:表示欠费隔离 EXPIRE:表示到期隔离 MANMADE:表示主动退还隔离 NOTISOLATED:表示未隔离 注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": "NOTISOLATED"
|
||||
"type": "String",
|
||||
"desc": "ARREAR:表示欠费隔离\nEXPIRE:表示到期隔离\nMANMADE:表示主动退还隔离\nNOTISOLATED:表示未隔离",
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "GPUInfo",
|
||||
"type": "json",
|
||||
"type": "GPUInfo",
|
||||
"desc": "GPU信息。如果是gpu类型子机,该值会返回GPU信息,如果是其他类型子机则不返回。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": null
|
||||
"example": ""
|
||||
},
|
||||
{
|
||||
"name": "LicenseType",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例的操作系统许可类型,默认为TencentCloud",
|
||||
"example": null
|
||||
"example": "TencentCloud"
|
||||
},
|
||||
{
|
||||
"name": "DisableApiTermination",
|
||||
"type": "Boolean",
|
||||
"desc": "实例销毁保护标志,表示是否允许通过api接口删除实例。取值范围: TRUE:表示开启实例保护,不允许通过api接口删除实例 FALSE:表示关闭实例保护,允许通过api接口删除实例 默认取值:FALSE。",
|
||||
"example": null
|
||||
"desc": "TRUE:表示开启实例保护,不允许通过api接口删除实例\nFALSE:表示关闭实例保护,允许通过api接口删除实例默认取值:FALSE。",
|
||||
"example": "false"
|
||||
},
|
||||
{
|
||||
"name": "DefaultLoginUser",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "默认登录用户。",
|
||||
"example": null
|
||||
"example": "root"
|
||||
},
|
||||
{
|
||||
"name": "DefaultLoginPort",
|
||||
"type": "整数",
|
||||
"type": "Integer",
|
||||
"desc": "默认登录端口。",
|
||||
"example": null
|
||||
"example": "22"
|
||||
},
|
||||
{
|
||||
"name": "LatestOperationErrorMsg",
|
||||
"type": "文本",
|
||||
"type": "String",
|
||||
"desc": "实例的最新操作错误信息。注意:此字段可能返回 null,表示取不到有效值。",
|
||||
"example": null
|
||||
"example": "None"
|
||||
}
|
||||
]
|
@@ -1,103 +1,138 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from flask_babel import lazy_gettext as _l
|
||||
|
||||
from api.lib.resp_format import CommonErrFormat
|
||||
|
||||
|
||||
class ErrFormat(CommonErrFormat):
|
||||
ci_type_config = "模型配置"
|
||||
ci_type_config = _l("CI Model") # 模型配置
|
||||
|
||||
invalid_relation_type = "无效的关系类型: {}"
|
||||
ci_type_not_found = "模型不存在!"
|
||||
argument_attributes_must_be_list = "参数 attributes 类型必须是列表"
|
||||
argument_file_not_found = "文件似乎并未上传"
|
||||
invalid_relation_type = _l("Invalid relation type: {}") # 无效的关系类型: {}
|
||||
ci_type_not_found = _l("CIType is not found") # 模型不存在!
|
||||
|
||||
attribute_not_found = "属性 {} 不存在!"
|
||||
attribute_is_unique_id = "该属性是模型的唯一标识,不能被删除!"
|
||||
attribute_is_ref_by_type = "该属性被模型 {} 引用, 不能删除!"
|
||||
attribute_value_type_cannot_change = "属性的值类型不允许修改!"
|
||||
attribute_list_value_cannot_change = "多值不被允许修改!"
|
||||
attribute_index_cannot_change = "修改索引 非管理员不被允许!"
|
||||
attribute_index_change_failed = "索引切换失败!"
|
||||
invalid_choice_values = "预定义值的类型不对!"
|
||||
attribute_name_duplicate = "重复的属性名 {}"
|
||||
add_attribute_failed = "创建属性 {} 失败!"
|
||||
update_attribute_failed = "修改属性 {} 失败!"
|
||||
cannot_edit_attribute = "您没有权限修改该属性!"
|
||||
cannot_delete_attribute = "目前只允许 属性创建人、管理员 删除属性!"
|
||||
attribute_name_cannot_be_builtin = "属性字段名不能是内置字段: id, _id, ci_id, type, _type, ci_type"
|
||||
attribute_choice_other_invalid = "预定义值: 其他模型请求参数不合法!"
|
||||
# 参数 attributes 类型必须是列表
|
||||
argument_attributes_must_be_list = _l("The type of parameter attributes must be a list")
|
||||
argument_file_not_found = _l("The file doesn't seem to be uploaded") # 文件似乎并未上传
|
||||
|
||||
ci_not_found = "CI {} 不存在"
|
||||
unique_constraint = "多属性联合唯一校验不通过: {}"
|
||||
unique_value_not_found = "模型的主键 {} 不存在!"
|
||||
unique_key_required = "主键字段 {} 缺失"
|
||||
ci_is_already_existed = "CI 已经存在!"
|
||||
relation_constraint = "关系约束: {}, 校验失败 "
|
||||
m2m_relation_constraint = "多对多关系 限制: 模型 {} <-> {} 已经存在多对多关系!"
|
||||
relation_not_found = "CI关系: {} 不存在"
|
||||
ci_search_Parentheses_invalid = "搜索表达式里小括号前不支持: 或、非"
|
||||
attribute_not_found = _l("Attribute {} does not exist!") # 属性 {} 不存在!
|
||||
attribute_is_unique_id = _l(
|
||||
"This attribute is the unique identifier of the model and cannot be deleted!") # 该属性是模型的唯一标识,不能被删除!
|
||||
attribute_is_ref_by_type = _l(
|
||||
"This attribute is referenced by model {} and cannot be deleted!") # 该属性被模型 {} 引用, 不能删除!
|
||||
attribute_value_type_cannot_change = _l(
|
||||
"The value type of the attribute is not allowed to be modified!") # 属性的值类型不允许修改!
|
||||
attribute_list_value_cannot_change = _l("Multiple values are not allowed to be modified!") # 多值不被允许修改!
|
||||
# 修改索引 非管理员不被允许!
|
||||
attribute_index_cannot_change = _l("Modifying the index is not allowed for non-administrators!")
|
||||
attribute_index_change_failed = _l("Index switching failed!") # 索引切换失败!
|
||||
invalid_choice_values = _l("The predefined value is of the wrong type!") # 预定义值的类型不对!
|
||||
attribute_name_duplicate = _l("Duplicate attribute name {}") # 重复的属性名 {}
|
||||
add_attribute_failed = _l("Failed to create attribute {}!") # 创建属性 {} 失败!
|
||||
update_attribute_failed = _l("Modify attribute {} failed!") # 修改属性 {} 失败!
|
||||
cannot_edit_attribute = _l("You do not have permission to modify this attribute!") # 您没有权限修改该属性!
|
||||
cannot_delete_attribute = _l(
|
||||
"Only creators and administrators are allowed to delete attributes!") # 目前只允许 属性创建人、管理员 删除属性!
|
||||
# 属性字段名不能是内置字段: id, _id, ci_id, type, _type, ci_type
|
||||
attribute_name_cannot_be_builtin = _l(
|
||||
"Attribute field names cannot be built-in fields: id, _id, ci_id, type, _type, ci_type")
|
||||
attribute_choice_other_invalid = _l(
|
||||
"Predefined value: Other model request parameters are illegal!") # 预定义值: 其他模型请求参数不合法!
|
||||
|
||||
ci_type_not_found2 = "模型 {} 不存在"
|
||||
ci_type_is_already_existed = "模型 {} 已经存在"
|
||||
unique_key_not_define = "主键未定义或者已被删除"
|
||||
only_owner_can_delete = "只有创建人才能删除它!"
|
||||
ci_exists_and_cannot_delete_type = "因为CI已经存在,不能删除模型"
|
||||
ci_relation_view_exists_and_cannot_delete_type = "因为关系视图 {} 引用了该模型,不能删除模型"
|
||||
ci_type_group_not_found = "模型分组 {} 不存在"
|
||||
ci_type_group_exists = "模型分组 {} 已经存在"
|
||||
ci_type_relation_not_found = "模型关系 {} 不存在"
|
||||
ci_type_attribute_group_duplicate = "属性分组 {} 已存在"
|
||||
ci_type_attribute_group_not_found = "属性分组 {} 不存在"
|
||||
ci_type_group_attribute_not_found = "属性组<{0}> - 属性<{1}> 不存在"
|
||||
unique_constraint_duplicate = "唯一约束已经存在!"
|
||||
unique_constraint_invalid = "唯一约束的属性不能是 JSON 和 多值"
|
||||
ci_type_trigger_duplicate = "重复的触发器"
|
||||
ci_type_trigger_not_found = "触发器 {} 不存在"
|
||||
ci_not_found = _l("CI {} does not exist") # CI {} 不存在
|
||||
unique_constraint = _l("Multiple attribute joint unique verification failed: {}") # 多属性联合唯一校验不通过: {}
|
||||
unique_value_not_found = _l("The model's primary key {} does not exist!") # 模型的主键 {} 不存在!
|
||||
unique_key_required = _l("Primary key {} is missing") # 主键字段 {} 缺失
|
||||
ci_is_already_existed = _l("CI already exists!") # CI 已经存在!
|
||||
relation_constraint = _l("Relationship constraint: {}, verification failed") # 关系约束: {}, 校验失败
|
||||
# 多对多关系 限制: 模型 {} <-> {} 已经存在多对多关系!
|
||||
m2m_relation_constraint = _l(
|
||||
"Many-to-many relationship constraint: Model {} <-> {} already has a many-to-many relationship!")
|
||||
|
||||
record_not_found = "操作记录 {} 不存在"
|
||||
cannot_delete_unique = "不能删除唯一标识"
|
||||
cannot_delete_default_order_attr = "不能删除默认排序的属性"
|
||||
relation_not_found = _l("CI relationship: {} does not exist") # CI关系: {} 不存在
|
||||
|
||||
preference_relation_view_node_required = "没有选择节点"
|
||||
preference_search_option_not_found = "该搜索选项不存在!"
|
||||
preference_search_option_exists = "该搜索选项命名重复!"
|
||||
# 搜索表达式里小括号前不支持: 或、非
|
||||
ci_search_Parentheses_invalid = _l("In search expressions, not supported before parentheses: or, not")
|
||||
|
||||
relation_type_exists = "关系类型 {} 已经存在"
|
||||
relation_type_not_found = "关系类型 {} 不存在"
|
||||
ci_type_not_found2 = _l("Model {} does not exist") # 模型 {} 不存在
|
||||
ci_type_is_already_existed = _l("Model {} already exists") # 模型 {} 已经存在
|
||||
unique_key_not_define = _l("The primary key is undefined or has been deleted") # 主键未定义或者已被删除
|
||||
only_owner_can_delete = _l("Only the creator can delete it!") # 只有创建人才能删除它!
|
||||
ci_exists_and_cannot_delete_type = _l(
|
||||
"The model cannot be deleted because the CI already exists") # 因为CI已经存在,不能删除模型
|
||||
|
||||
attribute_value_invalid = "无效的属性值: {}"
|
||||
attribute_value_invalid2 = "{} 无效的值: {}"
|
||||
not_in_choice_values = "{} 不在预定义值里"
|
||||
attribute_value_unique_required = "属性 {} 的值必须是唯一的, 当前值 {} 已存在"
|
||||
attribute_value_required = "属性 {} 值必须存在"
|
||||
attribute_value_unknown_error = "新增或者修改属性值未知错误: {}"
|
||||
# 因为关系视图 {} 引用了该模型,不能删除模型
|
||||
ci_relation_view_exists_and_cannot_delete_type = _l(
|
||||
"The model cannot be deleted because the model is referenced by the relational view {}")
|
||||
ci_type_group_not_found = _l("Model group {} does not exist") # 模型分组 {} 不存在
|
||||
ci_type_group_exists = _l("Model group {} already exists") # 模型分组 {} 已经存在
|
||||
ci_type_relation_not_found = _l("Model relationship {} does not exist") # 模型关系 {} 不存在
|
||||
ci_type_attribute_group_duplicate = _l("Attribute group {} already exists") # 属性分组 {} 已存在
|
||||
ci_type_attribute_group_not_found = _l("Attribute group {} does not exist") # 属性分组 {} 不存在
|
||||
# 属性组<{0}> - 属性<{1}> 不存在
|
||||
ci_type_group_attribute_not_found = _l("Attribute group <{0}> - attribute <{1}> does not exist")
|
||||
unique_constraint_duplicate = _l("The unique constraint already exists!") # 唯一约束已经存在!
|
||||
# 唯一约束的属性不能是 JSON 和 多值
|
||||
unique_constraint_invalid = _l("Uniquely constrained attributes cannot be JSON and multi-valued")
|
||||
ci_type_trigger_duplicate = _l("Duplicated trigger") # 重复的触发器
|
||||
ci_type_trigger_not_found = _l("Trigger {} does not exist") # 触发器 {} 不存在
|
||||
|
||||
custom_name_duplicate = "订制名重复"
|
||||
record_not_found = _l("Operation record {} does not exist") # 操作记录 {} 不存在
|
||||
cannot_delete_unique = _l("Unique identifier cannot be deleted") # 不能删除唯一标识
|
||||
cannot_delete_default_order_attr = _l("Cannot delete default sorted attributes") # 不能删除默认排序的属性
|
||||
|
||||
limit_ci_type = "模型数超过限制: {}"
|
||||
limit_ci = "CI数超过限制: {}"
|
||||
preference_relation_view_node_required = _l("No node selected") # 没有选择节点
|
||||
preference_search_option_not_found = _l("This search option does not exist!") # 该搜索选项不存在!
|
||||
preference_search_option_exists = _l("This search option has a duplicate name!") # 该搜索选项命名重复!
|
||||
|
||||
adr_duplicate = "自动发现规则: {} 已经存在!"
|
||||
adr_not_found = "自动发现规则: {} 不存在!"
|
||||
adr_referenced = "该自动发现规则被模型引用, 不能删除!"
|
||||
ad_duplicate = "自动发现规则的应用不能重复定义!"
|
||||
ad_not_found = "您要修改的自动发现: {} 不存在!"
|
||||
ad_not_unique_key = "属性字段没有包括唯一标识: {}"
|
||||
adc_not_found = "自动发现的实例不存在!"
|
||||
adt_not_found = "模型并未关联该自动发现!"
|
||||
adt_secret_no_permission = "只有创建人才能修改Secret!"
|
||||
cannot_delete_adt = "该规则已经有自动发现的实例, 不能被删除!"
|
||||
adr_default_ref_once = "该默认的自动发现规则 已经被模型 {} 引用!"
|
||||
adr_unique_key_required = "unique_key方法必须返回非空字符串!"
|
||||
adr_plugin_attributes_list_required = "attributes方法必须返回的是list"
|
||||
adr_plugin_attributes_list_no_empty = "attributes方法返回的list不能为空!"
|
||||
adt_target_all_no_permission = "只有管理员才可以定义执行机器为: 所有节点!"
|
||||
adt_target_expr_no_permission = "执行机器权限检查不通过: {}"
|
||||
relation_type_exists = _l("Relationship type {} already exists") # 关系类型 {} 已经存在
|
||||
relation_type_not_found = _l("Relationship type {} does not exist") # 关系类型 {} 不存在
|
||||
|
||||
ci_filter_name_cannot_be_empty = "CI过滤授权 必须命名!"
|
||||
ci_filter_perm_cannot_or_query = "CI过滤授权 暂时不支持 或 查询"
|
||||
ci_filter_perm_attr_no_permission = "您没有属性 {} 的操作权限!"
|
||||
ci_filter_perm_ci_no_permission = "您没有该CI的操作权限!"
|
||||
attribute_value_invalid = _l("Invalid attribute value: {}") # 无效的属性值: {}
|
||||
attribute_value_invalid2 = _l("{} Invalid value: {}") # {} 无效的值: {}
|
||||
not_in_choice_values = _l("{} is not in the predefined values") # {} 不在预定义值里
|
||||
# 属性 {} 的值必须是唯一的, 当前值 {} 已存在
|
||||
attribute_value_unique_required = _l("The value of attribute {} must be unique, {} already exists")
|
||||
attribute_value_required = _l("Attribute {} value must exist") # 属性 {} 值必须存在
|
||||
|
||||
password_save_failed = "保存密码失败: {}"
|
||||
password_load_failed = "获取密码失败: {}"
|
||||
# 新增或者修改属性值未知错误: {}
|
||||
attribute_value_unknown_error = _l("Unknown error when adding or modifying attribute value: {}")
|
||||
|
||||
custom_name_duplicate = _l("Duplicate custom name") # 订制名重复
|
||||
|
||||
limit_ci_type = _l("Number of models exceeds limit: {}") # 模型数超过限制: {}
|
||||
limit_ci = _l("The number of CIs exceeds the limit: {}") # CI数超过限制: {}
|
||||
|
||||
adr_duplicate = _l("Auto-discovery rule: {} already exists!") # 自动发现规则: {} 已经存在!
|
||||
adr_not_found = _l("Auto-discovery rule: {} does not exist!") # 自动发现规则: {} 不存在!
|
||||
# 该自动发现规则被模型引用, 不能删除!
|
||||
adr_referenced = _l("This auto-discovery rule is referenced by the model and cannot be deleted!")
|
||||
# 自动发现规则的应用不能重复定义!
|
||||
ad_duplicate = _l("The application of auto-discovery rules cannot be defined repeatedly!")
|
||||
ad_not_found = _l("The auto-discovery you want to modify: {} does not exist!") # 您要修改的自动发现: {} 不存在!
|
||||
ad_not_unique_key = _l("Attribute does not include unique identifier: {}") # 属性字段没有包括唯一标识: {}
|
||||
adc_not_found = _l("The auto-discovery instance does not exist!") # 自动发现的实例不存在!
|
||||
adt_not_found = _l("The model is not associated with this auto-discovery!") # 模型并未关联该自动发现!
|
||||
adt_secret_no_permission = _l("Only the creator can modify the Secret!") # 只有创建人才能修改Secret!
|
||||
# 该规则已经有自动发现的实例, 不能被删除!
|
||||
cannot_delete_adt = _l("This rule already has auto-discovery instances and cannot be deleted!")
|
||||
# 该默认的自动发现规则 已经被模型 {} 引用!
|
||||
adr_default_ref_once = _l("The default auto-discovery rule is already referenced by model {}!")
|
||||
# unique_key方法必须返回非空字符串!
|
||||
adr_unique_key_required = _l("The unique_key method must return a non-empty string!")
|
||||
adr_plugin_attributes_list_required = _l("The attributes method must return a list") # attributes方法必须返回的是list
|
||||
# attributes方法返回的list不能为空!
|
||||
adr_plugin_attributes_list_no_empty = _l("The list returned by the attributes method cannot be empty!")
|
||||
# 只有管理员才可以定义执行机器为: 所有节点!
|
||||
adt_target_all_no_permission = _l("Only administrators can define execution targets as: all nodes!")
|
||||
adt_target_expr_no_permission = _l("Execute targets permission check failed: {}") # 执行机器权限检查不通过: {}
|
||||
|
||||
ci_filter_name_cannot_be_empty = _l("CI filter authorization must be named!") # CI过滤授权 必须命名!
|
||||
ci_filter_perm_cannot_or_query = _l(
|
||||
"CI filter authorization is currently not supported or query") # CI过滤授权 暂时不支持 或 查询
|
||||
# 您没有属性 {} 的操作权限!
|
||||
ci_filter_perm_attr_no_permission = _l("You do not have permission to operate attribute {}!")
|
||||
ci_filter_perm_ci_no_permission = _l("You do not have permission to operate this CI!") # 您没有该CI的操作权限!
|
||||
|
||||
password_save_failed = _l("Failed to save password: {}") # 保存密码失败: {}
|
||||
password_load_failed = _l("Failed to get password: {}") # 获取密码失败: {}
|
||||
|
@@ -94,6 +94,11 @@ class AttributeValueManager(object):
|
||||
@staticmethod
|
||||
def _check_is_choice(attr, value_type, value):
|
||||
choice_values = AttributeManager.get_choice_values(attr.id, value_type, attr.choice_web_hook, attr.choice_other)
|
||||
if value_type == ValueTypeEnum.FLOAT:
|
||||
if float(value) not in list(map(float, [i[0] for i in choice_values])):
|
||||
return abort(400, ErrFormat.not_in_choice_values.format(value))
|
||||
|
||||
else:
|
||||
if str(value) not in list(map(str, [i[0] for i in choice_values])):
|
||||
return abort(400, ErrFormat.not_in_choice_values.format(value))
|
||||
|
||||
|
@@ -24,7 +24,15 @@ def get_all_department_list(to_dict=True):
|
||||
*criterion
|
||||
).order_by(Department.department_id.asc())
|
||||
results = query.all()
|
||||
return [r.to_dict() for r in results] if to_dict else results
|
||||
if to_dict:
|
||||
datas = []
|
||||
for r in results:
|
||||
d = r.to_dict()
|
||||
if r.department_id == 0:
|
||||
d['department_name'] = ErrFormat.company_wide
|
||||
datas.append(d)
|
||||
return datas
|
||||
return results
|
||||
|
||||
|
||||
def get_all_employee_list(block=0, to_dict=True):
|
||||
@@ -101,6 +109,7 @@ class DepartmentTree(object):
|
||||
employees = self.get_employees_by_d_id(department_id)
|
||||
|
||||
top_d['employees'] = employees
|
||||
top_d['department_name'] = ErrFormat.company_wide
|
||||
if len(sub_deps) == 0:
|
||||
top_d[sub_departments_column_name] = []
|
||||
d_list.append(top_d)
|
||||
@@ -246,7 +255,7 @@ class DepartmentCRUD(object):
|
||||
return abort(400, ErrFormat.acl_update_role_failed.format(str(e)))
|
||||
|
||||
try:
|
||||
existed.update(**kwargs)
|
||||
return existed.update(**kwargs)
|
||||
except Exception as e:
|
||||
return abort(400, str(e))
|
||||
|
||||
@@ -313,6 +322,7 @@ class DepartmentCRUD(object):
|
||||
tree_list = []
|
||||
|
||||
for top_d in top_deps:
|
||||
top_d['department_name'] = ErrFormat.company_wide
|
||||
tree = Tree()
|
||||
identifier_root = top_d['department_id']
|
||||
tree.create_node(
|
||||
@@ -383,6 +393,9 @@ class DepartmentCRUD(object):
|
||||
|
||||
d['employee_count'] = len(list(filter(lambda e: e['department_id'] in d_ids, all_employee_list)))
|
||||
|
||||
if int(department_parent_id) == -1:
|
||||
d['department_name'] = ErrFormat.company_wide
|
||||
|
||||
return all_departments, department_id_list
|
||||
|
||||
@staticmethod
|
||||
|
@@ -296,6 +296,8 @@ class EmployeeCRUD(object):
|
||||
for r in pagination.items:
|
||||
d = r.Employee.to_dict()
|
||||
d['department_name'] = r.Department.department_name if r.Department else ''
|
||||
if r.Employee.department_id == 0:
|
||||
d['department_name'] = ErrFormat.company_wide
|
||||
employees.append(d)
|
||||
|
||||
return {
|
||||
|
@@ -1,77 +1,82 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from flask_babel import lazy_gettext as _l
|
||||
|
||||
from api.lib.resp_format import CommonErrFormat
|
||||
|
||||
|
||||
class ErrFormat(CommonErrFormat):
|
||||
company_info_is_already_existed = "公司信息已存在!无法创建"
|
||||
company_info_is_already_existed = _l("Company info already existed") # 公司信息已存在!无法创建
|
||||
|
||||
no_file_part = "没有文件部分"
|
||||
file_is_required = "文件是必须的"
|
||||
file_not_found = "文件不存在"
|
||||
file_type_not_allowed = "文件类型不允许"
|
||||
upload_failed = "上传失败: {}"
|
||||
no_file_part = _l("No file part") # 没有文件部分
|
||||
file_is_required = _l("File is required") # 文件是必须的
|
||||
file_not_found = _l("File not found") # 文件不存在
|
||||
file_type_not_allowed = _l("File type not allowed") # 文件类型不允许
|
||||
upload_failed = _l("Upload failed: {}") # 上传失败: {}
|
||||
|
||||
direct_supervisor_is_not_self = "直属上级不能是自己"
|
||||
parent_department_is_not_self = "上级部门不能是自己"
|
||||
employee_list_is_empty = "员工列表为空"
|
||||
direct_supervisor_is_not_self = _l("Direct supervisor is not self") # 直属上级不能是自己
|
||||
parent_department_is_not_self = _l("Parent department is not self") # 上级部门不能是自己
|
||||
employee_list_is_empty = _l("Employee list is empty") # 员工列表为空
|
||||
|
||||
column_name_not_support = "不支持的列名"
|
||||
password_is_required = "密码不能为空"
|
||||
employee_acl_rid_is_zero = "员工ACL角色ID不能为0"
|
||||
column_name_not_support = _l("Column name not support") # 不支持的列名
|
||||
password_is_required = _l("Password is required") # 密码是必须的
|
||||
employee_acl_rid_is_zero = _l("Employee acl rid is zero") # 员工ACL角色ID不能为0
|
||||
|
||||
generate_excel_failed = "生成excel失败: {}"
|
||||
rename_columns_failed = "字段转换为中文失败: {}"
|
||||
cannot_block_this_employee_is_other_direct_supervisor = "该员工是其他员工的直属上级, 不能禁用"
|
||||
cannot_block_this_employee_is_department_manager = "该员工是部门负责人, 不能禁用"
|
||||
employee_id_not_found = "员工ID [{}] 不存在"
|
||||
value_is_required = "值是必须的"
|
||||
email_already_exists = "邮箱 [{}] 已存在"
|
||||
query_column_none_keep_value_empty = "查询 {} 空值时请保持value为空"
|
||||
not_support_operator = "不支持的操作符: {}"
|
||||
not_support_relation = "不支持的关系: {}"
|
||||
conditions_field_missing = "conditions内元素字段缺失,请检查!"
|
||||
datetime_format_error = "{} 格式错误,应该为:%Y-%m-%d %H:%M:%S"
|
||||
department_level_relation_error = "部门层级关系不正确"
|
||||
delete_reserved_department_name = "保留部门,无法删除!"
|
||||
department_id_is_required = "部门ID是必须的"
|
||||
department_list_is_required = "部门列表是必须的"
|
||||
cannot_to_be_parent_department = "{} 不能设置为上级部门"
|
||||
department_id_not_found = "部门ID [{}] 不存在"
|
||||
parent_department_id_must_more_than_zero = "上级部门ID必须大于0"
|
||||
department_name_already_exists = "部门名称 [{}] 已存在"
|
||||
new_department_is_none = "新部门是空的"
|
||||
generate_excel_failed = _l("Generate excel failed: {}") # 生成excel失败: {}
|
||||
rename_columns_failed = _l("Rename columns failed: {}") # 重命名字段失败: {}
|
||||
cannot_block_this_employee_is_other_direct_supervisor = _l(
|
||||
"Cannot block this employee is other direct supervisor") # 该员工是其他员工的直属上级, 不能禁用
|
||||
cannot_block_this_employee_is_department_manager = _l(
|
||||
"Cannot block this employee is department manager") # 该员工是部门负责人, 不能禁用
|
||||
employee_id_not_found = _l("Employee id [{}] not found") # 员工ID [{}] 不存在
|
||||
value_is_required = _l("Value is required") # 值是必须的
|
||||
email_already_exists = _l("Email already exists") # 邮箱已存在
|
||||
query_column_none_keep_value_empty = _l("Query {} none keep value empty") # 查询 {} 空值时请保持value为空"
|
||||
not_support_operator = _l("Not support operator: {}") # 不支持的操作符: {}
|
||||
not_support_relation = _l("Not support relation: {}") # 不支持的关系: {}
|
||||
conditions_field_missing = _l("Conditions field missing") # conditions内元素字段缺失,请检查!
|
||||
datetime_format_error = _l("Datetime format error: {}") # {} 格式错误,应该为:%Y-%m-%d %H:%M:%S
|
||||
department_level_relation_error = _l("Department level relation error") # 部门层级关系不正确
|
||||
delete_reserved_department_name = _l("Delete reserved department name") # 保留部门,无法删除!
|
||||
department_id_is_required = _l("Department id is required") # 部门ID是必须的
|
||||
department_list_is_required = _l("Department list is required") # 部门列表是必须的
|
||||
cannot_to_be_parent_department = _l("{} Cannot to be parent department") # 不能设置为上级部门
|
||||
department_id_not_found = _l("Department id [{}] not found") # 部门ID [{}] 不存在
|
||||
parent_department_id_must_more_than_zero = _l("Parent department id must more than zero") # 上级部门ID必须大于0
|
||||
department_name_already_exists = _l("Department name [{}] already exists") # 部门名称 [{}] 已存在
|
||||
new_department_is_none = _l("New department is none") # 新部门是空的
|
||||
|
||||
acl_edit_user_failed = "ACL 修改用户失败: {}"
|
||||
acl_uid_not_found = "ACL 用户UID [{}] 不存在"
|
||||
acl_add_user_failed = "ACL 添加用户失败: {}"
|
||||
acl_add_role_failed = "ACL 添加角色失败: {}"
|
||||
acl_update_role_failed = "ACL 更新角色失败: {}"
|
||||
acl_get_all_users_failed = "ACL 获取所有用户失败: {}"
|
||||
acl_remove_user_from_role_failed = "ACL 从角色中移除用户失败: {}"
|
||||
acl_add_user_to_role_failed = "ACL 添加用户到角色失败: {}"
|
||||
acl_import_user_failed = "ACL 导入用户[{}]失败: {}"
|
||||
acl_edit_user_failed = _l("ACL edit user failed: {}") # ACL 修改用户失败: {}
|
||||
acl_uid_not_found = _l("ACL uid not found: {}") # ACL 用户UID [{}] 不存在
|
||||
acl_add_user_failed = _l("ACL add user failed: {}") # ACL 添加用户失败: {}
|
||||
acl_add_role_failed = _l("ACL add role failed: {}") # ACL 添加角色失败: {}
|
||||
acl_update_role_failed = _l("ACL update role failed: {}") # ACL 更新角色失败: {}
|
||||
acl_get_all_users_failed = _l("ACL get all users failed: {}") # ACL 获取所有用户失败: {}
|
||||
acl_remove_user_from_role_failed = _l("ACL remove user from role failed: {}") # ACL 从角色中移除用户失败: {}
|
||||
acl_add_user_to_role_failed = _l("ACL add user to role failed: {}") # ACL 添加用户到角色失败: {}
|
||||
acl_import_user_failed = _l("ACL import user failed: {}") # ACL 导入用户失败: {}
|
||||
|
||||
nickname_is_required = "用户名不能为空"
|
||||
username_is_required = "username不能为空"
|
||||
email_is_required = "邮箱不能为空"
|
||||
email_format_error = "邮箱格式错误"
|
||||
email_send_timeout = "邮件发送超时"
|
||||
nickname_is_required = _l("Nickname is required") # 昵称不能为空
|
||||
username_is_required = _l("Username is required") # 用户名不能为空
|
||||
email_is_required = _l("Email is required") # 邮箱不能为空
|
||||
email_format_error = _l("Email format error") # 邮箱格式错误
|
||||
email_send_timeout = _l("Email send timeout") # 邮件发送超时
|
||||
|
||||
common_data_not_found = "ID {} 找不到记录"
|
||||
common_data_already_existed = "{} 已存在"
|
||||
notice_platform_existed = "{} 已存在"
|
||||
notice_not_existed = "{} 配置项不存在"
|
||||
notice_please_config_messenger_first = "请先配置 messenger"
|
||||
notice_bind_err_with_empty_mobile = "绑定失败,手机号为空"
|
||||
notice_bind_failed = "绑定失败: {}"
|
||||
notice_bind_success = "绑定成功"
|
||||
notice_remove_bind_success = "解绑成功"
|
||||
common_data_not_found = _l("Common data not found {} ") # ID {} 找不到记录
|
||||
common_data_already_existed = _l("Common data {} already existed") # {} 已存在
|
||||
notice_platform_existed = _l("Notice platform {} existed") # {} 已存在
|
||||
notice_not_existed = _l("Notice {} not existed") # {} 配置项不存在
|
||||
notice_please_config_messenger_first = _l("Notice please config messenger first") # 请先配置messenger URL
|
||||
notice_bind_err_with_empty_mobile = _l("Notice bind err with empty mobile") # 绑定错误,手机号为空
|
||||
notice_bind_failed = _l("Notice bind failed: {}") # 绑定失败: {}
|
||||
notice_bind_success = _l("Notice bind success") # 绑定成功
|
||||
notice_remove_bind_success = _l("Notice remove bind success") # 解绑成功
|
||||
|
||||
not_support_test = "不支持的测试类型: {}"
|
||||
not_support_auth_type = "不支持的认证类型: {}"
|
||||
ldap_server_connect_timeout = "LDAP服务器连接超时"
|
||||
ldap_server_connect_not_available = "LDAP服务器连接不可用"
|
||||
ldap_test_unknown_error = "LDAP测试未知错误: {}"
|
||||
common_data_not_support_auth_type = "通用数据不支持auth类型: {}"
|
||||
ldap_test_username_required = "LDAP测试用户名必填"
|
||||
not_support_test = _l("Not support test type: {}") # 不支持的测试类型: {}
|
||||
not_support_auth_type = _l("Not support auth type: {}") # 不支持的认证类型: {}
|
||||
ldap_server_connect_timeout = _l("LDAP server connect timeout") # LDAP服务器连接超时
|
||||
ldap_server_connect_not_available = _l("LDAP server connect not available") # LDAP服务器连接不可用
|
||||
ldap_test_unknown_error = _l("LDAP test unknown error: {}") # LDAP测试未知错误: {}
|
||||
common_data_not_support_auth_type = _l("Common data not support auth type: {}") # 通用数据不支持auth类型: {}
|
||||
ldap_test_username_required = _l("LDAP test username required") # LDAP测试用户名必填
|
||||
|
||||
company_wide = _l("Company wide") # 全公司
|
||||
|
@@ -1,46 +1,50 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from flask_babel import lazy_gettext as _l
|
||||
|
||||
from api.lib.resp_format import CommonErrFormat
|
||||
|
||||
|
||||
class ErrFormat(CommonErrFormat):
|
||||
login_succeed = "登录成功"
|
||||
ldap_connection_failed = "连接LDAP服务失败"
|
||||
invalid_password = "密码验证失败"
|
||||
auth_only_with_app_token_failed = "应用 Token验证失败"
|
||||
session_invalid = "您不是应用管理员 或者 session失效(尝试一下退出重新登录)"
|
||||
login_succeed = _l("login successful") # 登录成功
|
||||
ldap_connection_failed = _l("Failed to connect to LDAP service") # 连接LDAP服务失败
|
||||
invalid_password = _l("Password verification failed") # 密码验证失败
|
||||
auth_only_with_app_token_failed = _l("Application Token verification failed") # 应用 Token验证失败
|
||||
# 您不是应用管理员 或者 session失效(尝试一下退出重新登录)
|
||||
session_invalid = _l(
|
||||
"You are not the application administrator or the session has expired (try logging out and logging in again)")
|
||||
|
||||
resource_type_not_found = "资源类型 {} 不存在!"
|
||||
resource_type_exists = "资源类型 {} 已经存在!"
|
||||
resource_type_cannot_delete = "因为该类型下有资源的存在, 不能删除!"
|
||||
resource_type_not_found = _l("Resource type {} does not exist!") # 资源类型 {} 不存在!
|
||||
resource_type_exists = _l("Resource type {} already exists!") # 资源类型 {} 已经存在!
|
||||
# 因为该类型下有资源的存在, 不能删除!
|
||||
resource_type_cannot_delete = _l("Because there are resources under this type, they cannot be deleted!")
|
||||
|
||||
user_not_found = "用户 {} 不存在!"
|
||||
user_exists = "用户 {} 已经存在!"
|
||||
role_not_found = "角色 {} 不存在!"
|
||||
role_exists = "角色 {} 已经存在!"
|
||||
global_role_not_found = "全局角色 {} 不存在!"
|
||||
global_role_exists = "全局角色 {} 已经存在!"
|
||||
user_not_found = _l("User {} does not exist!") # 用户 {} 不存在!
|
||||
user_exists = _l("User {} already exists!") # 用户 {} 已经存在!
|
||||
role_not_found = _l("Role {} does not exist!") # 角色 {} 不存在!
|
||||
role_exists = _l("Role {} already exists!") # 角色 {} 已经存在!
|
||||
global_role_not_found = _l("Global role {} does not exist!") # 全局角色 {} 不存在!
|
||||
global_role_exists = _l("Global role {} already exists!") # 全局角色 {} 已经存在!
|
||||
|
||||
resource_no_permission = "您没有资源: {} 的 {} 权限"
|
||||
admin_required = "需要管理员权限"
|
||||
role_required = "需要角色: {}"
|
||||
user_role_delete_invalid = "删除用户角色, 请在 用户管理 页面操作!"
|
||||
resource_no_permission = _l("You do not have {} permission on resource: {}") # 您没有资源: {} 的 {} 权限
|
||||
admin_required = _l("Requires administrator permissions") # 需要管理员权限
|
||||
role_required = _l("Requires role: {}") # 需要角色: {}
|
||||
# 删除用户角色, 请在 用户管理 页面操作!
|
||||
user_role_delete_invalid = _l("To delete a user role, please operate on the User Management page!")
|
||||
|
||||
app_is_ready_existed = "应用 {} 已经存在"
|
||||
app_not_found = "应用 {} 不存在!"
|
||||
app_secret_invalid = "应用的Secret无效"
|
||||
app_is_ready_existed = _l("Application {} already exists") # 应用 {} 已经存在
|
||||
app_not_found = _l("Application {} does not exist!") # 应用 {} 不存在!
|
||||
app_secret_invalid = _l("The Secret is invalid") # 应用的Secret无效
|
||||
|
||||
resource_not_found = "资源 {} 不存在!"
|
||||
resource_exists = "资源 {} 已经存在!"
|
||||
resource_not_found = _l("Resource {} does not exist!") # 资源 {} 不存在!
|
||||
resource_exists = _l("Resource {} already exists!") # 资源 {} 已经存在!
|
||||
|
||||
resource_group_not_found = "资源组 {} 不存在!"
|
||||
resource_group_exists = "资源组 {} 已经存在!"
|
||||
resource_group_not_found = _l("Resource group {} does not exist!") # 资源组 {} 不存在!
|
||||
resource_group_exists = _l("Resource group {} already exists!") # 资源组 {} 已经存在!
|
||||
|
||||
inheritance_dead_loop = "继承检测到了死循环"
|
||||
role_relation_not_found = "角色关系 {} 不存在!"
|
||||
inheritance_dead_loop = _l("Inheritance detected infinite loop") # 继承检测到了死循环
|
||||
role_relation_not_found = _l("Role relationship {} does not exist!") # 角色关系 {} 不存在!
|
||||
|
||||
trigger_not_found = "触发器 {} 不存在!"
|
||||
trigger_exists = "触发器 {} 已经存在!"
|
||||
trigger_disabled = "触发器 {} 已经被禁用!"
|
||||
|
||||
invalid_password = "密码不正确!"
|
||||
trigger_not_found = _l("Trigger {} does not exist!") # 触发器 {} 不存在!
|
||||
trigger_exists = _l("Trigger {} already exists!") # 触发器 {} 已经存在!
|
||||
trigger_disabled = _l("Trigger {} has been disabled!") # Trigger {} has been disabled!
|
||||
|
@@ -1,29 +1,34 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from flask_babel import lazy_gettext as _l
|
||||
|
||||
|
||||
class CommonErrFormat(object):
|
||||
unauthorized = "未认证"
|
||||
unknown_error = "未知错误"
|
||||
unauthorized = _l("unauthorized") # 未认证
|
||||
unknown_error = _l("unknown error") # 未知错误
|
||||
|
||||
invalid_request = "不合法的请求"
|
||||
invalid_operation = "无效的操作"
|
||||
invalid_request = _l("Illegal request") # 不合法的请求
|
||||
invalid_operation = _l("Invalid operation") # 无效的操作
|
||||
|
||||
not_found = "不存在"
|
||||
not_found = _l("does not exist") # 不存在
|
||||
|
||||
circular_dependency_error = "存在循环依赖!"
|
||||
circular_dependency_error = _l("There is a circular dependency!") # 存在循环依赖!
|
||||
|
||||
unknown_search_error = "未知搜索错误"
|
||||
unknown_search_error = _l("Unknown search error") # 未知搜索错误
|
||||
|
||||
invalid_json = "json格式似乎不正确了, 请仔细确认一下!"
|
||||
# json格式似乎不正确了, 请仔细确认一下!
|
||||
invalid_json = _l("The json format seems to be incorrect, please confirm carefully!")
|
||||
|
||||
datetime_argument_invalid = "参数 {} 格式不正确, 格式必须是: yyyy-mm-dd HH:MM:SS"
|
||||
# 参数 {} 格式不正确, 格式必须是: yyyy-mm-dd HH:MM:SS
|
||||
datetime_argument_invalid = _l("The format of parameter {} is incorrect, the format must be: yyyy-mm-dd HH:MM:SS")
|
||||
|
||||
argument_value_required = "参数 {} 的值不能为空!"
|
||||
argument_required = "请求缺少参数 {}"
|
||||
argument_invalid = "参数 {} 的值无效"
|
||||
argument_str_length_limit = "参数 {} 的长度必须 <= {}"
|
||||
argument_value_required = _l("The value of parameter {} cannot be empty!") # 参数 {} 的值不能为空!
|
||||
argument_required = _l("The request is missing parameters {}") # 请求缺少参数 {}
|
||||
argument_invalid = _l("Invalid value for parameter {}") # 参数 {} 的值无效
|
||||
argument_str_length_limit = _l("The length of parameter {} must be <= {}") # 参数 {} 的长度必须 <= {}
|
||||
|
||||
role_required = "角色 {} 才能操作!"
|
||||
user_not_found = "用户 {} 不存在"
|
||||
no_permission = "您没有资源: {} 的{}权限!"
|
||||
no_permission2 = "您没有操作权限!"
|
||||
no_permission_only_owner = "只有创建人或者管理员才有权限!"
|
||||
role_required = _l("Role {} can only operate!") # 角色 {} 才能操作!
|
||||
user_not_found = _l("User {} does not exist") # 用户 {} 不存在
|
||||
no_permission = _l("You do not have {} permission for resource: {}!") # 您没有资源: {} 的{}权限!
|
||||
no_permission2 = _l("You do not have permission to operate!") # 您没有操作权限!
|
||||
no_permission_only_owner = _l("Only the creator or administrator has permission!") # 只有创建人或者管理员才有权限!
|
||||
|
BIN
cmdb-api/api/translations/zh/LC_MESSAGES/messages.mo
Normal file
BIN
cmdb-api/api/translations/zh/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
819
cmdb-api/api/translations/zh/LC_MESSAGES/messages.po
Normal file
819
cmdb-api/api/translations/zh/LC_MESSAGES/messages.po
Normal file
@@ -0,0 +1,819 @@
|
||||
# Chinese translations for PROJECT.
|
||||
# Copyright (C) 2023 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2024-01-03 11:39+0800\n"
|
||||
"PO-Revision-Date: 2023-12-25 20:21+0800\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: zh\n"
|
||||
"Language-Team: zh <LL@li.org>\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.14.0\n"
|
||||
|
||||
#: api/lib/resp_format.py:7
|
||||
msgid "unauthorized"
|
||||
msgstr "未认证"
|
||||
|
||||
#: api/lib/resp_format.py:8
|
||||
msgid "unknown error"
|
||||
msgstr "未知错误"
|
||||
|
||||
#: api/lib/resp_format.py:10
|
||||
msgid "Illegal request"
|
||||
msgstr "不合法的请求"
|
||||
|
||||
#: api/lib/resp_format.py:11
|
||||
msgid "Invalid operation"
|
||||
msgstr "无效的操作"
|
||||
|
||||
#: api/lib/resp_format.py:13
|
||||
msgid "does not exist"
|
||||
msgstr "不存在"
|
||||
|
||||
#: api/lib/resp_format.py:15
|
||||
msgid "There is a circular dependency!"
|
||||
msgstr "存在循环依赖!"
|
||||
|
||||
#: api/lib/resp_format.py:17
|
||||
msgid "Unknown search error"
|
||||
msgstr "未知搜索错误"
|
||||
|
||||
#: api/lib/resp_format.py:20
|
||||
msgid "The json format seems to be incorrect, please confirm carefully!"
|
||||
msgstr "# json格式似乎不正确了, 请仔细确认一下!"
|
||||
|
||||
#: api/lib/resp_format.py:23
|
||||
msgid ""
|
||||
"The format of parameter {} is incorrect, the format must be: yyyy-mm-dd "
|
||||
"HH:MM:SS"
|
||||
msgstr "参数 {} 格式不正确, 格式必须是: yyyy-mm-dd HH:MM:SS"
|
||||
|
||||
#: api/lib/resp_format.py:25
|
||||
msgid "The value of parameter {} cannot be empty!"
|
||||
msgstr "参数 {} 的值不能为空!"
|
||||
|
||||
#: api/lib/resp_format.py:26
|
||||
msgid "The request is missing parameters {}"
|
||||
msgstr "请求缺少参数 {}"
|
||||
|
||||
#: api/lib/resp_format.py:27
|
||||
msgid "Invalid value for parameter {}"
|
||||
msgstr "参数 {} 的值无效"
|
||||
|
||||
#: api/lib/resp_format.py:28
|
||||
msgid "The length of parameter {} must be <= {}"
|
||||
msgstr "参数 {} 的长度必须 <= {}"
|
||||
|
||||
#: api/lib/resp_format.py:30
|
||||
msgid "Role {} can only operate!"
|
||||
msgstr "角色 {} 才能操作!"
|
||||
|
||||
#: api/lib/resp_format.py:31
|
||||
msgid "User {} does not exist"
|
||||
msgstr "用户 {} 不存在"
|
||||
|
||||
#: api/lib/resp_format.py:32
|
||||
msgid "You do not have {} permission for resource: {}!"
|
||||
msgstr "您没有资源: {} 的{}权限!"
|
||||
|
||||
#: api/lib/resp_format.py:33
|
||||
msgid "You do not have permission to operate!"
|
||||
msgstr "您没有操作权限!"
|
||||
|
||||
#: api/lib/resp_format.py:34
|
||||
msgid "Only the creator or administrator has permission!"
|
||||
msgstr "只有创建人或者管理员才有权限!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:9
|
||||
msgid "CI Model"
|
||||
msgstr "模型配置"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:11
|
||||
msgid "Invalid relation type: {}"
|
||||
msgstr "无效的关系类型: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:12
|
||||
msgid "CIType is not found"
|
||||
msgstr "模型不存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:15
|
||||
msgid "The type of parameter attributes must be a list"
|
||||
msgstr "参数 attributes 类型必须是列表"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:16
|
||||
msgid "The file doesn't seem to be uploaded"
|
||||
msgstr "文件似乎并未上传"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:18
|
||||
msgid "Attribute {} does not exist!"
|
||||
msgstr "属性 {} 不存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:19
|
||||
msgid ""
|
||||
"This attribute is the unique identifier of the model and cannot be "
|
||||
"deleted!"
|
||||
msgstr "该属性是模型的唯一标识,不能被删除!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:21
|
||||
msgid "This attribute is referenced by model {} and cannot be deleted!"
|
||||
msgstr "该属性被模型 {} 引用, 不能删除!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:23
|
||||
msgid "The value type of the attribute is not allowed to be modified!"
|
||||
msgstr "属性的值类型不允许修改!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:25
|
||||
msgid "Multiple values are not allowed to be modified!"
|
||||
msgstr "多值不被允许修改!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:27
|
||||
msgid "Modifying the index is not allowed for non-administrators!"
|
||||
msgstr "修改索引 非管理员不被允许!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:28
|
||||
msgid "Index switching failed!"
|
||||
msgstr "索引切换失败!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:29
|
||||
msgid "The predefined value is of the wrong type!"
|
||||
msgstr "预定义值的类型不对!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:30
|
||||
msgid "Duplicate attribute name {}"
|
||||
msgstr "重复的属性名 {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:31
|
||||
msgid "Failed to create attribute {}!"
|
||||
msgstr "创建属性 {} 失败!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:32
|
||||
msgid "Modify attribute {} failed!"
|
||||
msgstr "修改属性 {} 失败!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:33
|
||||
msgid "You do not have permission to modify this attribute!"
|
||||
msgstr "您没有权限修改该属性!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:34
|
||||
msgid "Only creators and administrators are allowed to delete attributes!"
|
||||
msgstr "目前只允许 属性创建人、管理员 删除属性!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:37
|
||||
msgid ""
|
||||
"Attribute field names cannot be built-in fields: id, _id, ci_id, type, "
|
||||
"_type, ci_type"
|
||||
msgstr "属性字段名不能是内置字段: id, _id, ci_id, type, _type, ci_type"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:39
|
||||
msgid "Predefined value: Other model request parameters are illegal!"
|
||||
msgstr "预定义值: 其他模型请求参数不合法!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:42
|
||||
msgid "CI {} does not exist"
|
||||
msgstr "CI {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:43
|
||||
msgid "Multiple attribute joint unique verification failed: {}"
|
||||
msgstr "多属性联合唯一校验不通过: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:44
|
||||
msgid "The model's primary key {} does not exist!"
|
||||
msgstr "模型的主键 {} 不存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:45
|
||||
msgid "Primary key {} is missing"
|
||||
msgstr "主键字段 {} 缺失"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:46
|
||||
msgid "CI already exists!"
|
||||
msgstr "CI 已经存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:47
|
||||
msgid "Relationship constraint: {}, verification failed"
|
||||
msgstr "关系约束: {}, 校验失败"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:49
|
||||
msgid ""
|
||||
"Many-to-many relationship constraint: Model {} <-> {} already has a many-"
|
||||
"to-many relationship!"
|
||||
msgstr "多对多关系 限制: 模型 {} <-> {} 已经存在多对多关系!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:52
|
||||
msgid "CI relationship: {} does not exist"
|
||||
msgstr "CI关系: {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:55
|
||||
msgid "In search expressions, not supported before parentheses: or, not"
|
||||
msgstr "搜索表达式里小括号前不支持: 或、非"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:57
|
||||
msgid "Model {} does not exist"
|
||||
msgstr "模型 {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:58
|
||||
msgid "Model {} already exists"
|
||||
msgstr "模型 {} 已经存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:59
|
||||
msgid "The primary key is undefined or has been deleted"
|
||||
msgstr "主键未定义或者已被删除"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:60
|
||||
msgid "Only the creator can delete it!"
|
||||
msgstr "只有创建人才能删除它!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:61
|
||||
msgid "The model cannot be deleted because the CI already exists"
|
||||
msgstr "因为CI已经存在,不能删除模型"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:65
|
||||
msgid ""
|
||||
"The model cannot be deleted because the model is referenced by the "
|
||||
"relational view {}"
|
||||
msgstr "因为关系视图 {} 引用了该模型,不能删除模型"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:67
|
||||
msgid "Model group {} does not exist"
|
||||
msgstr "模型分组 {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:68
|
||||
msgid "Model group {} already exists"
|
||||
msgstr "模型分组 {} 已经存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:69
|
||||
msgid "Model relationship {} does not exist"
|
||||
msgstr "模型关系 {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:70
|
||||
msgid "Attribute group {} already exists"
|
||||
msgstr "属性分组 {} 已存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:71
|
||||
msgid "Attribute group {} does not exist"
|
||||
msgstr "属性分组 {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:73
|
||||
msgid "Attribute group <{0}> - attribute <{1}> does not exist"
|
||||
msgstr "属性组<{0}> - 属性<{1}> 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:74
|
||||
msgid "The unique constraint already exists!"
|
||||
msgstr "唯一约束已经存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:76
|
||||
msgid "Uniquely constrained attributes cannot be JSON and multi-valued"
|
||||
msgstr "唯一约束的属性不能是 JSON 和 多值"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:77
|
||||
msgid "Duplicated trigger"
|
||||
msgstr "重复的触发器"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:78
|
||||
msgid "Trigger {} does not exist"
|
||||
msgstr "触发器 {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:80
|
||||
msgid "Operation record {} does not exist"
|
||||
msgstr "操作记录 {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:81
|
||||
msgid "Unique identifier cannot be deleted"
|
||||
msgstr "不能删除唯一标识"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:82
|
||||
msgid "Cannot delete default sorted attributes"
|
||||
msgstr "不能删除默认排序的属性"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:84
|
||||
msgid "No node selected"
|
||||
msgstr "没有选择节点"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:85
|
||||
msgid "This search option does not exist!"
|
||||
msgstr "该搜索选项不存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:86
|
||||
msgid "This search option has a duplicate name!"
|
||||
msgstr "该搜索选项命名重复!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:88
|
||||
msgid "Relationship type {} already exists"
|
||||
msgstr "关系类型 {} 已经存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:89
|
||||
msgid "Relationship type {} does not exist"
|
||||
msgstr "关系类型 {} 不存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:91
|
||||
msgid "Invalid attribute value: {}"
|
||||
msgstr "无效的属性值: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:92
|
||||
msgid "{} Invalid value: {}"
|
||||
msgstr "无效的值: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:93
|
||||
msgid "{} is not in the predefined values"
|
||||
msgstr "{} 不在预定义值里"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:95
|
||||
msgid "The value of attribute {} must be unique, {} already exists"
|
||||
msgstr "属性 {} 的值必须是唯一的, 当前值 {} 已存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:96
|
||||
msgid "Attribute {} value must exist"
|
||||
msgstr "属性 {} 值必须存在"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:99
|
||||
msgid "Unknown error when adding or modifying attribute value: {}"
|
||||
msgstr "新增或者修改属性值未知错误: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:101
|
||||
msgid "Duplicate custom name"
|
||||
msgstr "订制名重复"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:103
|
||||
msgid "Number of models exceeds limit: {}"
|
||||
msgstr "模型数超过限制: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:104
|
||||
msgid "The number of CIs exceeds the limit: {}"
|
||||
msgstr "CI数超过限制: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:106
|
||||
msgid "Auto-discovery rule: {} already exists!"
|
||||
msgstr "自动发现规则: {} 已经存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:107
|
||||
msgid "Auto-discovery rule: {} does not exist!"
|
||||
msgstr "自动发现规则: {} 不存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:109
|
||||
msgid "This auto-discovery rule is referenced by the model and cannot be deleted!"
|
||||
msgstr "该自动发现规则被模型引用, 不能删除!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:111
|
||||
msgid "The application of auto-discovery rules cannot be defined repeatedly!"
|
||||
msgstr "自动发现规则的应用不能重复定义!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:112
|
||||
msgid "The auto-discovery you want to modify: {} does not exist!"
|
||||
msgstr "您要修改的自动发现: {} 不存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:113
|
||||
msgid "Attribute does not include unique identifier: {}"
|
||||
msgstr "属性字段没有包括唯一标识: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:114
|
||||
msgid "The auto-discovery instance does not exist!"
|
||||
msgstr "自动发现的实例不存在!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:115
|
||||
msgid "The model is not associated with this auto-discovery!"
|
||||
msgstr "模型并未关联该自动发现!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:116
|
||||
msgid "Only the creator can modify the Secret!"
|
||||
msgstr "只有创建人才能修改Secret!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:118
|
||||
msgid "This rule already has auto-discovery instances and cannot be deleted!"
|
||||
msgstr "该规则已经有自动发现的实例, 不能被删除!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:120
|
||||
msgid "The default auto-discovery rule is already referenced by model {}!"
|
||||
msgstr "该默认的自动发现规则 已经被模型 {} 引用!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:122
|
||||
msgid "The unique_key method must return a non-empty string!"
|
||||
msgstr "unique_key方法必须返回非空字符串!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:123
|
||||
msgid "The attributes method must return a list"
|
||||
msgstr "attributes方法必须返回的是list"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:125
|
||||
msgid "The list returned by the attributes method cannot be empty!"
|
||||
msgstr "attributes方法返回的list不能为空!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:127
|
||||
msgid "Only administrators can define execution targets as: all nodes!"
|
||||
msgstr "只有管理员才可以定义执行机器为: 所有节点!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:128
|
||||
msgid "Execute targets permission check failed: {}"
|
||||
msgstr "执行机器权限检查不通过: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:130
|
||||
msgid "CI filter authorization must be named!"
|
||||
msgstr "CI过滤授权 必须命名!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:131
|
||||
msgid "CI filter authorization is currently not supported or query"
|
||||
msgstr "CI过滤授权 暂时不支持 或 查询"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:134
|
||||
msgid "You do not have permission to operate attribute {}!"
|
||||
msgstr "您没有属性 {} 的操作权限!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:135
|
||||
msgid "You do not have permission to operate this CI!"
|
||||
msgstr "您没有该CI的操作权限!"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:137
|
||||
msgid "Failed to save password: {}"
|
||||
msgstr "保存密码失败: {}"
|
||||
|
||||
#: api/lib/cmdb/resp_format.py:138
|
||||
msgid "Failed to get password: {}"
|
||||
msgstr "获取密码失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:8
|
||||
msgid "Company info already existed"
|
||||
msgstr "公司信息已存在,无法创建!"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:10
|
||||
msgid "No file part"
|
||||
msgstr "没有文件部分"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:11
|
||||
msgid "File is required"
|
||||
msgstr "文件是必须的"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:12
|
||||
msgid "File not found"
|
||||
msgstr "文件不存在!"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:13
|
||||
msgid "File type not allowed"
|
||||
msgstr "文件类型不允许!"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:14
|
||||
msgid "Upload failed: {}"
|
||||
msgstr "上传失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:16
|
||||
msgid "Direct supervisor is not self"
|
||||
msgstr "直属上级不能是自己"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:17
|
||||
msgid "Parent department is not self"
|
||||
msgstr "上级部门不能是自己"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:18
|
||||
msgid "Employee list is empty"
|
||||
msgstr "员工列表为空"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:20
|
||||
msgid "Column name not support"
|
||||
msgstr "不支持的列名"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:21
|
||||
msgid "Password is required"
|
||||
msgstr "密码是必须的"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:22
|
||||
msgid "Employee acl rid is zero"
|
||||
msgstr "员工ACL角色ID不能为0"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:24
|
||||
msgid "Generate excel failed: {}"
|
||||
msgstr "生成excel失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:25
|
||||
msgid "Rename columns failed: {}"
|
||||
msgstr "重命名字段失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:26
|
||||
msgid "Cannot block this employee is other direct supervisor"
|
||||
msgstr "该员工是其他员工的直属上级, 不能禁用"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:28
|
||||
msgid "Cannot block this employee is department manager"
|
||||
msgstr "该员工是部门负责人, 不能禁用"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:30
|
||||
msgid "Employee id [{}] not found"
|
||||
msgstr "员工ID [{}] 不存在!"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:31
|
||||
msgid "Value is required"
|
||||
msgstr "值是必须的"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:32
|
||||
msgid "Email already exists"
|
||||
msgstr "邮箱已存在!"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:33
|
||||
msgid "Query {} none keep value empty"
|
||||
msgstr "查询 {} 空值时请保持value为空"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:34
|
||||
msgid "Not support operator: {}"
|
||||
msgstr "不支持的操作符: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:35
|
||||
msgid "Not support relation: {}"
|
||||
msgstr "不支持的关系: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:36
|
||||
msgid "Conditions field missing"
|
||||
msgstr " conditions内元素字段缺失,请检查!"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:37
|
||||
msgid "Datetime format error: {}"
|
||||
msgstr "{}格式错误,应该为:%Y-%m-%d %H:%M:%S"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:38
|
||||
msgid "Department level relation error"
|
||||
msgstr "部门层级关系不正确"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:39
|
||||
msgid "Delete reserved department name"
|
||||
msgstr "保留部门,无法删除!"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:40
|
||||
msgid "Department id is required"
|
||||
msgstr "部门ID是必须的"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:41
|
||||
msgid "Department list is required"
|
||||
msgstr "部门列表是必须的"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:42
|
||||
msgid "{} Cannot to be parent department"
|
||||
msgstr "{} 不能设置为上级部门"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:43
|
||||
msgid "Department id [{}] not found"
|
||||
msgstr "部门ID [{}] 不存在"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:44
|
||||
msgid "Parent department id must more than zero"
|
||||
msgstr "上级部门ID必须大于0"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:45
|
||||
msgid "Department name [{}] already exists"
|
||||
msgstr "部门名称 [{}] 已存在"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:46
|
||||
msgid "New department is none"
|
||||
msgstr "新部门是空的"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:48
|
||||
msgid "ACL edit user failed: {}"
|
||||
msgstr "ACL 修改用户失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:49
|
||||
msgid "ACL uid not found: {}"
|
||||
msgstr "ACL 用户UID [{}] 不存在"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:50
|
||||
msgid "ACL add user failed: {}"
|
||||
msgstr "ACL 添加用户失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:51
|
||||
msgid "ACL add role failed: {}"
|
||||
msgstr "ACL 添加角色失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:52
|
||||
msgid "ACL update role failed: {}"
|
||||
msgstr "ACL 更新角色失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:53
|
||||
msgid "ACL get all users failed: {}"
|
||||
msgstr "ACL 获取所有用户失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:54
|
||||
msgid "ACL remove user from role failed: {}"
|
||||
msgstr "ACL 从角色中移除用户失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:55
|
||||
msgid "ACL add user to role failed: {}"
|
||||
msgstr "ACL 添加用户到角色失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:56
|
||||
msgid "ACL import user failed: {}"
|
||||
msgstr "ACL 导入用户失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:58
|
||||
msgid "Nickname is required"
|
||||
msgstr "昵称不能为空"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:59
|
||||
msgid "Username is required"
|
||||
msgstr "用户名不能为空"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:60
|
||||
msgid "Email is required"
|
||||
msgstr "邮箱不能为空"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:61
|
||||
msgid "Email format error"
|
||||
msgstr "邮箱格式错误"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:62
|
||||
msgid "Email send timeout"
|
||||
msgstr "邮件发送超时"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:64
|
||||
msgid "Common data not found {} "
|
||||
msgstr "ID {} 找不到记录"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:65
|
||||
msgid "Common data {} already existed"
|
||||
msgstr "{} 已经存在"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:66
|
||||
msgid "Notice platform {} existed"
|
||||
msgstr "{} 已经存在"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:67
|
||||
msgid "Notice {} not existed"
|
||||
msgstr "{} 配置项不存在"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:68
|
||||
msgid "Notice please config messenger first"
|
||||
msgstr "请先配置messenger URL"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:69
|
||||
msgid "Notice bind err with empty mobile"
|
||||
msgstr "绑定错误,手机号为空"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:70
|
||||
msgid "Notice bind failed: {}"
|
||||
msgstr "绑定失败: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:71
|
||||
msgid "Notice bind success"
|
||||
msgstr "绑定成功"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:72
|
||||
msgid "Notice remove bind success"
|
||||
msgstr "解绑成功"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:74
|
||||
msgid "Not support test type: {}"
|
||||
msgstr "不支持的测试类型: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:75
|
||||
msgid "Not support auth type: {}"
|
||||
msgstr "不支持的认证类型: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:76
|
||||
msgid "LDAP server connect timeout"
|
||||
msgstr "LDAP服务器连接超时"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:77
|
||||
msgid "LDAP server connect not available"
|
||||
msgstr "LDAP服务器连接不可用"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:78
|
||||
msgid "LDAP test unknown error: {}"
|
||||
msgstr "LDAP测试未知错误: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:79
|
||||
msgid "Common data not support auth type: {}"
|
||||
msgstr "通用数据不支持auth类型: {}"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:80
|
||||
msgid "LDAP test username required"
|
||||
msgstr "LDAP测试用户名必填"
|
||||
|
||||
#: api/lib/common_setting/resp_format.py:82
|
||||
msgid "Company wide"
|
||||
msgstr "全公司"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:9
|
||||
msgid "login successful"
|
||||
msgstr "登录成功"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:10
|
||||
msgid "Failed to connect to LDAP service"
|
||||
msgstr "连接LDAP服务失败"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:11
|
||||
msgid "Password verification failed"
|
||||
msgstr "密码验证失败"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:12
|
||||
msgid "Application Token verification failed"
|
||||
msgstr "应用 Token验证失败"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:14
|
||||
msgid ""
|
||||
"You are not the application administrator or the session has expired (try"
|
||||
" logging out and logging in again)"
|
||||
msgstr "您不是应用管理员 或者 session失效(尝试一下退出重新登录)"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:17
|
||||
msgid "Resource type {} does not exist!"
|
||||
msgstr "资源类型 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:18
|
||||
msgid "Resource type {} already exists!"
|
||||
msgstr "资源类型 {} 已经存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:20
|
||||
msgid "Because there are resources under this type, they cannot be deleted!"
|
||||
msgstr "因为该类型下有资源的存在, 不能删除!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:22
|
||||
msgid "User {} does not exist!"
|
||||
msgstr "用户 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:23
|
||||
msgid "User {} already exists!"
|
||||
msgstr "用户 {} 已经存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:24
|
||||
msgid "Role {} does not exist!"
|
||||
msgstr "角色 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:25
|
||||
msgid "Role {} already exists!"
|
||||
msgstr "角色 {} 已经存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:26
|
||||
msgid "Global role {} does not exist!"
|
||||
msgstr "全局角色 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:27
|
||||
msgid "Global role {} already exists!"
|
||||
msgstr "全局角色 {} 已经存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:29
|
||||
msgid "You do not have {} permission on resource: {}"
|
||||
msgstr "您没有资源: {} 的 {} 权限"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:30
|
||||
msgid "Requires administrator permissions"
|
||||
msgstr "需要管理员权限"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:31
|
||||
msgid "Requires role: {}"
|
||||
msgstr "需要角色: {}"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:33
|
||||
msgid "To delete a user role, please operate on the User Management page!"
|
||||
msgstr "删除用户角色, 请在 用户管理 页面操作!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:35
|
||||
msgid "Application {} already exists"
|
||||
msgstr "应用 {} 已经存在"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:36
|
||||
msgid "Application {} does not exist!"
|
||||
msgstr "应用 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:37
|
||||
msgid "The Secret is invalid"
|
||||
msgstr "应用的Secret无效"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:39
|
||||
msgid "Resource {} does not exist!"
|
||||
msgstr "资源 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:40
|
||||
msgid "Resource {} already exists!"
|
||||
msgstr "资源 {} 已经存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:42
|
||||
msgid "Resource group {} does not exist!"
|
||||
msgstr "资源组 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:43
|
||||
msgid "Resource group {} already exists!"
|
||||
msgstr "资源组 {} 已经存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:45
|
||||
msgid "Inheritance detected infinite loop"
|
||||
msgstr "继承检测到了死循环"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:46
|
||||
msgid "Role relationship {} does not exist!"
|
||||
msgstr "角色关系 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:48
|
||||
msgid "Trigger {} does not exist!"
|
||||
msgstr "触发器 {} 不存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:49
|
||||
msgid "Trigger {} already exists!"
|
||||
msgstr "触发器 {} 已经存在!"
|
||||
|
||||
#: api/lib/perm/acl/resp_format.py:50
|
||||
msgid "Trigger {} has been disabled!"
|
||||
msgstr "Trigger {} has been disabled!"
|
||||
|
||||
#~ msgid "Not a valid date value."
|
||||
#~ msgstr ""
|
||||
|
@@ -62,7 +62,7 @@ class DepartmentView(APIView):
|
||||
class DepartmentIDView(APIView):
|
||||
url_prefix = (f'{prefix}/<int:_id>',)
|
||||
|
||||
def get(self, _id):
|
||||
def put(self, _id):
|
||||
form = DepartmentForm(MultiDict(request.json))
|
||||
if not form.validate():
|
||||
abort(400, ','.join(['{}: {}'.format(filed, ','.join(msg))
|
||||
|
1
cmdb-api/babel.cfg
Normal file
1
cmdb-api/babel.cfg
Normal file
@@ -0,0 +1 @@
|
||||
[python: api/**.py]
|
@@ -10,6 +10,7 @@ environs==4.2.0
|
||||
flasgger==0.9.5
|
||||
Flask==2.3.2
|
||||
Flask-Bcrypt==1.0.1
|
||||
flask-babel==4.0.0
|
||||
Flask-Caching==2.0.2
|
||||
Flask-Cors==4.0.0
|
||||
Flask-Login>=0.6.2
|
||||
|
@@ -27,7 +27,8 @@
|
||||
"core-js": "^3.31.0",
|
||||
"echarts": "^5.3.2",
|
||||
"element-ui": "^2.15.10",
|
||||
"exceljs": "^4.3.0",
|
||||
"exceljs": "^4.4.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"html2canvas": "^1.0.0-rc.5",
|
||||
"is-buffer": "^2.0.5",
|
||||
"jquery": "^3.6.0",
|
||||
@@ -47,6 +48,7 @@
|
||||
"vue-codemirror": "^4.0.6",
|
||||
"vue-cropper": "^0.6.2",
|
||||
"vue-grid-layout": "2.3.12",
|
||||
"vue-i18n": "8.28.2",
|
||||
"vue-infinite-scroll": "^2.0.2",
|
||||
"vue-json-editor": "^1.4.3",
|
||||
"vue-ls": "^3.2.1",
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-config-provider :locale="locale">
|
||||
<a-config-provider :locale="antdLocale">
|
||||
<div id="app" :class="{ 'ops-fullscreen': isOpsFullScreen, 'ops-only-topmenu': isOpsOnlyTopMenu }">
|
||||
<router-view v-if="alive" />
|
||||
</div>
|
||||
@@ -7,8 +7,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
import { mapState, mapActions, mapMutations } from 'vuex'
|
||||
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
|
||||
import enUS from 'ant-design-vue/lib/locale-provider/en_US'
|
||||
import { AppDeviceEnquire } from '@/utils/mixin'
|
||||
import { debounce } from './utils/util'
|
||||
|
||||
@@ -24,20 +25,28 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
locale: zhCN,
|
||||
alive: true,
|
||||
timer: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['locale']),
|
||||
antdLocale() {
|
||||
if (this.locale === 'zh') {
|
||||
return zhCN
|
||||
}
|
||||
return enUS
|
||||
},
|
||||
isOpsFullScreen() {
|
||||
return this.$route.name === 'cmdb_screen'
|
||||
return ['cmdb_screen'].includes(this.$route.name)
|
||||
},
|
||||
isOpsOnlyTopMenu() {
|
||||
return ['fullscreen_index', 'setting_person'].includes(this.$route.name)
|
||||
return ['fullscreen_index', 'setting_person', 'notice_center'].includes(this.$route.name)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.SET_LOCALE(localStorage.getItem('ops_locale') || 'zh')
|
||||
this.$i18n.locale = localStorage.getItem('ops_locale') || 'zh'
|
||||
this.timer = setInterval(() => {
|
||||
this.setTime(new Date().getTime())
|
||||
}, 1000)
|
||||
@@ -184,6 +193,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setTime']),
|
||||
...mapMutations(['SET_LOCALE']),
|
||||
reload() {
|
||||
this.alive = false
|
||||
this.$nextTick(() => {
|
||||
|
@@ -1,29 +1,37 @@
|
||||
export const ruleTypeList = [
|
||||
{ value: 'and', label: '与' },
|
||||
{ value: 'or', label: '或' },
|
||||
import i18n from '@/lang'
|
||||
|
||||
export const ruleTypeList = () => {
|
||||
return [
|
||||
{ value: 'and', label: i18n.t('cmdbFilterComp.and') },
|
||||
{ value: 'or', label: i18n.t('cmdbFilterComp.or') },
|
||||
// { value: 'not', label: '非' },
|
||||
]
|
||||
}
|
||||
|
||||
export const expList = [
|
||||
{ value: 'is', label: '等于' },
|
||||
{ value: '~is', label: '不等于' },
|
||||
{ value: 'contain', label: '包含' },
|
||||
{ value: '~contain', label: '不包含' },
|
||||
{ value: 'start_with', label: '以...开始' },
|
||||
{ value: '~start_with', label: '不以...开始' },
|
||||
{ value: 'end_with', label: '以...结束' },
|
||||
{ value: '~end_with', label: '不以...结束' },
|
||||
{ value: '~value', label: '为空' }, // 为空的定义有点绕
|
||||
{ value: 'value', label: '不为空' },
|
||||
export const expList = () => {
|
||||
return [
|
||||
{ value: 'is', label: i18n.t('cmdbFilterComp.is') },
|
||||
{ value: '~is', label: i18n.t('cmdbFilterComp.~is') },
|
||||
{ value: 'contain', label: i18n.t('cmdbFilterComp.contain') },
|
||||
{ value: '~contain', label: i18n.t('cmdbFilterComp.~contain') },
|
||||
{ value: 'start_with', label: i18n.t('cmdbFilterComp.start_with') },
|
||||
{ value: '~start_with', label: i18n.t('cmdbFilterComp.~start_with') },
|
||||
{ value: 'end_with', label: i18n.t('cmdbFilterComp.end_with') },
|
||||
{ value: '~end_with', label: i18n.t('cmdbFilterComp.~end_with') },
|
||||
{ value: '~value', label: i18n.t('cmdbFilterComp.~value') }, // 为空的定义有点绕
|
||||
{ value: 'value', label: i18n.t('cmdbFilterComp.value') },
|
||||
]
|
||||
}
|
||||
|
||||
export const advancedExpList = [
|
||||
{ value: 'in', label: 'in查询' },
|
||||
{ value: '~in', label: '非in查询' },
|
||||
{ value: 'range', label: '范围' },
|
||||
{ value: '~range', label: '范围外' },
|
||||
{ value: 'compare', label: '比较' },
|
||||
export const advancedExpList = () => {
|
||||
return [
|
||||
{ value: 'in', label: i18n.t('cmdbFilterComp.in') },
|
||||
{ value: '~in', label: i18n.t('cmdbFilterComp.~in') },
|
||||
{ value: 'range', label: i18n.t('cmdbFilterComp.range') },
|
||||
{ value: '~range', label: i18n.t('cmdbFilterComp.~range') },
|
||||
{ value: 'compare', label: i18n.t('cmdbFilterComp.compare') },
|
||||
]
|
||||
}
|
||||
|
||||
export const compareTypeList = [
|
||||
{ value: '1', label: '>' },
|
||||
|
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-space :style="{ display: 'flex', marginBottom: '10px' }" v-for="(item, index) in ruleList" :key="item.id">
|
||||
<div :style="{ width: '50px', height: '24px', position: 'relative' }">
|
||||
<div :style="{ width: '70px', height: '24px', position: 'relative' }">
|
||||
<treeselect
|
||||
v-if="index"
|
||||
class="custom-treeselect"
|
||||
:style="{ width: '50px', '--custom-height': '24px', position: 'absolute', top: '-17px', left: 0 }"
|
||||
:style="{ width: '70px', '--custom-height': '24px', position: 'absolute', top: '-17px', left: 0 }"
|
||||
v-model="item.type"
|
||||
:multiple="false"
|
||||
:clearable="false"
|
||||
@@ -91,7 +91,7 @@
|
||||
searchable
|
||||
v-if="isChoiceByProperty(item.property) && (item.exp === 'is' || item.exp === '~is')"
|
||||
:options="getChoiceValueByProperty(item.property)"
|
||||
placeholder="请选择"
|
||||
:placeholder="$t('placeholder2')"
|
||||
:normalizer="
|
||||
(node) => {
|
||||
return {
|
||||
@@ -119,9 +119,21 @@
|
||||
v-else-if="item.exp === 'range' || item.exp === '~range'"
|
||||
:style="{ width: '175px' }"
|
||||
>
|
||||
<a-input class="ops-input" size="small" v-model="item.min" :style="{ width: '78px' }" placeholder="最小值" />
|
||||
<a-input
|
||||
class="ops-input"
|
||||
size="small"
|
||||
v-model="item.min"
|
||||
:style="{ width: '78px' }"
|
||||
:placeholder="$t('min')"
|
||||
/>
|
||||
~
|
||||
<a-input class="ops-input" size="small" v-model="item.max" :style="{ width: '78px' }" placeholder="最大值" />
|
||||
<a-input
|
||||
class="ops-input"
|
||||
size="small"
|
||||
v-model="item.max"
|
||||
:style="{ width: '78px' }"
|
||||
:placeholder="$t('max')"
|
||||
/>
|
||||
</a-input-group>
|
||||
<a-input-group size="small" compact v-else-if="item.exp === 'compare'" :style="{ width: '175px' }">
|
||||
<treeselect
|
||||
@@ -151,19 +163,23 @@
|
||||
v-else-if="item.exp !== 'value' && item.exp !== '~value'"
|
||||
size="small"
|
||||
v-model="item.value"
|
||||
:placeholder="item.exp === 'in' || item.exp === '~in' ? '以 ; 分隔' : ''"
|
||||
:placeholder="item.exp === 'in' || item.exp === '~in' ? $t('cmdbFilterComp.split', { separator: ';' }) : ''"
|
||||
class="ops-input"
|
||||
:style="{ width: '175px' }"
|
||||
></a-input>
|
||||
<div v-else :style="{ width: '175px' }"></div>
|
||||
<a-tooltip title="复制">
|
||||
<a-tooltip :title="$t('copy')">
|
||||
<a class="operation" @click="handleCopyRule(item)"><ops-icon type="icon-xianxing-copy"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="删除">
|
||||
<a-tooltip :title="$t('delete')">
|
||||
<a class="operation" @click="handleDeleteRule(item)"><ops-icon type="icon-xianxing-delete"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="$t('cmdbFilterComp.addHere')" v-if="needAddHere">
|
||||
<a class="operation" @click="handleAddRuleAt(item)"><a-icon type="plus-circle"/></a>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
<div class="table-filter-add">
|
||||
<a @click="handleAddRule">+ 新增</a>
|
||||
<a @click="handleAddRule">+ {{ $t('new') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -191,12 +207,13 @@ export default {
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
needAddHere: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ruleTypeList,
|
||||
expList,
|
||||
advancedExpList,
|
||||
compareTypeList,
|
||||
}
|
||||
},
|
||||
@@ -210,6 +227,15 @@ export default {
|
||||
return val
|
||||
},
|
||||
},
|
||||
ruleTypeList() {
|
||||
return ruleTypeList()
|
||||
},
|
||||
expList() {
|
||||
return expList()
|
||||
},
|
||||
advancedExpList() {
|
||||
return advancedExpList()
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getExpListByProperty(property) {
|
||||
@@ -217,10 +243,10 @@ export default {
|
||||
const _find = this.canSearchPreferenceAttrList.find((item) => item.name === property)
|
||||
if (_find && ['0', '1', '3', '4', '5'].includes(_find.value_type)) {
|
||||
return [
|
||||
{ value: 'is', label: '等于' },
|
||||
{ value: '~is', label: '不等于' },
|
||||
{ value: '~value', label: '为空' }, // 为空的定义有点绕
|
||||
{ value: 'value', label: '不为空' },
|
||||
{ value: 'is', label: this.$t('cmdbFilterComp.is') },
|
||||
{ value: '~is', label: this.$t('cmdbFilterComp.~is') },
|
||||
{ value: '~value', label: this.$t('cmdbFilterComp.~value') }, // 为空的定义有点绕
|
||||
{ value: 'value', label: this.$t('cmdbFilterComp.value') },
|
||||
]
|
||||
}
|
||||
return this.expList
|
||||
@@ -255,6 +281,19 @@ export default {
|
||||
}
|
||||
this.$emit('change', this.ruleList)
|
||||
},
|
||||
handleAddRuleAt(item) {
|
||||
const idx = this.ruleList.findIndex((r) => r.id === item.id)
|
||||
if (idx > -1) {
|
||||
this.ruleList.splice(idx, 0, {
|
||||
id: uuidv4(),
|
||||
type: 'and',
|
||||
property: this.canSearchPreferenceAttrList[0]?.name,
|
||||
exp: 'is',
|
||||
value: null,
|
||||
})
|
||||
}
|
||||
this.$emit('change', this.ruleList)
|
||||
},
|
||||
getChoiceValueByProperty(property) {
|
||||
const _find = this.canSearchPreferenceAttrList.find((item) => item.name === property)
|
||||
if (_find) {
|
||||
|
@@ -9,23 +9,25 @@
|
||||
@visibleChange="visibleChange"
|
||||
>
|
||||
<slot name="popover_item">
|
||||
<a-button type="primary" ghost>条件过滤<a-icon type="filter"/></a-button>
|
||||
<a-button type="primary" ghost>{{ $t('cmdbFilterComp.conditionFilter') }}<a-icon type="filter"/></a-button>
|
||||
</slot>
|
||||
<template slot="content">
|
||||
<Expression
|
||||
:needAddHere="needAddHere"
|
||||
v-model="ruleList"
|
||||
:canSearchPreferenceAttrList="canSearchPreferenceAttrList.filter((attr) => !attr.is_password)"
|
||||
/>
|
||||
<a-divider :style="{ margin: '10px 0' }" />
|
||||
<div style="width:534px">
|
||||
<div style="width:554px">
|
||||
<a-space :style="{ display: 'flex', justifyContent: 'flex-end' }">
|
||||
<a-button type="primary" size="small" @click="handleSubmit">确定</a-button>
|
||||
<a-button size="small" @click="handleClear">清空</a-button>
|
||||
<a-button type="primary" size="small" @click="handleSubmit">{{ $t('confirm') }}</a-button>
|
||||
<a-button size="small" @click="handleClear">{{ $t('clear') }}</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
<Expression
|
||||
:needAddHere="needAddHere"
|
||||
v-else
|
||||
v-model="ruleList"
|
||||
:canSearchPreferenceAttrList="canSearchPreferenceAttrList.filter((attr) => !attr.is_password)"
|
||||
@@ -63,6 +65,10 @@ export default {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
needAddHere: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@@ -89,20 +89,23 @@ export default {
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const keyMapList = [
|
||||
{ value: 'default', label: '默认' },
|
||||
{ value: 'vim', label: 'vim' },
|
||||
{ value: 'emacs', label: 'emacs' },
|
||||
{ value: 'sublime', label: 'sublime' },
|
||||
]
|
||||
return {
|
||||
keyMapList,
|
||||
coder: null,
|
||||
fontSize: 14,
|
||||
keyMap: 'default',
|
||||
fullscreenExitVisible: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
keyMapList() {
|
||||
return [
|
||||
{ value: 'default', label: this.$t('default') },
|
||||
{ value: 'vim', label: 'vim' },
|
||||
{ value: 'emacs', label: 'emacs' },
|
||||
{ value: 'sublime', label: 'sublime' },
|
||||
]
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
initCodeMirror(codeContent) {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
export const iconTypeList = [
|
||||
import i18n from '@/lang'
|
||||
|
||||
export const iconTypeList = () => [
|
||||
// { value: '0', label: '常用' },
|
||||
{ value: '1', label: '线性' },
|
||||
{ value: '2', label: '实底' },
|
||||
{ value: '3', label: '多色' }
|
||||
{ value: '1', label: i18n.t('customIconSelect.outlined') },
|
||||
{ value: '2', label: i18n.t('customIconSelect.filled') },
|
||||
{ value: '3', label: i18n.t('customIconSelect.multicolor') }
|
||||
]
|
||||
|
||||
export const commonIconList = ['changyong-ubuntu',
|
||||
|
@@ -16,7 +16,7 @@
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<div :class="`${currentIconType === '4' ? 'selected' : ''}`" @click="handleChangeIconType('4')">
|
||||
自定义
|
||||
{{ this.$t('customIconSelect.custom') }}
|
||||
</div>
|
||||
<a-upload
|
||||
slot="description"
|
||||
@@ -26,7 +26,7 @@
|
||||
accept=".svg,.png,.jpg,.jpeg"
|
||||
v-if="currentIconType === '4'"
|
||||
>
|
||||
<a-button icon="plus" size="small" type="primary">添加</a-button>
|
||||
<a-button icon="plus" size="small" type="primary">{{ $t('add') }}</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
<div class="custom-icon-select-popover-content">
|
||||
@@ -55,11 +55,11 @@
|
||||
@click="clickCustomIcon(icon)"
|
||||
>
|
||||
<div class="custom-icon-select-popover-content-img-box">
|
||||
<img :src="`/api/common-setting/v1/file/${icon.data.url}`" />
|
||||
<img v-if="icon.data && icon.data.url" :src="`/api/common-setting/v1/file/${icon.data.url}`" />
|
||||
<a-popconfirm
|
||||
overlayClassName="custom-icon-select-confirm-popover"
|
||||
:getPopupContainer="(trigger) => trigger.parentNode"
|
||||
title="确认删除?"
|
||||
:title="$t('confirmDelete')"
|
||||
@confirm="(e) => deleteIcon(e, icon)"
|
||||
@cancel="
|
||||
(e) => {
|
||||
@@ -92,7 +92,7 @@
|
||||
:show-upload-list="false"
|
||||
accept=".svg,.png,.jpg,.jpeg"
|
||||
>
|
||||
<a> 暂无自定义图标,点击此处上传 </a>
|
||||
<a> {{ $t('customIconSelect.nodata') }} </a>
|
||||
</a-upload>
|
||||
</a-empty>
|
||||
</div>
|
||||
@@ -102,27 +102,27 @@
|
||||
</template>
|
||||
<a-form class="custom-icon-select-form" :form="form" v-show="currentIconType === '4' && formVisible">
|
||||
<a-form-item
|
||||
label="名称"
|
||||
:label="$t('name')"
|
||||
:labelCol="{ span: 4 }"
|
||||
:wrapperCol="{ span: 16 }"
|
||||
><a-input
|
||||
v-decorator="['name', { rules: [{ required: true, message: '请输入名称' }] }]"
|
||||
v-decorator="['name', { rules: [{ required: true, message: $t('placeholder1') }] }]"
|
||||
/></a-form-item>
|
||||
<a-form-item label="预览" :labelCol="{ span: 4 }">
|
||||
<a-form-item :label="$t('customIconSelect.preview')" :labelCol="{ span: 4 }">
|
||||
<div class="custom-icon-select-form-img">
|
||||
<img :src="formImg" />
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item label=" " :colon="false" :labelCol="{ span: 16 }">
|
||||
<a-space>
|
||||
<a-button size="small" @click="handleCancel">取消</a-button>
|
||||
<a-button size="small" type="primary" @click="handleOk">确定</a-button>
|
||||
<a-button size="small" @click="handleCancel">{{ $t('cancel') }}</a-button>
|
||||
<a-button size="small" type="primary" @click="handleOk">{{ $t('confirm') }}</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<div class="custom-icon-select-block" id="custom-icon-select-block" @click="showSelect">
|
||||
<div class="custom-icon-select-block" :id="`custom-icon-select-block-${uuid}`" @click="showSelect">
|
||||
<img v-if="value.id && value.url" :src="`/api/common-setting/v1/file/${value.url}`" />
|
||||
<ops-icon
|
||||
v-else
|
||||
@@ -134,6 +134,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { ColorPicker } from 'element-ui'
|
||||
import {
|
||||
iconTypeList,
|
||||
@@ -166,7 +167,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
iconTypeList,
|
||||
commonIconList,
|
||||
linearIconList,
|
||||
fillIconList,
|
||||
@@ -177,6 +177,7 @@ export default {
|
||||
formVisible: false,
|
||||
formImg: null,
|
||||
file: null,
|
||||
uuid: uuidv4(),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -200,6 +201,9 @@ export default {
|
||||
const splitFileName = this.file.name.split('.')
|
||||
return splitFileName.splice(0, splitFileName.length - 1).join('')
|
||||
},
|
||||
iconTypeList() {
|
||||
return iconTypeList()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('click', this.eventListener)
|
||||
@@ -217,7 +221,7 @@ export default {
|
||||
eventListener(e) {
|
||||
if (this.visible) {
|
||||
const dom = document.getElementById(`custom-icon-select-popover`)
|
||||
const dom_icon = document.getElementById(`custom-icon-select-block`)
|
||||
const dom_icon = document.getElementById(`custom-icon-select-block-${this.uuid}`)
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
if (dom) {
|
||||
@@ -249,12 +253,11 @@ export default {
|
||||
color: '',
|
||||
})
|
||||
} else {
|
||||
this.$emit('change', { name: icon.data.name, id: icon.id, url: icon.data.url })
|
||||
this.$emit('change', { name: icon.data.name, id: icon.id, url: icon?.data?.url })
|
||||
}
|
||||
},
|
||||
showSelect() {
|
||||
this.visible = true
|
||||
console.log(this.value)
|
||||
if (!this.value.name) {
|
||||
this.currentIconType = '3'
|
||||
return
|
||||
@@ -278,7 +281,7 @@ export default {
|
||||
beforeUpload(file) {
|
||||
const isLt2M = file.size / 1024 / 1024 < 2
|
||||
if (!isLt2M) {
|
||||
this.$message.error('图片大小不可超过2MB!')
|
||||
this.$message.error(this.$t('customIconSelect.sizeLimit'))
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -306,7 +309,7 @@ export default {
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
addFileData('ops-custom-icon', { data: { name: values.name, url: res.file_name } }).then(() => {
|
||||
this.$message.success('上传成功!')
|
||||
this.$message.success(this.$t('uploadSuccess'))
|
||||
this.handleCancel()
|
||||
this.getFileData()
|
||||
})
|
||||
@@ -318,7 +321,7 @@ export default {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
deleteFileData('ops-custom-icon', icon.id).then(() => {
|
||||
this.$message.success('删除成功!')
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
this.handleCancel()
|
||||
this.getFileData()
|
||||
})
|
||||
|
@@ -6,17 +6,17 @@
|
||||
:flat="true"
|
||||
:multiple="true"
|
||||
:options="employeeTreeSelectOption"
|
||||
placeholder="请输入搜索内容"
|
||||
:placeholder="$t('placeholderSearch')"
|
||||
v-model="treeValue"
|
||||
:max-height="height - 50"
|
||||
noChildrenText="空"
|
||||
noOptionsText="空"
|
||||
:clearable="false"
|
||||
:always-open="true"
|
||||
:default-expand-level="1"
|
||||
:default-expand-level="showInternship ? 0 : 1"
|
||||
:class="{ 'employee-transfer': true, 'employee-transfer-has-input': !!inputValue }"
|
||||
@search-change="changeInputValue"
|
||||
noResultsText="暂无数据"
|
||||
:noResultsText="$t('noData')"
|
||||
openDirection="below"
|
||||
>
|
||||
</treeselect>
|
||||
@@ -85,6 +85,10 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showInternship: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -99,13 +103,22 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
employeeTreeSelectOption() {
|
||||
return formatOption(
|
||||
const formatOptions = formatOption(
|
||||
this.allTreeDepAndEmp,
|
||||
2,
|
||||
this.isDisabledAllCompany,
|
||||
this.uniqueKey || 'department_id',
|
||||
this.uniqueKey || 'employee_id'
|
||||
)
|
||||
if (this.showInternship) {
|
||||
formatOptions.push(
|
||||
...[
|
||||
{ id: -2, label: '全职' },
|
||||
{ id: -3, label: '实习生' },
|
||||
]
|
||||
)
|
||||
}
|
||||
return formatOptions
|
||||
},
|
||||
allTreeDepAndEmp() {
|
||||
if (this.getDataBySelf) {
|
||||
@@ -148,12 +161,16 @@ export default {
|
||||
const department = []
|
||||
const user = []
|
||||
this.rightData.forEach((item) => {
|
||||
if (item === -2 || item === -3) {
|
||||
department.push(item)
|
||||
} else {
|
||||
const _split = item.split('-')
|
||||
if (_split[0] === 'department') {
|
||||
department.push(Number(_split[1]))
|
||||
} else {
|
||||
user.push(Number(_split[1]))
|
||||
}
|
||||
}
|
||||
})
|
||||
const _idx = department.findIndex((item) => item === 0)
|
||||
if (_idx > -1) {
|
||||
@@ -191,6 +208,12 @@ export default {
|
||||
}
|
||||
},
|
||||
getLabel(id) {
|
||||
if (id === -2) {
|
||||
return '全职'
|
||||
}
|
||||
if (id === -3) {
|
||||
return '实习生'
|
||||
}
|
||||
const _split = id.split('-')
|
||||
const type = _split[0]
|
||||
const _id = Number(_split[1])
|
||||
|
@@ -81,25 +81,23 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
// 取消订阅
|
||||
cancelAttributes(e, menu) {
|
||||
const that = this
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
this.$confirm({
|
||||
title: '警告',
|
||||
content: `确认取消订阅 ${menu.meta.title}?`,
|
||||
title: this.$t('alert'),
|
||||
content: this.$t('cmdb.preference.confirmcancelSub2', { name: menu.meta.title }),
|
||||
onOk() {
|
||||
const citypeId = menu.meta.typeId
|
||||
const unsubCIType = subscribeCIType(citypeId, '')
|
||||
const unsubTree = subscribeTreeView(citypeId, '')
|
||||
Promise.all([unsubCIType, unsubTree]).then(() => {
|
||||
that.$message.success('取消订阅成功')
|
||||
that.$message.success(that.$t('cmdb.preference.cancelSubSuccess'))
|
||||
const lastTypeId = window.localStorage.getItem('ops_ci_typeid') || undefined
|
||||
if (Number(citypeId) === Number(lastTypeId)) {
|
||||
localStorage.setItem('ops_ci_typeid', '')
|
||||
}
|
||||
// 删除路由
|
||||
const href = window.location.href
|
||||
const hrefSplit = href.split('/')
|
||||
if (Number(hrefSplit[hrefSplit.length - 1]) === Number(citypeId)) {
|
||||
@@ -119,12 +117,10 @@ export default {
|
||||
},
|
||||
// select menu item
|
||||
onOpenChange(openKeys) {
|
||||
// 在水平模式下时执行,并且不再执行后续
|
||||
if (this.mode === 'horizontal') {
|
||||
this.openKeys = openKeys
|
||||
return
|
||||
}
|
||||
// 非水平模式时
|
||||
const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
|
||||
if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
|
||||
this.openKeys = openKeys
|
||||
@@ -161,6 +157,12 @@ export default {
|
||||
}
|
||||
return null
|
||||
},
|
||||
renderI18n(title) {
|
||||
if (Object.prototype.toString.call(this.$t(`${title}`)) === '[object Object]') {
|
||||
return title
|
||||
}
|
||||
return this.$t(`${title}`)
|
||||
},
|
||||
renderMenuItem(menu) {
|
||||
const isShowDot = menu.path.substr(0, 22) === '/cmdb/instances/types/'
|
||||
const isShowGrant = menu.path.substr(0, 20) === '/cmdb/relationviews/'
|
||||
@@ -170,9 +172,6 @@ export default {
|
||||
const attrs = { href: menu.meta.targetHref || menu.path, target: menu.meta.target }
|
||||
|
||||
if (menu.children && menu.hideChildrenInMenu) {
|
||||
// 把有子菜单的 并且 父菜单是要隐藏子菜单的
|
||||
// 都给子菜单增加一个 hidden 属性
|
||||
// 用来给刷新页面时, selectedKeys 做控制用
|
||||
menu.children.forEach(item => {
|
||||
item.meta = Object.assign(item.meta, { hidden: true })
|
||||
})
|
||||
@@ -183,7 +182,7 @@ export default {
|
||||
<tag {...{ props, attrs }}>
|
||||
{this.renderIcon({ icon: menu.meta.icon, customIcon: menu.meta.customIcon, name: menu.meta.name, typeId: menu.meta.typeId, routeName: menu.name, selectedIcon: menu.meta.selectedIcon, })}
|
||||
<span>
|
||||
<span class={menu.meta.title.length > 10 ? 'scroll' : ''}>{menu.meta.title}</span>
|
||||
<span class={this.renderI18n(menu.meta.title).length > 10 ? 'scroll' : ''}>{this.renderI18n(menu.meta.title)}</span>
|
||||
{isShowDot &&
|
||||
<a-popover
|
||||
overlayClassName="custom-menu-extra-submenu"
|
||||
@@ -193,8 +192,8 @@ export default {
|
||||
getPopupContainer={(trigger) => trigger}
|
||||
content={() =>
|
||||
<div>
|
||||
<div onClick={e => this.handlePerm(e, menu, 'CIType')} class="custom-menu-extra-submenu-item"><a-icon type="user-add" />授权</div>
|
||||
<div onClick={e => this.cancelAttributes(e, menu)} class="custom-menu-extra-submenu-item"><a-icon type="star" />取消订阅</div>
|
||||
<div onClick={e => this.handlePerm(e, menu, 'CIType')} class="custom-menu-extra-submenu-item"><a-icon type="user-add" />{ this.renderI18n('grant') }</div>
|
||||
<div onClick={e => this.cancelAttributes(e, menu)} class="custom-menu-extra-submenu-item"><a-icon type="star" />{ this.renderI18n('cmdb.preference.cancelSub') }</div>
|
||||
</div>}
|
||||
>
|
||||
<a-icon type="menu" ref="extraEllipsis" class="custom-menu-extra-ellipsis"></a-icon>
|
||||
@@ -217,7 +216,7 @@ export default {
|
||||
<SubMenu {...{ key: menu.path }}>
|
||||
<span slot="title">
|
||||
{this.renderIcon({ icon: menu.meta.icon, selectedIcon: menu.meta.selectedIcon, routeName: menu.name })}
|
||||
<span>{menu.meta.title}</span>
|
||||
<span>{this.renderI18n(menu.meta.title)}</span>
|
||||
</span>
|
||||
{itemArr}
|
||||
</SubMenu>
|
||||
@@ -284,7 +283,7 @@ export default {
|
||||
this.$refs.cmdbGrantRelationView.open({ name: menu.meta.name, cmdbGrantType: 'relation_view' })
|
||||
}
|
||||
} else {
|
||||
this.$message.error('权限不足!')
|
||||
this.$message.error(this.$t('noPermission'))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -3,9 +3,9 @@
|
||||
<slot></slot>
|
||||
<template #empty>
|
||||
<slot name="empty">
|
||||
<div>
|
||||
<img :style="{ width: '100px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>暂无数据</div>
|
||||
<div :style="{ paddingTop: '10px' }">
|
||||
<img :style="{ width: '100px', height: '90px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
|
2
cmdb-ui/src/components/Pager/index.js
Normal file
2
cmdb-ui/src/components/Pager/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import Pager from './index.vue'
|
||||
export default Pager
|
138
cmdb-ui/src/components/Pager/index.vue
Normal file
138
cmdb-ui/src/components/Pager/index.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-row class="row" type="flex" justify="end">
|
||||
<a-col>
|
||||
<a-space align="end">
|
||||
<a-button
|
||||
class="left-button"
|
||||
size="small"
|
||||
:disabled="prevIsDisabled"
|
||||
@click="prevPage"
|
||||
><a-icon
|
||||
type="left"
|
||||
/></a-button>
|
||||
<a-button class="page-button" size="small">{{ currentPage }}</a-button>
|
||||
<a-button
|
||||
class="right-button"
|
||||
size="small"
|
||||
:disabled="nextIsDisabled"
|
||||
@click="nextPage"
|
||||
><a-icon
|
||||
type="right"
|
||||
/></a-button>
|
||||
<a-dropdown
|
||||
class="dropdown"
|
||||
size="small"
|
||||
placement="topCenter"
|
||||
:trigger="['click']"
|
||||
:disabled="dropdownIsDisabled"
|
||||
>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item v-for="(size, index) in pageSizes" :key="index" @click="handleItemClick(size)">
|
||||
{{ `${size}${$t('itemsPerPage')}` }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button size="small">{{ `${pageSize}${$t('itemsPerPage')}` }}<a-icon type="down" /> </a-button>
|
||||
</a-dropdown>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Pager',
|
||||
props: {
|
||||
currentPage: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dropdownIsDisabled: false,
|
||||
prevIsDisabled: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nextIsDisabled() {
|
||||
return this.isLoading || this.total < this.pageSize
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isLoading: {
|
||||
immediate: true,
|
||||
handler: function(val) {
|
||||
if (val) {
|
||||
this.dropdownIsDisabled = true
|
||||
this.prevIsDisabled = true
|
||||
} else {
|
||||
this.dropdownIsDisabled = false
|
||||
if (this.currentPage === 1) {
|
||||
this.prevIsDisabled = true
|
||||
} else {
|
||||
this.prevIsDisabled = false
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
currentPage: {
|
||||
immediate: true,
|
||||
handler: function(val) {
|
||||
if (val === 1) {
|
||||
this.prevIsDisabled = true
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleItemClick(size) {
|
||||
this.$emit('showSizeChange', size)
|
||||
},
|
||||
nextPage() {
|
||||
const pageNum = this.currentPage + 1
|
||||
this.$emit('change', pageNum)
|
||||
},
|
||||
prevPage() {
|
||||
const pageNum = this.currentPage - 1
|
||||
this.$emit('change', pageNum)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.row {
|
||||
margin-top: 5px;
|
||||
.left-button {
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
}
|
||||
.right-button {
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
}
|
||||
.page-button {
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -3,12 +3,12 @@
|
||||
<a-switch
|
||||
class="role-transfer-switch"
|
||||
v-model="isUserRole"
|
||||
checked-children="用户"
|
||||
un-checked-children="虚拟"
|
||||
:checked-children="$t('user')"
|
||||
:un-checked-children="$t('visual')"
|
||||
@change="loadRoles"
|
||||
/>
|
||||
<div class="role-transfer-left">
|
||||
<a-input placeholder="请输入搜索内容" v-model="searchValue" />
|
||||
<a-input :placeholder="$t('placeholderSearch')" v-model="searchValue" />
|
||||
<div v-for="item in filterAllRoles" :key="item.id" @click="handleSelectedLeft(item.id)">
|
||||
<a-checkbox :checked="selectedLeft.includes(item.id)" />
|
||||
<div :title="item.name" class="role-transfer-left-role">{{ item.name }}</div>
|
||||
|
@@ -10,9 +10,10 @@
|
||||
>
|
||||
<a-icon type="setting" />
|
||||
</span>
|
||||
<span class="locale" @click="changeLang">{{ locale === 'zh' ? 'English' : '中文' }}</span>
|
||||
<a-popover
|
||||
trigger="click"
|
||||
:overlayStyle="{ width: '120px' }"
|
||||
:overlayStyle="{ width: '150px' }"
|
||||
placement="bottomRight"
|
||||
overlayClassName="custom-user"
|
||||
>
|
||||
@@ -20,12 +21,12 @@
|
||||
<router-link :to="{ name: 'setting_person' }" :style="{ color: '#000000a6' }">
|
||||
<div class="custom-user-item">
|
||||
<a-icon type="user" :style="{ marginRight: '10px' }" />
|
||||
<span>个人中心</span>
|
||||
<span>{{ $t('topMenu.personalCenter') }}</span>
|
||||
</div>
|
||||
</router-link>
|
||||
<div @click="handleLogout" class="custom-user-item">
|
||||
<a-icon type="logout" :style="{ marginRight: '10px' }" />
|
||||
<span>退出登录</span>
|
||||
<span>{{ $t('topMenu.logout') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<span class="action ant-dropdown-link user-dropdown-menu">
|
||||
@@ -44,8 +45,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapActions, mapGetters, mapMutations } from 'vuex'
|
||||
import DocumentLink from './DocumentLink.vue'
|
||||
import { mapState, mapActions, mapGetters } from 'vuex'
|
||||
import { setDocumentTitle, domTitle } from '@/utils/domUtil'
|
||||
|
||||
export default {
|
||||
name: 'UserMenu',
|
||||
@@ -53,20 +55,21 @@ export default {
|
||||
DocumentLink,
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
...mapState(['user', 'locale']),
|
||||
hasBackendPermission() {
|
||||
return this.user?.roles?.permissions.includes('acl_admin', 'backend_admin') || false
|
||||
return this.user?.detailPermissions?.backend?.length
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['Logout']),
|
||||
...mapGetters(['nickname', 'avatar']),
|
||||
...mapMutations(['SET_LOCALE']),
|
||||
handleLogout() {
|
||||
const that = this
|
||||
|
||||
this.$confirm({
|
||||
title: '提示',
|
||||
content: '确认注销登录 ?',
|
||||
title: this.$t('tip'),
|
||||
content: this.$t('topMenu.confirmLogout'),
|
||||
onOk() {
|
||||
return that.Logout()
|
||||
},
|
||||
@@ -76,9 +79,22 @@ export default {
|
||||
handleClick() {
|
||||
this.$router.push('/setting')
|
||||
},
|
||||
changeLang() {
|
||||
if (this.locale === 'zh') {
|
||||
this.SET_LOCALE('en')
|
||||
this.$i18n.locale = 'en'
|
||||
} else {
|
||||
this.SET_LOCALE('zh')
|
||||
this.$i18n.locale = 'zh'
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
setDocumentTitle(`${this.$t(this.$route.meta.title)} - ${domTitle}`)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '~@/style/static.less';
|
||||
.color {
|
||||
@@ -98,4 +114,11 @@ export default {
|
||||
color: #000000a6;
|
||||
}
|
||||
}
|
||||
|
||||
.locale {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #custom_colors[color_1];
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -38,11 +38,18 @@ import CardTitle from '@/components/CardTitle'
|
||||
import ElementUI from 'element-ui'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import OpsTable from '@/components/OpsTable'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import i18n from '@/lang'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$bus = EventBus
|
||||
|
||||
VXETable.setup({
|
||||
i18n: (key, args) => i18n.t(key, args)
|
||||
})
|
||||
Vue.use(VXETable)
|
||||
VXETable.use(VXETablePluginExportXLSX)
|
||||
Vue.use(VueI18n)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
@@ -75,4 +82,3 @@ Vue.component('CustomRadio', CustomRadio)
|
||||
Vue.component('CardTitle', CardTitle)
|
||||
Vue.component('Treeselect', Treeselect)
|
||||
Vue.component('OpsTable', OpsTable)
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import NProgress from 'nprogress'
|
||||
import 'nprogress/nprogress.css'
|
||||
import { setDocumentTitle, domTitle } from '@/utils/domUtil'
|
||||
import { ACCESS_TOKEN } from './store/global/mutation-types'
|
||||
import i18n from '@/lang'
|
||||
|
||||
NProgress.configure({ showSpinner: false })
|
||||
|
||||
@@ -17,7 +18,7 @@ const whitePath = ['/user/login', '/user/logout', '/user/register', '/api/sso/lo
|
||||
// 登录页面处理处理 是否使用单点登录
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start() // start progress bar
|
||||
to.meta && (!!to.meta.title && setDocumentTitle(`${to.meta.title} - ${domTitle}`))
|
||||
to.meta && (!!to.meta.title && setDocumentTitle(`${i18n.t(to.meta.title)} - ${domTitle}`))
|
||||
|
||||
const authed = store.state.authed
|
||||
const auth_type = localStorage.getItem('ops_auth_type')
|
||||
|
151
cmdb-ui/src/lang/en.js
Normal file
151
cmdb-ui/src/lang/en.js
Normal file
@@ -0,0 +1,151 @@
|
||||
import cmdb_en from '@/modules/cmdb/lang/en.js'
|
||||
import cs_en from '../views/setting/lang/en.js'
|
||||
import acl_en from '@/modules/acl/lang/en.js'
|
||||
|
||||
export default {
|
||||
commonMenu: {
|
||||
permission: 'Permission',
|
||||
role: 'Roles',
|
||||
resource: 'Resources',
|
||||
resourceType: 'Resource Types',
|
||||
trigger: 'Triggers',
|
||||
},
|
||||
screen: 'Big Screen',
|
||||
dashboard: 'Dashboard',
|
||||
admin: 'Admin',
|
||||
user: 'User',
|
||||
role: 'Role',
|
||||
operation: 'Operation',
|
||||
login: 'Login',
|
||||
refresh: 'Refresh',
|
||||
cancel: 'Cancel',
|
||||
confirm: 'Confirm',
|
||||
create: 'Create',
|
||||
edit: 'Edit',
|
||||
deleting: 'Deleting',
|
||||
deletingTip: 'Deleting, total of {total}, {successNum} succeeded, {errorNum} failed',
|
||||
grant: 'Grant',
|
||||
login_at: 'Login At',
|
||||
logout_at: 'Logout At',
|
||||
createSuccess: 'Create Success',
|
||||
editSuccess: 'edit Success',
|
||||
warning: 'Warning',
|
||||
export: 'Export',
|
||||
placeholderSearch: 'Please Search',
|
||||
success: 'Success',
|
||||
fail: 'Fail',
|
||||
browser: 'Browser',
|
||||
status: 'Status',
|
||||
type: 'Type',
|
||||
description: 'Description',
|
||||
new: 'New',
|
||||
add: 'Add',
|
||||
define: 'Define',
|
||||
update: 'Update',
|
||||
clear: 'Clear',
|
||||
delete: 'Delete',
|
||||
copy: 'Copy',
|
||||
created_at: 'Created At',
|
||||
updated_at: 'Updated At',
|
||||
placeholder1: 'Please Input',
|
||||
placeholder2: 'Please Select',
|
||||
confirmDelete: 'Confirm delete?',
|
||||
confirmDelete2: 'Confirm delete [{name}]?',
|
||||
query: 'Query',
|
||||
search: 'Search',
|
||||
hide: 'Hide',
|
||||
expand: 'Expand',
|
||||
save: 'Save',
|
||||
submit: 'Submit',
|
||||
upload: 'Import',
|
||||
download: 'Export',
|
||||
name: 'Name',
|
||||
alias: 'Alias',
|
||||
desc: 'Description',
|
||||
other: 'Other',
|
||||
icon: 'Icon',
|
||||
addSuccess: 'Added successfully',
|
||||
uploadSuccess: 'Import successfully',
|
||||
saveSuccess: 'Save successfully',
|
||||
copySuccess: 'Copy successfully',
|
||||
updateSuccess: 'Updated successfully',
|
||||
deleteSuccess: 'Deleted successfully',
|
||||
operateSuccess: 'The operation was successful',
|
||||
noPermission: 'No Permission',
|
||||
noData: 'No Data',
|
||||
seconds: 'Seconds',
|
||||
createdAt: 'Created At',
|
||||
updatedAt: 'Updated At',
|
||||
deletedAt: 'Deleted At',
|
||||
required: 'required',
|
||||
email: 'Email',
|
||||
wechat: 'Wechat',
|
||||
dingding: 'DingTalk',
|
||||
feishu: 'Feishu',
|
||||
bot: 'Robot',
|
||||
checkAll: 'Select All',
|
||||
loading: 'Loading...',
|
||||
view: 'View',
|
||||
reset: 'Reset',
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
all: 'All',
|
||||
selectRows: 'Selected: {rows} items',
|
||||
itemsPerPage: '/page',
|
||||
'星期一': 'Monday',
|
||||
'星期二': 'Tuesday',
|
||||
'星期三': 'Wednesday',
|
||||
'星期四': 'Thursday',
|
||||
'星期五': 'Friday',
|
||||
'星期六': 'Saturday',
|
||||
'星期日': 'Sunday',
|
||||
hour: 'hour',
|
||||
'items/page': '{items} items/page',
|
||||
max: 'Max',
|
||||
min: 'Min',
|
||||
visual: 'Visual',
|
||||
default: 'default',
|
||||
tip: 'Tip',
|
||||
pagination: {
|
||||
total: '{range0}-{range1} of {total} items'
|
||||
},
|
||||
topMenu: {
|
||||
personalCenter: 'My Profile',
|
||||
logout: 'Logout',
|
||||
confirmLogout: 'Are you sure to log out?'
|
||||
},
|
||||
cmdbFilterComp: {
|
||||
conditionFilter: 'Conditional filtering',
|
||||
and: 'and',
|
||||
or: 'or',
|
||||
is: 'equal',
|
||||
'~is': 'not equal',
|
||||
contain: 'contain',
|
||||
'~contain': 'not contain',
|
||||
start_with: 'start_with',
|
||||
'~start_with': 'not start_with',
|
||||
end_with: 'end_with',
|
||||
'~end_with': 'not end_with',
|
||||
'~value': 'null',
|
||||
value: 'not null',
|
||||
in: 'in',
|
||||
'~in': 'not in',
|
||||
range: 'range',
|
||||
'~range': 'out of range',
|
||||
compare: 'compare',
|
||||
addHere: 'Add Here',
|
||||
split: 'split by {separator}'
|
||||
},
|
||||
customIconSelect: {
|
||||
outlined: 'Outlined',
|
||||
filled: 'Filled',
|
||||
multicolor: 'Multicolor',
|
||||
custom: 'Custom',
|
||||
preview: 'Preview',
|
||||
sizeLimit: 'The image size cannot exceed 2MB!',
|
||||
nodata: 'There are currently no custom icons available. Click here to upload'
|
||||
},
|
||||
cmdb: cmdb_en,
|
||||
cs: cs_en,
|
||||
acl: acl_en,
|
||||
}
|
18
cmdb-ui/src/lang/index.js
Normal file
18
cmdb-ui/src/lang/index.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import VueI18n from 'vue-i18n'
|
||||
import zh from './zh'
|
||||
import en from './en'
|
||||
import Vue from 'vue'
|
||||
import zhCN from 'vxe-table/lib/locale/lang/zh-CN'
|
||||
import enUS from 'vxe-table/lib/locale/lang/en-US'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
const i18n = new VueI18n({
|
||||
locale: 'zh', // 初始化中文
|
||||
messages: {
|
||||
'zh': { ...zh, ...zhCN },
|
||||
'en': { ...en, ...enUS },
|
||||
},
|
||||
silentTranslationWarn: true
|
||||
})
|
||||
|
||||
export default i18n
|
151
cmdb-ui/src/lang/zh.js
Normal file
151
cmdb-ui/src/lang/zh.js
Normal file
@@ -0,0 +1,151 @@
|
||||
import cmdb_zh from '@/modules/cmdb/lang/zh.js'
|
||||
import cs_zh from '../views/setting/lang/zh.js'
|
||||
import acl_zh from '@/modules/acl/lang/zh.js'
|
||||
|
||||
export default {
|
||||
commonMenu: {
|
||||
permission: '权限管理',
|
||||
role: '角色管理',
|
||||
resource: '资源管理',
|
||||
resourceType: '资源类型',
|
||||
trigger: '触发器',
|
||||
},
|
||||
screen: '大屏',
|
||||
dashboard: '仪表盘',
|
||||
admin: '管理员',
|
||||
user: '用户',
|
||||
role: '角色',
|
||||
operation: '操作',
|
||||
login: '登录',
|
||||
refresh: '刷新',
|
||||
cancel: '取消',
|
||||
confirm: '确定',
|
||||
create: '创建',
|
||||
edit: '编辑',
|
||||
deleting: '正在删除',
|
||||
deletingTip: '正在删除,共{total}个,成功{successNum}个,失败{errorNum}个',
|
||||
grant: '授权',
|
||||
login_at: '登录时间',
|
||||
logout_at: '登出时间',
|
||||
createSuccess: '创建成功',
|
||||
editSuccess: '修改成功',
|
||||
warning: '警告',
|
||||
export: '导出',
|
||||
placeholderSearch: '请查找',
|
||||
success: '成功',
|
||||
fail: '失败',
|
||||
browser: '浏览器',
|
||||
status: '状态',
|
||||
type: '类型',
|
||||
description: '描述',
|
||||
new: '新增',
|
||||
add: '添加',
|
||||
define: '定义',
|
||||
update: '修改',
|
||||
clear: '清空',
|
||||
delete: '删除',
|
||||
copy: '复制',
|
||||
created_at: '创建日期',
|
||||
updated_at: '更新日期',
|
||||
placeholder1: '请输入',
|
||||
placeholder2: '请选择',
|
||||
confirmDelete: '确认删除?',
|
||||
confirmDelete2: '确认删除【{name}】?',
|
||||
query: '查询',
|
||||
search: '搜索',
|
||||
hide: '隐藏',
|
||||
expand: '展开',
|
||||
save: '保存',
|
||||
submit: '提交',
|
||||
upload: '导入',
|
||||
download: '导出',
|
||||
name: '名称',
|
||||
alias: '别名',
|
||||
desc: '描述',
|
||||
other: '其他',
|
||||
icon: '图标',
|
||||
addSuccess: '新增成功',
|
||||
uploadSuccess: '导入成功',
|
||||
saveSuccess: '保存成功',
|
||||
copySuccess: '复制成功',
|
||||
updateSuccess: '更新成功',
|
||||
deleteSuccess: '删除成功',
|
||||
operateSuccess: '操作成功',
|
||||
noPermission: '权限不足',
|
||||
noData: '暂无数据',
|
||||
seconds: '秒',
|
||||
createdAt: '创建时间',
|
||||
updatedAt: '更新时间',
|
||||
deletedAt: '删除时间',
|
||||
required: '必须',
|
||||
email: '邮件',
|
||||
wechat: '企业微信',
|
||||
dingding: '钉钉',
|
||||
feishu: '飞书',
|
||||
bot: '机器人',
|
||||
checkAll: '全选',
|
||||
loading: '加载中...',
|
||||
view: '查看',
|
||||
reset: '重置',
|
||||
yes: '是',
|
||||
no: '否',
|
||||
all: '全部',
|
||||
selectRows: '选取:{rows} 项',
|
||||
itemsPerPage: '/页',
|
||||
'星期一': '星期一',
|
||||
'星期二': '星期二',
|
||||
'星期三': '星期三',
|
||||
'星期四': '星期四',
|
||||
'星期五': '星期五',
|
||||
'星期六': '星期六',
|
||||
'星期日': '星期日',
|
||||
hour: '小时',
|
||||
'items/page': '{items} 条/页',
|
||||
max: '最大值',
|
||||
min: '最小值',
|
||||
visual: '虚拟',
|
||||
default: '默认',
|
||||
tip: '提示',
|
||||
pagination: {
|
||||
total: '当前展示 {range0}-{range1} 条数据, 共 {total} 条'
|
||||
},
|
||||
topMenu: {
|
||||
personalCenter: '个人中心',
|
||||
logout: '退出登录',
|
||||
confirmLogout: '确认退出登录吗?'
|
||||
},
|
||||
cmdbFilterComp: {
|
||||
conditionFilter: '条件过滤',
|
||||
and: '与',
|
||||
or: '或',
|
||||
is: '等于',
|
||||
'~is': '不等于',
|
||||
contain: '包含',
|
||||
'~contain': '不包含',
|
||||
start_with: '以...开始',
|
||||
'~start_with': '不以...开始',
|
||||
end_with: '以...结束',
|
||||
'~end_with': '不以...结束',
|
||||
'~value': '为空',
|
||||
value: '不为空',
|
||||
in: 'in查询',
|
||||
'~in': '非in查询',
|
||||
range: '范围',
|
||||
'~range': '范围外',
|
||||
compare: '比较',
|
||||
addHere: '在此处添加',
|
||||
split: '以 {separator} 分隔'
|
||||
},
|
||||
customIconSelect: {
|
||||
outlined: '线框',
|
||||
filled: '实底',
|
||||
multicolor: '多色',
|
||||
custom: '自定义',
|
||||
preview: '预览',
|
||||
sizeLimit: '图片大小不可超过2MB!',
|
||||
nodata: '暂无自定义图标,点击此处上传'
|
||||
},
|
||||
cmdb: cmdb_zh,
|
||||
cs: cs_zh,
|
||||
acl: acl_zh,
|
||||
}
|
@@ -10,6 +10,7 @@ import './guard' // guard permission control
|
||||
import './utils/filter' // global filter
|
||||
import Setting from './config/setting'
|
||||
import { Icon } from 'ant-design-vue'
|
||||
import i18n from './lang'
|
||||
|
||||
import iconFont from '../public/iconfont/iconfont'
|
||||
|
||||
@@ -22,6 +23,7 @@ async function start() {
|
||||
const _vue = new Vue({
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
created: bootstrap,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
125
cmdb-ui/src/modules/acl/lang/en.js
Normal file
125
cmdb-ui/src/modules/acl/lang/en.js
Normal file
@@ -0,0 +1,125 @@
|
||||
const acl_en = {
|
||||
date: 'Date',
|
||||
operator: 'Operator',
|
||||
resource: 'Resource',
|
||||
resourceType: 'Resource Type',
|
||||
addResourceType: 'Add Resource Type',
|
||||
app: 'App',
|
||||
operateTime: 'Operate Time',
|
||||
permission: 'Permission',
|
||||
permission_placeholder: 'please select permission',
|
||||
permissionList: 'Permission List',
|
||||
summaryPermissions: 'Summary of permissions',
|
||||
source: 'Source',
|
||||
username: 'Username',
|
||||
username_placeholder: 'please input username',
|
||||
userList: 'User List',
|
||||
groupUser: 'Group User',
|
||||
addUser: 'Add User',
|
||||
subordinateUsers: 'Subordinate Users',
|
||||
nickname: 'Nickname',
|
||||
nickname_placeholder: 'please input nickname',
|
||||
password: 'Password',
|
||||
password_placeholder: 'please input password',
|
||||
department: 'Department',
|
||||
group: 'Group',
|
||||
email: 'Email',
|
||||
email_placeholder: 'please input email',
|
||||
mobile: 'Mobile',
|
||||
isBlock: 'Is Block',
|
||||
block: 'Block',
|
||||
joined_at: 'Joined At',
|
||||
role: 'Role',
|
||||
role_placeholder1: 'please input role',
|
||||
role_placeholder2: 'please select role',
|
||||
role_placeholder3: 'please select a role name, multiple choices are allowed',
|
||||
allRole: 'All Roles',
|
||||
visualRole: 'Virtual Role',
|
||||
addVisualRole: 'Add Virtual Role',
|
||||
inheritedFrom: 'Inherited from',
|
||||
heir: 'Inherit Roles',
|
||||
permissionChange: 'Permissions',
|
||||
roleChange: 'Roles',
|
||||
resourceChange: 'Resources',
|
||||
resourceTypeChange: 'Resource Type',
|
||||
trigger: 'Triggers',
|
||||
triggerNameInput: 'Please enter trigger name',
|
||||
triggerChange: 'Triggers',
|
||||
roleManage: 'Roles',
|
||||
userManage: 'Users',
|
||||
appManage: 'Applications',
|
||||
resourceManage: 'Resources',
|
||||
history: 'Audits',
|
||||
userSecret: 'Secrets',
|
||||
none: 'none',
|
||||
danger: 'Dangerous',
|
||||
confirmDeleteApp: 'Are you sure you want to delete this app?',
|
||||
revoke: 'Revoke',
|
||||
convenient: 'Quick Grant',
|
||||
group2: 'Group',
|
||||
groupName: 'Group Name',
|
||||
resourceName: 'Resource Name',
|
||||
creator: 'Creator',
|
||||
member: 'Members',
|
||||
viewAuth: 'view Auth',
|
||||
addTypeTips: 'There is no type information yet, please add the resource type first!',
|
||||
addResource: 'Add Resource',
|
||||
resourceList: 'Resource List',
|
||||
confirmResetSecret: 'Are you sure you want to reset the user secrets?',
|
||||
addTrigger: 'Add Trigger',
|
||||
deleteTrigger: 'Delete Trigger',
|
||||
applyTrigger: 'Apply Trigger',
|
||||
cancelTrigger: 'Cancel Trigger',
|
||||
enable: 'Enable',
|
||||
disable: 'Disable',
|
||||
viewMatchResult: 'View regular matching results',
|
||||
confirmDeleteTrigger: 'Are you sure you want to delete this trigger?',
|
||||
ruleApply: 'Apply',
|
||||
triggerTip1: 'Are you sure you want to apply this trigger?',
|
||||
triggerTip2: 'Cancel applying this trigger?',
|
||||
appNameInput: 'Please enter an application name',
|
||||
descInput: 'Please enter a description',
|
||||
addApp: 'Add',
|
||||
updateApp: 'Update',
|
||||
cancel: 'Cancel',
|
||||
typeName: 'Name',
|
||||
typeNameInput: 'Please enter a type name',
|
||||
resourceNameInput: 'Please enter resource name',
|
||||
pressEnter: 'Press Enter to confirm filtering',
|
||||
groupMember: 'Group Members:',
|
||||
isGroup: 'Group?',
|
||||
errorTips: 'Error message',
|
||||
roleList: 'Role List',
|
||||
virtual: 'Virtual',
|
||||
resourceBatchTips: 'Please enter the resource name, separated by newlines',
|
||||
memberManage: 'Members: ',
|
||||
newResource: 'New Resource: ',
|
||||
deleteResource: 'Delete Resource: ',
|
||||
deleteResourceType: 'Delete Resource Type: ',
|
||||
noChange: 'No change',
|
||||
batchOperate: 'Batch Operations',
|
||||
batchGrant: 'Batch Grant',
|
||||
batchRevoke: 'Batch Revoke',
|
||||
editPerm: 'Add authorization: ',
|
||||
permInput: 'Please enter permission name',
|
||||
resourceTypeName: 'Resource Type Name',
|
||||
selectedParents: 'Optionally inherit roles',
|
||||
isAppAdmin: 'is app admin',
|
||||
addRole: 'Add Role',
|
||||
roleRelation: 'Role Relation',
|
||||
roleRelationAdd: 'Add Role Relation',
|
||||
roleRelationDelete: 'Delete Role Relation',
|
||||
role2: 'Role',
|
||||
admin: 'Admin',
|
||||
involvingRP: 'Involving resources and permissions',
|
||||
startAt: 'Start Time',
|
||||
endAt: 'End Time',
|
||||
triggerTips1: 'Priority regular pattern (secondary wildcard)',
|
||||
pleaseSelectType: 'Please select resource type',
|
||||
apply: 'Apply',
|
||||
mobileTips: 'Please enter the correct phone number',
|
||||
remove: 'Remove',
|
||||
deleteUserConfirm: 'Are you sure you want to remove this user?',
|
||||
copyResource: 'Copy resource name'
|
||||
}
|
||||
export default acl_en
|
125
cmdb-ui/src/modules/acl/lang/zh.js
Normal file
125
cmdb-ui/src/modules/acl/lang/zh.js
Normal file
@@ -0,0 +1,125 @@
|
||||
const acl_zh = {
|
||||
date: '日期',
|
||||
operator: '操作员',
|
||||
resource: '资源',
|
||||
resourceType: '资源类型',
|
||||
addResourceType: '新增资源类型',
|
||||
app: '应用',
|
||||
operateTime: '操作时间',
|
||||
permission: '权限',
|
||||
permission_placeholder: '请选择权限',
|
||||
permissionList: '权限列表',
|
||||
summaryPermissions: '权限汇总',
|
||||
source: '来源',
|
||||
username: '用户名',
|
||||
username_placeholder: '请输入用户名',
|
||||
userList: '用户列表',
|
||||
groupUser: '组用户',
|
||||
addUser: '新增用户',
|
||||
subordinateUsers: '下属用户',
|
||||
nickname: '中文名',
|
||||
nickname_placeholder: '请输入中文名',
|
||||
password: '密码',
|
||||
password_placeholder: '请输入密码',
|
||||
department: '部门',
|
||||
group: '小组',
|
||||
email: '邮箱',
|
||||
email_placeholder: '请输入邮箱',
|
||||
mobile: '手机号',
|
||||
isBlock: '是否锁定',
|
||||
block: '锁定',
|
||||
joined_at: '加入时间',
|
||||
role: '角色名',
|
||||
role_placeholder1: '请输入角色名',
|
||||
role_placeholder2: '请选择角色名称',
|
||||
role_placeholder3: '请选择角色名称,可多选',
|
||||
allRole: '所有角色',
|
||||
visualRole: '虚拟角色',
|
||||
addVisualRole: '新增虚拟角色',
|
||||
inheritedFrom: '继承自',
|
||||
heir: '继承者',
|
||||
permissionChange: '权限变更',
|
||||
roleChange: '角色变更',
|
||||
resourceChange: '资源变更',
|
||||
resourceTypeChange: '资源类型变更',
|
||||
trigger: '触发器',
|
||||
triggerNameInput: '请输入触发器名',
|
||||
triggerChange: '触发器变更',
|
||||
roleManage: '角色管理',
|
||||
userManage: '用户管理',
|
||||
appManage: '应用管理',
|
||||
resourceManage: '资源管理',
|
||||
history: '操作审计',
|
||||
userSecret: '用户密钥',
|
||||
none: '无',
|
||||
danger: '危险操作',
|
||||
confirmDeleteApp: '确定要删除该App吗?',
|
||||
revoke: '权限回收',
|
||||
convenient: '便捷授权',
|
||||
group2: '组',
|
||||
groupName: '资源组名',
|
||||
resourceName: '资源名',
|
||||
creator: '创建者',
|
||||
member: '成员',
|
||||
viewAuth: '查看授权',
|
||||
addTypeTips: '暂无类型信息,请先添加资源类型!',
|
||||
addResource: '新增资源',
|
||||
resourceList: '资源列表',
|
||||
confirmResetSecret: '确定重置用户密钥?',
|
||||
addTrigger: '新增触发器',
|
||||
deleteTrigger: '删除触发器',
|
||||
applyTrigger: '应用触发器',
|
||||
cancelTrigger: '取消触发器',
|
||||
enable: '启用',
|
||||
disable: '禁用',
|
||||
viewMatchResult: '查看正则匹配结果',
|
||||
confirmDeleteTrigger: '确认删除该触发器吗?',
|
||||
ruleApply: '规则应用',
|
||||
triggerTip1: '是否确定应用该触发器?',
|
||||
triggerTip2: '是否取消应用该触发器?',
|
||||
appNameInput: '请输入应用名称',
|
||||
descInput: '请输入描述',
|
||||
addApp: '创建应用',
|
||||
updateApp: '更新应用',
|
||||
cancel: '撤销',
|
||||
typeName: '类型名',
|
||||
typeNameInput: '请输入类型名',
|
||||
resourceNameInput: '请输入资源名',
|
||||
pressEnter: '按回车确认筛选',
|
||||
groupMember: '组成员:',
|
||||
isGroup: '是否组',
|
||||
errorTips: '错误提示',
|
||||
roleList: '角色列表',
|
||||
virtual: '虚拟',
|
||||
resourceBatchTips: '请输入资源名,换行分隔',
|
||||
memberManage: '成员管理:',
|
||||
newResource: '新建资源:',
|
||||
deleteResource: '删除资源:',
|
||||
deleteResourceType: '删除资源类型:',
|
||||
noChange: '没有修改',
|
||||
batchOperate: '批量操作',
|
||||
batchGrant: '批量授权',
|
||||
batchRevoke: '批量权限回收',
|
||||
editPerm: '添加授权:',
|
||||
permInput: '请输入权限名',
|
||||
resourceTypeName: '资源类型名',
|
||||
selectedParents: '可选择继承角色',
|
||||
isAppAdmin: '是否应用管理员',
|
||||
addRole: '新增角色',
|
||||
roleRelation: '角色关系',
|
||||
roleRelationAdd: '添加角色关系',
|
||||
roleRelationDelete: '删除角色关系',
|
||||
role2: '角色',
|
||||
admin: '管理员',
|
||||
involvingRP: '涉及资源及权限',
|
||||
startAt: '开始时间',
|
||||
endAt: '结束时间',
|
||||
triggerTips1: '优先正则模式(次通配符)',
|
||||
pleaseSelectType: '请选择资源类型',
|
||||
apply: '应用',
|
||||
mobileTips: '请输入正确的手机号码',
|
||||
remove: '移除',
|
||||
deleteUserConfirm: '是否确定要移除该用户',
|
||||
copyResource: '复制资源名'
|
||||
}
|
||||
export default acl_zh
|
@@ -12,35 +12,35 @@ const genAppRoute = ({ name }) => {
|
||||
name: `${name}_roles_acl`,
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('../views/roles'),
|
||||
meta: { title: '角色管理', icon: 'team', keepAlive: true }
|
||||
meta: { title: 'acl.roleManage', icon: 'team', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: `/acl/${name}/resources`,
|
||||
name: `${name}_resources_acl`,
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('../views/resources'),
|
||||
meta: { title: '资源管理', icon: 'credit-card', keepAlive: false }
|
||||
meta: { title: 'acl.resourceManage', icon: 'credit-card', keepAlive: false }
|
||||
},
|
||||
{
|
||||
path: `/acl/${name}/resource_types`,
|
||||
name: `${name}_resource_types_acl`,
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('../views/resource_types'),
|
||||
meta: { title: '资源类型', icon: 'file-text', keepAlive: true }
|
||||
meta: { title: 'acl.resourceType', icon: 'file-text', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: `/acl/${name}/trigger`,
|
||||
name: `${name}_trigger_acl`,
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('../views/trigger'),
|
||||
meta: { title: '触发器', icon: 'clock-circle', keepAlive: true }
|
||||
meta: { title: 'acl.trigger', icon: 'clock-circle', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: `/acl/${name}/history`,
|
||||
name: `${name}_history_acl`,
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('../views/history'),
|
||||
meta: { title: '操作审计', icon: 'search', keepAlive: false }
|
||||
meta: { title: 'acl.history', icon: 'search', keepAlive: false }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -59,31 +59,31 @@ const genAclRoutes = async () => {
|
||||
path: `/acl/secret_key`,
|
||||
name: 'acl_secret_key',
|
||||
component: () => import('../views/secretKey'),
|
||||
meta: { title: '用户密钥', icon: 'key' }
|
||||
meta: { title: 'acl.userSecret', icon: 'key' }
|
||||
},
|
||||
{
|
||||
path: `/acl/operate_history`,
|
||||
name: 'acl_operate_history',
|
||||
component: () => import('../views/operation_history/index.vue'),
|
||||
meta: { title: '操作审计', icon: 'search', permission: ['acl_admin'] },
|
||||
meta: { title: 'acl.history', icon: 'search', permission: ['acl_admin'] }
|
||||
},
|
||||
{
|
||||
path: `/acl/user`,
|
||||
name: 'acl_user',
|
||||
component: () => import('../views/users'),
|
||||
meta: { title: '用户管理', icon: 'user', permission: ['acl_admin'] }
|
||||
meta: { title: 'acl.userManage', icon: 'user', permission: ['acl_admin'] }
|
||||
},
|
||||
{
|
||||
path: `/acl/roles`,
|
||||
name: `acl_roles`,
|
||||
component: () => import('../views/roles'),
|
||||
meta: { title: '角色管理', icon: 'team', keepAlive: true, permission: ['acl_admin'] }
|
||||
meta: { title: 'acl.roleManage', icon: 'team', keepAlive: true, permission: ['acl_admin'] }
|
||||
},
|
||||
{
|
||||
path: `/acl/apps`,
|
||||
name: 'acl_apps',
|
||||
component: () => import('../views/apps'),
|
||||
meta: { title: '应用管理', icon: 'appstore', permission: ['acl_admin'] }
|
||||
meta: { title: 'acl.appManage', icon: 'appstore', permission: ['acl_admin'] }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
:xs="24">
|
||||
<a-card>
|
||||
<a-card-meta :title="app.name">
|
||||
<div slot="description" :title="app.description || ''">{{ app.description || '无' }}</div>
|
||||
<div slot="description" :title="app.description || ''">{{ app.description || $t('none') }}</div>
|
||||
<a-avatar style="background-color: #5dc2f1" slot="avatar">{{ app.name[0].toUpperCase() }}</a-avatar>
|
||||
</a-card-meta>
|
||||
<template slot="actions">
|
||||
@@ -65,11 +65,11 @@ export default {
|
||||
handleDeleteApp(app) {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: '危险操作',
|
||||
content: '确定要删除该App吗?',
|
||||
title: that.$t('danger'),
|
||||
content: that.$t('confirmDeleteApp'),
|
||||
onOk() {
|
||||
deleteApp(app.id).then((res) => {
|
||||
that.$message.success(`删除成功:${app.name}`)
|
||||
that.$message.success(that.$t('deleteSuccess'))
|
||||
that.loadApps()
|
||||
})
|
||||
},
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="acl-history">
|
||||
<a-tabs default-active-key="1">
|
||||
<a-tab-pane key="1" tab="权限变更">
|
||||
<a-tab-pane key="1" :tab="$t('acl.permissionChange')">
|
||||
<permisson-history-table
|
||||
v-if="isloaded"
|
||||
:allResourceTypes="allResourceTypes"
|
||||
@@ -17,7 +17,7 @@
|
||||
@resourceClear="resourceClear"
|
||||
></permisson-history-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="角色变更">
|
||||
<a-tab-pane key="2" :tab="$t('acl.roleChange')">
|
||||
<role-history-table
|
||||
v-if="isloaded"
|
||||
:allUsers="allUsers"
|
||||
@@ -26,7 +26,7 @@
|
||||
:allUsersMap="allUsersMap"
|
||||
></role-history-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3" tab="资源变更">
|
||||
<a-tab-pane key="3" :tab="$t('acl.resourceChange')">
|
||||
<resource-history-table
|
||||
v-if="isloaded"
|
||||
:allResources="allResources"
|
||||
@@ -41,7 +41,7 @@
|
||||
@resourceClear="resourceClear"
|
||||
></resource-history-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="4" tab="资源类型变更">
|
||||
<a-tab-pane key="4" :tab="$t('acl.resourceTypeChange')">
|
||||
<resource-type-history-table
|
||||
v-if="isloaded"
|
||||
:allResourceTypes="allResourceTypes"
|
||||
@@ -52,7 +52,7 @@
|
||||
:allResourceTypesMap="allResourceTypesMap"
|
||||
></resource-type-history-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="5" tab="触发器变更">
|
||||
<a-tab-pane key="5" :tab="$t('acl.triggerChange')">
|
||||
<trigger-history-table
|
||||
v-if="isloaded"
|
||||
:allTriggers="allTriggers"
|
||||
|
@@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<CustomDrawer @close="handleClose" width="500" :title="title" :visible="visible" :closable="false">
|
||||
<a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
|
||||
<a-form-item label="应用名称">
|
||||
<a-input v-decorator="['name', { rules: [{ required: true, message: '请输入应用名称' }] }]"> </a-input>
|
||||
<a-form-item :label="$t('acl.app')">
|
||||
<a-input v-decorator="['name', { rules: [{ required: true, message: $t('acl.appNameInput') }] }]"> </a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="描述">
|
||||
<a-input v-decorator="['description', { rules: [{ required: true, message: '请输入描述' }] }]"> </a-input>
|
||||
<a-form-item :label="$t('desc')">
|
||||
<a-input v-decorator="['description', { rules: [{ required: true, message: $t('acl.descInput') }] }]">
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="AppId">
|
||||
<a-input v-decorator="['app_id', { rules: [{ required: false }] }]" :disabled="mode === 'update'"> </a-input>
|
||||
@@ -19,8 +20,8 @@
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="handleClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">提交</a-button>
|
||||
<a-button @click="handleClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('submit') }}</a-button>
|
||||
</div>
|
||||
</CustomDrawer>
|
||||
</template>
|
||||
@@ -32,10 +33,14 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
title: '创建应用',
|
||||
mode: 'create',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return this.$t('acl.addApp')
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
@@ -43,7 +48,7 @@ export default {
|
||||
handleEdit(ele) {
|
||||
this.visible = true
|
||||
if (ele) {
|
||||
this.title = '修改应用'
|
||||
this.title = this.$t('updateApp')
|
||||
this.mode = 'update'
|
||||
console.log(ele)
|
||||
const { name, description } = ele
|
||||
@@ -55,7 +60,7 @@ export default {
|
||||
})
|
||||
} else {
|
||||
this.mode = 'create'
|
||||
this.title = '创建应用'
|
||||
this.title = this.$t('acl.addApp')
|
||||
}
|
||||
},
|
||||
handleClose() {
|
||||
@@ -69,11 +74,11 @@ export default {
|
||||
}
|
||||
if (values.id) {
|
||||
await updateApp(values.id, values).then((res) => {
|
||||
this.$message.success('修改成功!')
|
||||
this.$message.success(this.$t('updateSuccess'))
|
||||
})
|
||||
} else {
|
||||
await addApp(values).then((res) => {
|
||||
this.$message.success('创建成功!')
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
})
|
||||
}
|
||||
this.handleClose()
|
||||
|
@@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-row class="row" type="flex" justify="end">
|
||||
<a-col>
|
||||
<a-space align="end">
|
||||
<a-button class="left-button" size="small" :disabled="prevIsDisabled" @click="prevPage"><a-icon type="left" /></a-button>
|
||||
<a-button class="page-button" size="small">{{ currentPage }}</a-button>
|
||||
<a-button class="right-button" size="small" :disabled="nextIsDisabled" @click="nextPage"><a-icon type="right" /></a-button>
|
||||
<a-dropdown class="dropdown" size="small" placement="topCenter" :trigger="['click']" :disabled="dropdownIsDisabled">
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item v-for="(size,index) in pageSizes" :key="index" @click="handleItemClick(size)">
|
||||
{{ size }}条/页
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button size="small"> {{ pageSize }}条/页 <a-icon type="down" /> </a-button>
|
||||
</a-dropdown>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
currentPage: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dropdownIsDisabled: false,
|
||||
prevIsDisabled: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nextIsDisabled() {
|
||||
return this.isLoading || this.total < this.pageSize
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isLoading: {
|
||||
immediate: true,
|
||||
handler: function (val) {
|
||||
if (val === true) {
|
||||
this.dropdownIsDisabled = true
|
||||
this.prevIsDisabled = true
|
||||
} else {
|
||||
this.dropdownIsDisabled = false
|
||||
if (this.currentPage === 1) {
|
||||
this.prevIsDisabled = true
|
||||
} else {
|
||||
this.prevIsDisabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
currentPage: {
|
||||
immediate: true,
|
||||
handler: function (val) {
|
||||
if (val === 1) {
|
||||
this.prevIsDisabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleItemClick(size) {
|
||||
this.$emit('showSizeChange', size)
|
||||
},
|
||||
nextPage() {
|
||||
const pageNum = this.currentPage + 1
|
||||
this.$emit('change', pageNum)
|
||||
},
|
||||
prevPage() {
|
||||
const pageNum = this.currentPage - 1
|
||||
this.$emit('change', pageNum)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.row{
|
||||
margin-top: 5px;
|
||||
.left-button{
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
}
|
||||
.right-button{
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
}
|
||||
.page-button{
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<CustomDrawer
|
||||
:title="`权限汇总: ${user.nickname}`"
|
||||
:title="`${$t('acl.summaryPermissions')}: ${user.nickname}`"
|
||||
:visible="visible"
|
||||
placement="left"
|
||||
width="100%"
|
||||
@@ -24,7 +24,7 @@
|
||||
<vxe-table :max-height="`${windowHeight - 230}px`" :data="resources" ref="rTable">
|
||||
<vxe-column
|
||||
field="name"
|
||||
title="资源名"
|
||||
:title="$t('acl.resourceName')"
|
||||
width="30%"
|
||||
:filters="[{ data: '' }]"
|
||||
:filter-method="filterNameMethod"
|
||||
@@ -39,62 +39,17 @@
|
||||
v-model="option.data"
|
||||
@input="$panel.changeOption($event, !!option.data, option)"
|
||||
@keyup.enter="$panel.confirmFilter()"
|
||||
placeholder="按回车确认筛选"
|
||||
:placeholder="$t('acl.pressEnter')"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="permissions" title="权限列表" width="70%">
|
||||
<vxe-column field="permissions" :title="$t('acl.permissionList')" width="70%">
|
||||
<template #default="{row}">
|
||||
<a-tag color="cyan" v-for="(r, index) in row.permissions" :key="index">{{ r }}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<!-- <a-table
|
||||
:columns="tableColumns"
|
||||
:dataSource="resources"
|
||||
:rowKey="record=>record.id"
|
||||
:pagination="{ showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条记录` }"
|
||||
showPagination="auto"
|
||||
ref="rTable"
|
||||
size="middle">
|
||||
<div slot="filterDropdown" slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }" class="custom-filter-dropdown">
|
||||
<a-input
|
||||
v-ant-ref="c => searchInput = c"
|
||||
:placeholder="` ${column.title}`"
|
||||
:value="selectedKeys[0]"
|
||||
@change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
|
||||
@pressEnter="() => handleSearch(selectedKeys, confirm, column)"
|
||||
style="width: 188px; margin-bottom: 8px; display: block;"
|
||||
/>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="() => handleSearch(selectedKeys, confirm, column)"
|
||||
icon="search"
|
||||
size="small"
|
||||
style="width: 90px; margin-right: 8px"
|
||||
>搜索</a-button>
|
||||
<a-button
|
||||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
<template slot="nameSearchRender" slot-scope="text">
|
||||
<span v-if="columnSearchText.name">
|
||||
<template v-for="(fragment, i) in text.toString().split(new RegExp(`(?<=${columnSearchText.name})|(?=${columnSearchText.name})`, 'i'))">
|
||||
<mark v-if="fragment.toLowerCase() === columnSearchText.name.toLowerCase()" :key="i" class="highlight">{{ fragment }}</mark>
|
||||
<template v-else>{{ fragment }}</template>
|
||||
</template>
|
||||
</span>
|
||||
<template v-else>{{ text }}</template>
|
||||
</template>
|
||||
<template slot="permissions" slot-scope="record">
|
||||
<a-tag color="cyan" v-for="(r, index) in record" :key="index">{{ r }}</a-tag>
|
||||
</template>
|
||||
</a-table> -->
|
||||
</a-spin>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
@@ -122,33 +77,6 @@ export default {
|
||||
resourceTypes: [],
|
||||
resourceTypePerms: [],
|
||||
resources: [],
|
||||
// tableColumns: [
|
||||
// {
|
||||
// title: '资源名',
|
||||
// dataIndex: 'name',
|
||||
// sorter: false,
|
||||
// width: 150,
|
||||
// // scopedSlots: {
|
||||
// // customRender: 'nameSearchRender',
|
||||
// // filterDropdown: 'filterDropdown',
|
||||
// // filterIcon: 'filterIcon'
|
||||
// // },
|
||||
// // onFilter: (value, record) => record.name && record.name.toLowerCase().includes(value.toLowerCase()),
|
||||
// // onFilterDropdownVisibleChange: (visible) => {
|
||||
// // if (visible) {
|
||||
// // setTimeout(() => {
|
||||
// // this.searchInput.focus()
|
||||
// // }, 0)
|
||||
// // }
|
||||
// // }
|
||||
// },
|
||||
// {
|
||||
// title: '权限列表',
|
||||
// dataIndex: 'permissions',
|
||||
// width: 300,
|
||||
// scopedSlots: { customRender: 'permissions' },
|
||||
// },
|
||||
// ],
|
||||
columnSearchText: {
|
||||
name: '',
|
||||
},
|
||||
@@ -156,14 +84,14 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
windowHeight: state => state.windowHeight,
|
||||
windowHeight: (state) => state.windowHeight,
|
||||
}),
|
||||
displayApps() {
|
||||
const roles = this.$store.state.user.roles.permissions
|
||||
if (roles.includes('acl_admin')) {
|
||||
return this.apps
|
||||
}
|
||||
return this.apps.filter(item => {
|
||||
return this.apps.filter((item) => {
|
||||
if (roles.includes(`${item.name}_admin`)) {
|
||||
return true
|
||||
}
|
||||
@@ -192,7 +120,7 @@ export default {
|
||||
},
|
||||
async loadRoles(_appId) {
|
||||
const res = await searchRole({ app_id: _appId, page_size: 9999, is_all: true })
|
||||
this.roles = res.roles.filter(item => item.uid)
|
||||
this.roles = res.roles.filter((item) => item.uid)
|
||||
},
|
||||
async handleSwitchApp(appId) {
|
||||
this.currentAppId = appId
|
||||
@@ -218,7 +146,7 @@ export default {
|
||||
},
|
||||
async loadResource() {
|
||||
this.spinning = true
|
||||
const fil = this.roles.filter(role => role.uid === this.user.uid)
|
||||
const fil = this.roles.filter((role) => role.uid === this.user.uid)
|
||||
if (!fil[0]) {
|
||||
return
|
||||
}
|
||||
|
@@ -1,29 +1,33 @@
|
||||
<template>
|
||||
<CustomDrawer
|
||||
:closable="false"
|
||||
:title="drawerTitle"
|
||||
:title="$t('acl.addResourceType')"
|
||||
:visible="drawerVisible"
|
||||
@close="onClose"
|
||||
placement="right"
|
||||
width="30%"
|
||||
>
|
||||
<a-form :form="form" :layout="formLayout" @submit="handleSubmit">
|
||||
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="类型名">
|
||||
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" :label="$t('acl.typeName')">
|
||||
<a-input
|
||||
name="name"
|
||||
placeholder=""
|
||||
v-decorator="['name', { rules: [{ required: true, message: '请输入资源名' }] }]"
|
||||
v-decorator="['name', { rules: [{ required: true, message: $t('acl.resourceNameInput') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="描述">
|
||||
<a-textarea placeholder="请输入描述信息..." name="description" :rows="4" />
|
||||
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" :label="$t('desc')">
|
||||
<a-textarea :placeholder="$t('acl.descInput')" name="description" :rows="4" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="权限">
|
||||
<a-form-item
|
||||
:label-col="formItemLayout.labelCol"
|
||||
:wrapper-col="formItemLayout.wrapperCol"
|
||||
:label="$t('acl.permission')"
|
||||
>
|
||||
<div :style="{ borderBottom: '1px solid #E9E9E9' }">
|
||||
<a-checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll">
|
||||
全选
|
||||
{{ $t('checkAll') }}
|
||||
</a-checkbox>
|
||||
</div>
|
||||
<br />
|
||||
@@ -35,8 +39,8 @@
|
||||
</a-form-item>
|
||||
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">确定</a-button>
|
||||
<a-button @click="onClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
@@ -49,7 +53,6 @@ export default {
|
||||
name: 'ResourceForm',
|
||||
data() {
|
||||
return {
|
||||
drawerTitle: '新增资源类型',
|
||||
drawerVisible: false,
|
||||
formLayout: 'vertical',
|
||||
perms: ['1'],
|
||||
@@ -142,8 +145,8 @@ export default {
|
||||
})
|
||||
},
|
||||
updateResourceType(id, data) {
|
||||
updateResourceTypeById(id, data).then(res => {
|
||||
this.$message.success(`更新成功`)
|
||||
updateResourceTypeById(id, data).then((res) => {
|
||||
this.$message.success(this.$t('updateSuccess'))
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
})
|
||||
@@ -151,18 +154,12 @@ export default {
|
||||
},
|
||||
|
||||
createResourceType(data) {
|
||||
addResourceType(data).then(res => {
|
||||
this.$message.success(`添加成功`)
|
||||
addResourceType(data).then((res) => {
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
},
|
||||
|
||||
// requestFailed (err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// }
|
||||
},
|
||||
watch: {},
|
||||
props: {
|
||||
|
@@ -21,22 +21,22 @@
|
||||
:height="`${windowHeight - windowHeightMinus}px`"
|
||||
:scroll-y="{ enabled: false }"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.deleted_at || row.updated_at || row.created_at }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="row.operate_type === 'grant' ? 'green' : 'red'">{{
|
||||
operateTypeMap.get(row.operate_type)
|
||||
}}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="rid" title="用户"></vxe-column>
|
||||
<vxe-column field="resource_type_id" title="资源类型"></vxe-column>
|
||||
<vxe-column field="resources" title="资源">
|
||||
<vxe-column field="rid" :title="$t('user')"></vxe-column>
|
||||
<vxe-column field="resource_type_id" :title="$t('acl.resourceType')"></vxe-column>
|
||||
<vxe-column field="resources" :title="$t('acl.resource')">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.resource_ids.length > 0">
|
||||
<a-tooltip placement="top">
|
||||
@@ -55,14 +55,14 @@
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="权限">
|
||||
<vxe-column :title="$t('acl.permission')">
|
||||
<template #default="{ row }">
|
||||
<a-tag v-for="(perm, index) in row.permission_ids" :key="'perms_' + perm + index">
|
||||
{{ perm }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" width="100px" title="来源"></vxe-column>
|
||||
<vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from './pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from './searchForm.vue'
|
||||
import { searchPermissonHistory } from '@/modules/acl/api/history'
|
||||
import debounce from 'lodash/debounce'
|
||||
@@ -122,10 +122,6 @@ export default {
|
||||
loading: true,
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
tableData: [],
|
||||
operateTypeMap: new Map([
|
||||
['grant', '授权'],
|
||||
['revoke', '撤销'],
|
||||
]),
|
||||
queryParams: {
|
||||
page: 1,
|
||||
page_size: 50,
|
||||
@@ -135,45 +131,45 @@ export default {
|
||||
},
|
||||
permissionTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: '用户',
|
||||
alias: this.$t('user'),
|
||||
is_choice: true,
|
||||
name: 'rid',
|
||||
value_type: '2',
|
||||
choice_value: this.allRoles,
|
||||
},
|
||||
{
|
||||
alias: '资源类型',
|
||||
alias: this.$t('acl.resourceType'),
|
||||
is_choice: true,
|
||||
name: 'resource_type_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allResourceTypes,
|
||||
},
|
||||
{
|
||||
alias: '资源',
|
||||
alias: this.$t('acl.resource'),
|
||||
is_choice: true,
|
||||
name: 'resource_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allResources,
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [{ 授权: 'grant' }, { 撤销: 'revoke' }],
|
||||
choice_value: [{ [this.$t('grant')]: 'grant' }, { [this.$t('acl.cancel')]: 'revoke' }],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -198,6 +194,12 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['grant', this.$t('grant')],
|
||||
['revoke', this.$t('acl.cancel')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<CustomDrawer
|
||||
title="便捷授权"
|
||||
:title="$t('acl.convenient')"
|
||||
width="500px"
|
||||
:maskClosable="false"
|
||||
:closable="true"
|
||||
@@ -10,12 +10,12 @@
|
||||
<a-form :form="form">
|
||||
<a-form-item>
|
||||
<div slot="label" style="display: inline-block">
|
||||
<span>角色列表</span>
|
||||
<span>{{ $t('acl.roleList') }}</span>
|
||||
<a-divider type="vertical" />
|
||||
<a-switch
|
||||
style="display: inline-block"
|
||||
checked-children="用户"
|
||||
un-checked-children="虚拟"
|
||||
:checked-children="$t('user')"
|
||||
:un-checked-children="$t('acl.virtual')"
|
||||
@change="handleRoleTypeChange"
|
||||
v-model="roleType"
|
||||
/>
|
||||
@@ -23,37 +23,37 @@
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
size="small"
|
||||
v-decorator="['roleIdList', { rules: [{ required: true, message: '请选择角色名称' }] }]"
|
||||
v-decorator="['roleIdList', { rules: [{ required: true, message: $t('acl.role_placeholder2') }] }]"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择角色名称,可多选!"
|
||||
:placeholder="$t('acl.role_placeholder3')"
|
||||
>
|
||||
<el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="权限列表">
|
||||
<a-form-item :label="$t('acl.permissionList')">
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
size="small"
|
||||
name="permName"
|
||||
v-decorator="['permName', { rules: [{ required: true, message: '请选择权限' }] }]"
|
||||
v-decorator="['permName', { rules: [{ required: true, message: this.$t('acl.permission_placeholder') }] }]"
|
||||
multiple
|
||||
placeholder="请选择权限,可多选!"
|
||||
:placeholder="this.$t('acl.permission_placeholder')"
|
||||
>
|
||||
<el-option v-for="perm in allPerms" :key="perm.name" :value="perm.name" :label="perm.name"></el-option>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="资源名">
|
||||
<a-form-item :label="$t('acl.resourceName')">
|
||||
<a-textarea
|
||||
v-decorator="['resource_names', { rules: [{ required: true, message: '请输入资源名,换行分隔' }] }]"
|
||||
v-decorator="['resource_names', { rules: [{ required: true, message: $t('acl.resourceBatchTips') }] }]"
|
||||
:autoSize="{ minRows: 4 }"
|
||||
placeholder="请输入资源名,换行分隔"
|
||||
:placeholder="$t('acl.resourceBatchTips')"
|
||||
/>
|
||||
</a-form-item>
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="handleRevoke" type="danger" ghost>权限回收</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">授权</a-button>
|
||||
<a-button @click="handleRevoke" type="danger" ghost>{{ $t('acl.revoke') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('grant') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
@@ -98,12 +98,12 @@ export default {
|
||||
this.loadRoles(Number(target))
|
||||
},
|
||||
loadRoles(isUserRole) {
|
||||
searchRole({ page_size: 9999, app_id: this.$route.name.split('_')[0], user_role: isUserRole }).then(res => {
|
||||
searchRole({ page_size: 9999, app_id: this.$route.name.split('_')[0], user_role: isUserRole }).then((res) => {
|
||||
this.allRoles = res.roles
|
||||
})
|
||||
},
|
||||
loadPerm(resourceTypeId) {
|
||||
getResourceTypePerms(resourceTypeId).then(res => {
|
||||
getResourceTypePerms(resourceTypeId).then((res) => {
|
||||
this.allPerms = res
|
||||
})
|
||||
},
|
||||
@@ -111,13 +111,13 @@ export default {
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
console.log(values)
|
||||
values.roleIdList.forEach(roleId => {
|
||||
values.roleIdList.forEach((roleId) => {
|
||||
setBatchRoleResourceByResourceName(roleId, {
|
||||
resource_names: values.resource_names.split('\n'),
|
||||
perms: values.permName,
|
||||
resource_type_id: this.resource_type_id,
|
||||
}).then(res => {
|
||||
this.$message.success('授权成功')
|
||||
}).then((res) => {
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
this.form.resetFields()
|
||||
})
|
||||
})
|
||||
@@ -128,13 +128,13 @@ export default {
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
console.log(values)
|
||||
values.roleIdList.forEach(roleId => {
|
||||
values.roleIdList.forEach((roleId) => {
|
||||
setBatchRoleResourceRevokeByResourceName(roleId, {
|
||||
resource_names: values.resource_names.split('\n'),
|
||||
perms: values.permName,
|
||||
resource_type_id: this.resource_type_id,
|
||||
}).then(res => {
|
||||
this.$message.success('权限回收成功')
|
||||
}).then((res) => {
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
this.form.resetFields()
|
||||
})
|
||||
})
|
||||
|
@@ -8,27 +8,27 @@
|
||||
width="30%"
|
||||
>
|
||||
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
|
||||
<a-form-item label="资源名">
|
||||
<a-form-item :label="$t('acl.resourceName')">
|
||||
<a-input
|
||||
name="name"
|
||||
placeholder=""
|
||||
v-decorator="['name', { rules: [{ required: true, message: '请输入资源名' }] }]"
|
||||
v-decorator="['name', { rules: [{ required: true, message: $t('acl.resourceNameInput') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="资源类型">
|
||||
<a-form-item :label="$t('acl.resourceType')">
|
||||
<a-select v-model="selectedTypeId">
|
||||
<a-select-option v-for="type in allTypes" :key="type.id">{{ type.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="是否组">
|
||||
<a-form-item :label="$t('acl.isGroup')">
|
||||
<a-radio-group v-model="isGroup">
|
||||
<a-radio :value="true">
|
||||
是
|
||||
{{ $t('yes') }}
|
||||
</a-radio>
|
||||
<a-radio :value="false">
|
||||
否
|
||||
{{ $t('no') }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
@@ -36,8 +36,8 @@
|
||||
<a-input name="id" type="hidden" v-decorator="['id', { rules: [] }]" />
|
||||
</a-form-item>
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">确定</a-button>
|
||||
<a-button @click="onClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
@@ -52,7 +52,6 @@ export default {
|
||||
name: 'ResourceForm',
|
||||
data() {
|
||||
return {
|
||||
drawerTitle: '新增资源',
|
||||
drawerVisible: false,
|
||||
allTypes: [],
|
||||
isGroup: false,
|
||||
@@ -68,7 +67,11 @@ export default {
|
||||
this.getAllResourceTypes()
|
||||
},
|
||||
|
||||
computed: {},
|
||||
computed: {
|
||||
drawerTitle() {
|
||||
return this.$t('acl.addResource')
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
getAllResourceTypes() {
|
||||
@@ -95,7 +98,7 @@ export default {
|
||||
values.type_id = this.selectedTypeId
|
||||
values.app_id = this.$route.name.split('_')[0]
|
||||
if (values.id) {
|
||||
this.$message.error('错误提示')
|
||||
this.$message.error(this.$t('acl.errorTips'))
|
||||
} else {
|
||||
this.createResource(values)
|
||||
}
|
||||
@@ -105,23 +108,17 @@ export default {
|
||||
createResource(data) {
|
||||
if (!this.isGroup) {
|
||||
addResource(data).then((res) => {
|
||||
this.$message.success(`添加成功`)
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.onClose()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
} else {
|
||||
addResourceGroup(data).then((res) => {
|
||||
this.$message.success(`添加成功`)
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.onClose()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
}
|
||||
},
|
||||
|
||||
// requestFailed(err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// },
|
||||
},
|
||||
watch: {
|
||||
'$route.name': function(newValue, oldValue) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-modal v-model="visible" :title="`组成员:${editRecord.name}`" :width="800" :footer="null">
|
||||
<a-modal v-model="visible" :title="`${$t('acl.groupMember')}${editRecord.name}`" :width="800" :footer="null">
|
||||
<div :style="{ maxHeight: '500px', overflow: 'auto' }">
|
||||
<a-tag :style="{ marginBottom: '5px' }" v-for="mem in members" :key="mem.name">
|
||||
{{ mem.name }}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-modal v-model="visible" :title="`成员管理:${editRecord.name}`" @ok="handleSubmit" :width="690">
|
||||
<a-modal v-model="visible" :title="`${$t('acl.memberManage')}${editRecord.name}`" @ok="handleSubmit" :width="690">
|
||||
<!-- <CustomTransfer
|
||||
ref="customTransfer"
|
||||
:show-search="true"
|
||||
@@ -26,7 +26,7 @@
|
||||
@selectChange="selectChange"
|
||||
:selectedKeys="selectedKeys"
|
||||
>
|
||||
<span slot="notFoundContent">暂无数据</span>
|
||||
<span slot="notFoundContent">{{ $t('noData') }}</span>
|
||||
<template slot="children" slot-scope="{ props: { direction, filteredItems } }">
|
||||
<div class="ant-transfer-list-content" v-if="direction === 'right'">
|
||||
<div
|
||||
@@ -104,7 +104,7 @@ export default {
|
||||
})
|
||||
updateResourceGroup(this.editRecord['id'], { items: items.join(',') }).then(() => {
|
||||
this.visible = false
|
||||
this.$message.success('更新成功!')
|
||||
this.$message.success(this.$t('updateSuccess'))
|
||||
})
|
||||
// .catch(err => this.$httpError(err))
|
||||
},
|
||||
|
@@ -4,7 +4,7 @@
|
||||
ref="child"
|
||||
:attrList="resourceTableAttrList"
|
||||
:hasSwitch="true"
|
||||
switchValue="组"
|
||||
:switchValue="$t('acl.group2')"
|
||||
@onSwitchChange="onSwitchChange"
|
||||
@search="handleSearch"
|
||||
@searchFormReset="searchFormReset"
|
||||
@@ -22,30 +22,30 @@
|
||||
resizable
|
||||
:height="`${windowHeight - 310}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="handleTagColor(row.operate_type)">
|
||||
{{ operateTypeMap.get(row.operate_type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="link_id" title="资源名">
|
||||
<vxe-column field="link_id" :title="$t('acl.resourceName')">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.current.name || row.origin.name }}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述">
|
||||
<vxe-column :title="$t('desc')">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.description }}
|
||||
</p>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" width="100px" title="来源"></vxe-column>
|
||||
<vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from './pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from './searchForm.vue'
|
||||
import { searchResourceHistory } from '@/modules/acl/api/history'
|
||||
export default {
|
||||
@@ -99,40 +99,6 @@ export default {
|
||||
checked: false,
|
||||
tableData: [],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
resourceTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
|
||||
},
|
||||
{
|
||||
alias: '资源名',
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allResources,
|
||||
},
|
||||
],
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['update', '修改'],
|
||||
['delete', '删除'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['update', 'orange'],
|
||||
@@ -146,6 +112,39 @@ export default {
|
||||
start: '',
|
||||
end: '',
|
||||
},
|
||||
resourceTableAttrList: [
|
||||
{
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ [this.$t('create')]: 'create' },
|
||||
{ [this.$t('update')]: 'update' },
|
||||
{ [this.$t('delete')]: 'delete' },
|
||||
],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.resourceName'),
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allResources,
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
@@ -170,6 +169,13 @@ export default {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
])
|
||||
},
|
||||
tableDataLength() {
|
||||
return this.tableData.length
|
||||
},
|
||||
@@ -280,7 +286,7 @@ export default {
|
||||
switch (operate_type) {
|
||||
// create
|
||||
case 'create': {
|
||||
item.description = `新建资源:${item.current.name}`
|
||||
item.description = `${this.$t('acl.newResource')}${item.current.name}`
|
||||
break
|
||||
}
|
||||
case 'update': {
|
||||
@@ -290,9 +296,9 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null) {
|
||||
item.description += ` 【 ${key} : 改为 ${newVal} 】 `
|
||||
item.description += ` 【 ${key} : -> ${newVal} 】 `
|
||||
} else {
|
||||
item.description += ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 `
|
||||
item.description += ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,18 +306,18 @@ export default {
|
||||
const currentResource_ids = item.currentResource_ids
|
||||
if (!_.isEqual(originResource_ids, currentResource_ids)) {
|
||||
if (originResource_ids.length === 0) {
|
||||
const str = ` 【 resource_ids : 新增 ${currentResource_ids} 】 `
|
||||
const str = ` 【 resource_ids : ${this.$t('new')} ${currentResource_ids} 】 `
|
||||
item.description += str
|
||||
} else {
|
||||
const str = ` 【 resource_ids : 由 ${originResource_ids} 改为 ${currentResource_ids} 】 `
|
||||
const str = ` 【 resource_ids : ${originResource_ids} -> ${currentResource_ids} 】 `
|
||||
item.description += str
|
||||
}
|
||||
}
|
||||
if (!item.description) item.description = '没有修改'
|
||||
if (!item.description) item.description = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
item.description = `删除资源:${item.origin.name}`
|
||||
item.description = `${this.$t('acl.deleteResource')}${item.origin.name}`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@
|
||||
>
|
||||
<vxe-column
|
||||
field="name"
|
||||
title="角色名"
|
||||
:title="$t('acl.role')"
|
||||
width="20%"
|
||||
:filters="[{ data: '' }]"
|
||||
:filter-method="filterNameMethod"
|
||||
@@ -32,19 +32,19 @@
|
||||
v-model="option.data"
|
||||
@input="$panel.changeOption($event, !!option.data, option)"
|
||||
@keyup.enter="$panel.confirmFilter()"
|
||||
placeholder="按回车确认筛选"
|
||||
:placeholder="$t('acl.pressEnter')"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="users" title="下属用户" width="35%">
|
||||
<vxe-column field="users" :title="$t('acl.subordinateUsers')" width="35%">
|
||||
<template #default="{row}">
|
||||
<a-tag color="green" v-for="user in row.users" :key="user.nickname">
|
||||
{{ user.nickname }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="perms" title="权限列表" width="35%">
|
||||
<vxe-column field="perms" :title="$t('acl.permissionList')" width="35%">
|
||||
<template #default="{row}">
|
||||
<a-tag
|
||||
closable
|
||||
@@ -57,43 +57,18 @@
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="operate" title="批量操作">
|
||||
<vxe-column field="operate" :title="$t('batchOperate')">
|
||||
<template #default="{row}">
|
||||
<a-button size="small" type="danger" @click="handleClearAll(row)">
|
||||
清空
|
||||
{{ $t('clear') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template slot="empty">
|
||||
<img :src="require(`@/assets/data_empty.png`)" />
|
||||
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">暂无数据</p>
|
||||
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">{{ $t('noData') }}</p>
|
||||
</template>
|
||||
</vxe-table>
|
||||
<!-- <a-table
|
||||
:columns="columns"
|
||||
:dataSource="resPerms"
|
||||
:rowKey="record => record.name"
|
||||
:pagination="{ showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条记录` }"
|
||||
showPagination="auto"
|
||||
ref="rTable"
|
||||
size="middle"
|
||||
>
|
||||
<div slot="perms" slot-scope="text">
|
||||
<a-tag closable color="cyan" v-for="perm in text" :key="perm.name" @close="deletePerm(perm.rid, perm.name)">
|
||||
{{ perm.name }}
|
||||
</a-tag>
|
||||
</div>
|
||||
<div slot="users" slot-scope="text">
|
||||
<a-tag color="green" v-for="user in text" :key="user.nickname">
|
||||
{{ user.nickname }}
|
||||
</a-tag>
|
||||
</div>
|
||||
<div slot="operate" slot-scope="text">
|
||||
<a-button size="small" type="danger" @click="handleClearAll(text)">
|
||||
清空
|
||||
</a-button>
|
||||
</div>
|
||||
</a-table> -->
|
||||
</CustomDrawer>
|
||||
</template>
|
||||
<script>
|
||||
@@ -112,40 +87,11 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
isGroup: false,
|
||||
drawerTitle: '权限列表',
|
||||
drawerVisible: false,
|
||||
record: null,
|
||||
allPerms: [],
|
||||
resPerms: [],
|
||||
roleID: null,
|
||||
// columns: [
|
||||
// {
|
||||
// title: '角色名',
|
||||
// dataIndex: 'name',
|
||||
// sorter: false,
|
||||
// width: 50,
|
||||
// },
|
||||
// {
|
||||
// title: '下属用户',
|
||||
// dataIndex: 'users',
|
||||
// sorter: false,
|
||||
// width: 150,
|
||||
// scopedSlots: { customRender: 'users' },
|
||||
// },
|
||||
// {
|
||||
// title: '权限列表',
|
||||
// dataIndex: 'perms',
|
||||
// sorter: false,
|
||||
// width: 150,
|
||||
// scopedSlots: { customRender: 'perms' },
|
||||
// },
|
||||
// {
|
||||
// title: '批量操作',
|
||||
// sorter: false,
|
||||
// width: 50,
|
||||
// scopedSlots: { customRender: 'operate' },
|
||||
// },
|
||||
// ],
|
||||
childrenDrawer: false,
|
||||
allRoles: [],
|
||||
}
|
||||
@@ -154,6 +100,9 @@ export default {
|
||||
...mapState({
|
||||
windowHeight: (state) => state.windowHeight,
|
||||
}),
|
||||
drawerTitle() {
|
||||
return this.$t('acl.permissionList')
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
this.form = this.$form.createForm(this)
|
||||
@@ -175,7 +124,7 @@ export default {
|
||||
perms: [],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
}).then((res) => {
|
||||
this.$message.success('删除成功')
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
this.$nextTick(() => {
|
||||
this.getResPerms(this.record.id)
|
||||
})
|
||||
@@ -185,7 +134,7 @@ export default {
|
||||
perms: [],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
}).then((res) => {
|
||||
this.$message.success('删除成功')
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
// for (let i = 0; i < this.resPerms.length; i++) {
|
||||
// if (this.resPerms[i].name === text.name) {
|
||||
// this.resPerms[i].perms = []
|
||||
@@ -227,7 +176,7 @@ export default {
|
||||
perms: [permName],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
}).then((res) => {
|
||||
this.$message.success(`删除成功`)
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
} else {
|
||||
@@ -235,18 +184,13 @@ export default {
|
||||
perms: [permName],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
}).then((res) => {
|
||||
this.$message.success(`删除成功`)
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
}
|
||||
},
|
||||
handleCancel(e) {
|
||||
this.drawerVisible = false
|
||||
},
|
||||
// requestFailed(err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// },
|
||||
filterNameMethod({ option, row }) {
|
||||
return row.name.toLowerCase().includes(option.data.toLowerCase())
|
||||
},
|
||||
|
@@ -3,42 +3,42 @@
|
||||
<a-form :form="form">
|
||||
<a-form-item>
|
||||
<div slot="label" style="display: inline-block">
|
||||
<span>角色列表</span>
|
||||
<span>{{ $t('acl.roleList') }}</span>
|
||||
<a-divider type="vertical" />
|
||||
<a-switch
|
||||
style="display: inline-block"
|
||||
checked-children="用户"
|
||||
un-checked-children="虚拟"
|
||||
:checked-children="$t('user')"
|
||||
:un-checked-children="$t('acl.virtual')"
|
||||
@change="handleRoleTypeChange"
|
||||
/>
|
||||
</div>
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
size="small"
|
||||
v-decorator="['roleIdList', { rules: [{ required: true, message: '请选择角色名称' }] }]"
|
||||
v-decorator="['roleIdList', { rules: [{ required: true, message: $t('acl.role_placeholder2') }] }]"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择角色名称,可多选!"
|
||||
:placeholder="$t('acl.role_placeholder3')"
|
||||
>
|
||||
<el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="权限列表">
|
||||
<a-form-item :label="$t('acl.permissionList')">
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
size="small"
|
||||
name="permName"
|
||||
v-decorator="['permName', { rules: [{ required: true, message: '请选择权限' }] }]"
|
||||
v-decorator="['permName', { rules: [{ required: true, message: $t('acl.permission_placeholder') }] }]"
|
||||
multiple
|
||||
placeholder="请选择权限,可多选!"
|
||||
:placeholder="$t('acl.permission_placeholder') "
|
||||
>
|
||||
<el-option v-for="perm in allPerms" :key="perm.name" :value="perm.name" :label="perm.name"></el-option>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="closeForm">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" :loading="loading">确定</a-button>
|
||||
<a-button @click="closeForm">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" :loading="loading">{{ $t('confirm') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
@@ -117,16 +117,12 @@ export default {
|
||||
this.type = type
|
||||
if (Array.isArray(record)) {
|
||||
this.loadPerm(record[0]['resource_type_id'])
|
||||
this.title = `${type === 'grant' ? '批量授权' : '批量权限回收'}`
|
||||
this.title = `${type === 'grant' ? this.$t('acl.batchGrant') : this.$t('acl.batchRevoke')}`
|
||||
} else {
|
||||
this.title = `添加授权:${record.name}`
|
||||
this.title = `${this.$t('acl.editPerm')}${record.name}`
|
||||
this.loadPerm(record['resource_type_id'])
|
||||
}
|
||||
},
|
||||
// requestFailed(err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// },
|
||||
handleSubmit(e) {
|
||||
e.preventDefault()
|
||||
this.form.validateFields((err, values) => {
|
||||
@@ -136,16 +132,10 @@ export default {
|
||||
this.loading = true
|
||||
if (!this.isGroup) {
|
||||
if (Array.isArray(this.instance)) {
|
||||
// const promises = this.instance.map(item => {
|
||||
// return setRoleResourcePerm(roleId, item.id, params)
|
||||
// })
|
||||
// Promise.all(promises).then(() => {
|
||||
// this.$message.success('添加授权成功')
|
||||
// })
|
||||
if (this.type === 'grant') {
|
||||
setBatchRoleResourcePerm(roleId, { ...params, resource_ids: this.instance.map((a) => a.id) })
|
||||
.then((res) => {
|
||||
this.$message.success('添加授权成功')
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@@ -153,7 +143,7 @@ export default {
|
||||
} else {
|
||||
setBatchRoleResourceRevoke(roleId, { ...params, resource_ids: this.instance.map((a) => a.id) })
|
||||
.then((res) => {
|
||||
this.$message.success('批量权限回收成功')
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@@ -162,7 +152,7 @@ export default {
|
||||
} else {
|
||||
setRoleResourcePerm(roleId, this.instance.id, params)
|
||||
.then((res) => {
|
||||
this.$message.success('添加授权成功')
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@@ -170,16 +160,10 @@ export default {
|
||||
}
|
||||
} else {
|
||||
if (Array.isArray(this.instance)) {
|
||||
// const promises = this.instance.map(item => {
|
||||
// return setRoleResourceGroupPerm(roleId, item.id, params)
|
||||
// })
|
||||
// Promise.all(promises).then(() => {
|
||||
// this.$message.success('添加授权成功')
|
||||
// })
|
||||
if (this.type === 'grant') {
|
||||
setBatchRoleResourceGroupPerm(roleId, { ...params, group_ids: this.instance.map((a) => a.id) })
|
||||
.then((res) => {
|
||||
this.$message.success('添加授权成功')
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@@ -190,7 +174,7 @@ export default {
|
||||
group_ids: this.instance.map((a) => a.id),
|
||||
})
|
||||
.then((res) => {
|
||||
this.$message.success('批量权限回收成功')
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@@ -199,7 +183,7 @@ export default {
|
||||
} else {
|
||||
setRoleResourceGroupPerm(roleId, this.instance.id, params)
|
||||
.then((res) => {
|
||||
this.$message.success('添加授权成功')
|
||||
this.$message.success(this.$t('operateSuccess'))
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
|
@@ -1,32 +1,32 @@
|
||||
<template>
|
||||
<CustomDrawer
|
||||
:closable="false"
|
||||
:title="drawerTitle"
|
||||
:title="$t('acl.addResourceType')"
|
||||
:visible="drawerVisible"
|
||||
@close="onClose"
|
||||
placement="right"
|
||||
width="500px"
|
||||
>
|
||||
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
|
||||
<a-form-item label="类型名">
|
||||
<a-form-item :label="$t('acl.typeName')">
|
||||
<a-input
|
||||
name="name"
|
||||
placeholder="类型名称"
|
||||
v-decorator="['name', { rules: [{ required: true, message: '请输入类型名' }] }]"
|
||||
:placeholder="$t('acl.typeName')"
|
||||
v-decorator="['name', { rules: [{ required: true, message: $t('acl.typeNameInput') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="描述">
|
||||
<a-form-item :label="$t('desc')">
|
||||
<a-textarea
|
||||
placeholder="请输入描述信息..."
|
||||
:placeholder="$t('acl.descInput')"
|
||||
name="description"
|
||||
:rows="4"
|
||||
v-decorator="['description', { rules: [] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="权限">
|
||||
<a-select mode="tags" v-model="perms" style="width: 100%" placeholder="请输入权限名..."> </a-select>
|
||||
<a-form-item :label="$t('acl.permission')">
|
||||
<a-select mode="tags" v-model="perms" style="width: 100%" :placeholder="$t('acl.permInput')"> </a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
@@ -34,8 +34,8 @@
|
||||
</a-form-item>
|
||||
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">确定</a-button>
|
||||
<a-button @click="onClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
@@ -48,7 +48,6 @@ export default {
|
||||
name: 'ResourceForm',
|
||||
data() {
|
||||
return {
|
||||
drawerTitle: '新增资源类型',
|
||||
drawerVisible: false,
|
||||
perms: [],
|
||||
}
|
||||
@@ -104,7 +103,7 @@ export default {
|
||||
},
|
||||
updateResourceType(id, data) {
|
||||
updateResourceTypeById(id, data).then((res) => {
|
||||
this.$message.success(`更新成功`)
|
||||
this.$message.success(this.$t('updateSuccess'))
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
})
|
||||
@@ -113,17 +112,11 @@ export default {
|
||||
|
||||
createResourceType(data) {
|
||||
addResourceType(data).then((res) => {
|
||||
this.$message.success(`添加成功`)
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
},
|
||||
|
||||
// requestFailed (err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// }
|
||||
},
|
||||
watch: {},
|
||||
props: {
|
||||
|
@@ -16,30 +16,30 @@
|
||||
:loading="loading"
|
||||
:height="`${windowHeight - 310}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="handleTagColor(row.operate_type)">
|
||||
{{ operateTypeMap.get(row.operate_type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="link_id" title="资源类型名">
|
||||
<vxe-column field="link_id" :title="$t('acl.resourceTypeName')">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.current.name || row.origin.name }}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述">
|
||||
<vxe-column :title="$t('desc')">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.changeDescription }}
|
||||
</p>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" width="100px" title="来源"></vxe-column>
|
||||
<vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from './pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from './searchForm.vue'
|
||||
import { searchResourceHistory } from '@/modules/acl/api/history'
|
||||
export default {
|
||||
@@ -93,40 +93,6 @@ export default {
|
||||
checked: false,
|
||||
tableData: [],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
resourceTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
|
||||
},
|
||||
{
|
||||
alias: '资源类型',
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allResourceTypes,
|
||||
},
|
||||
],
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['update', '修改'],
|
||||
['delete', '删除'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['update', 'orange'],
|
||||
@@ -155,12 +121,50 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableDataLength() {
|
||||
return this.tableData.length
|
||||
},
|
||||
resourceTableAttrList() {
|
||||
return [
|
||||
{
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [{ [this.$t('create')]: 'create' }, { [this.$t('update')]: 'update' }, { [this.$t('delete')]: 'delete' }],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.resourceType'),
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allResourceTypes,
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async getTable(queryParams) {
|
||||
@@ -236,7 +240,9 @@ export default {
|
||||
switch (operate_type) {
|
||||
// create
|
||||
case 'create': {
|
||||
item.changeDescription = `新增资源类型:${item.current.name}\n描述:${item.current.description}\n权限:${item.extra.permission_ids.current}`
|
||||
item.changeDescription = `${this.$t('acl.addResourceType')}:${item.current.name}\n${this.$t('desc')}:${
|
||||
item.current.description
|
||||
}\n${this.$t('acl.permission')}: ${item.extra.permission_ids.current}`
|
||||
break
|
||||
}
|
||||
case 'update': {
|
||||
@@ -246,10 +252,10 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null || oldVal === '') {
|
||||
const str = ` 【 ${key} : 改为 ${newVal} 】 \n`
|
||||
const str = ` 【 ${key} : -> ${newVal} 】 \n`
|
||||
item.changeDescription += str
|
||||
} else {
|
||||
const str = ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 \n`
|
||||
const str = ` 【 ${key} : ${oldVal} -> ${newVal} 】 \n`
|
||||
item.changeDescription += str
|
||||
}
|
||||
}
|
||||
@@ -257,13 +263,13 @@ export default {
|
||||
const currentPerms = item.extra.permission_ids.current
|
||||
const originPerms = item.extra.permission_ids.origin
|
||||
if (!_.isEqual(currentPerms, originPerms)) {
|
||||
item.changeDescription += ` 【 permission_ids : 由 ${originPerms} 改为 ${currentPerms} 】 `
|
||||
item.changeDescription += ` 【 permission_ids : ${originPerms} -> ${currentPerms} 】 `
|
||||
}
|
||||
if (!item.changeDescription) item.changeDescription = '没有修改'
|
||||
if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
item.changeDescription = `删除资源类型:${item.origin.name}\n描述:${item.origin.description}\n权限:${item.extra.permission_ids.origin}`
|
||||
item.changeDescription = `${this.$t('acl.deleteResourceType')}${item.origin.name}\n${this.$t('desc')}: ${item.origin.description}\n${this.$t('acl.permission')}: ${item.extra.permission_ids.origin}`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -2,17 +2,17 @@
|
||||
<CustomDrawer
|
||||
width="800px"
|
||||
placement="left"
|
||||
title="资源列表"
|
||||
:title="$t('acl.resourceList')"
|
||||
@close="handleCancel"
|
||||
:visible="visible"
|
||||
:hasFooter="false"
|
||||
>
|
||||
<a-form-item label="资源类型" :label-col="{ span: 2 }" :wrapper-col="{ span: 14 }">
|
||||
<a-form-item :label="$t('acl.resourceType')" :label-col="{ span: 4 }" :wrapper-col="{ span: 14 }">
|
||||
<a-select v-model="typeSelected" style="width:100%" @change="refresh">
|
||||
<a-select-option v-for="type in resourceTypes" :value="type.id" :key="type.id">{{ type.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<vxe-table
|
||||
<ops-table
|
||||
size="mini"
|
||||
stripe
|
||||
class="ops-stripe-table"
|
||||
@@ -22,7 +22,7 @@
|
||||
>
|
||||
<vxe-column
|
||||
field="name"
|
||||
title="资源名"
|
||||
:title="$t('acl.resourceName')"
|
||||
width="30%"
|
||||
:filters="[{ data: '' }]"
|
||||
:filter-method="filterNameMethod"
|
||||
@@ -30,7 +30,7 @@
|
||||
>
|
||||
<template #header="{ column }">
|
||||
<span>{{ column.title }}</span>
|
||||
<a-tooltip title="复制资源名">
|
||||
<a-tooltip :title="$t('acl.copyResource')">
|
||||
<a-icon @click="copyResourceName" class="resource-user-form-copy" theme="filled" type="copy" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
@@ -43,84 +43,17 @@
|
||||
v-model="option.data"
|
||||
@input="$panel.changeOption($event, !!option.data, option)"
|
||||
@keyup.enter="$panel.confirmFilter()"
|
||||
placeholder="按回车确认筛选"
|
||||
:placeholder="$t('acl.pressEnter')"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="permissions" title="权限列表" width="70%">
|
||||
<vxe-column field="permissions" :title="$t('acl.permissionList')" width="70%">
|
||||
<template #default="{row}">
|
||||
<a-tag color="cyan" v-for="(r, index) in row.permissions" :key="index">{{ r }}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template slot="empty">
|
||||
<img :src="require(`@/assets/data_empty.png`)" />
|
||||
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">暂无数据</p>
|
||||
</template>
|
||||
</vxe-table>
|
||||
<!-- <a-table
|
||||
:columns="columns"
|
||||
:dataSource="records"
|
||||
:rowKey="record => record.id"
|
||||
:pagination="false"
|
||||
ref="rTable"
|
||||
size="middle"
|
||||
:scroll="{ y: 300 }"
|
||||
> -->
|
||||
<!-- <div slot="filterDropdown" slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }" class="custom-filter-dropdown">
|
||||
<a-input
|
||||
v-ant-ref="c => searchInput = c"
|
||||
:placeholder="` ${column.title}`"
|
||||
:value="selectedKeys[0]"
|
||||
@change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
|
||||
@pressEnter="() => handleSearch(selectedKeys, confirm, column)"
|
||||
style="width: 188px; margin-bottom: 8px; display: block;"
|
||||
/>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="() => handleSearch(selectedKeys, confirm, column)"
|
||||
icon="search"
|
||||
size="small"
|
||||
style="width: 90px; margin-right: 8px"
|
||||
>搜索</a-button>
|
||||
<a-button
|
||||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
<template slot="nameSearchRender" slot-scope="text">
|
||||
<span v-if="columnSearchText.name">
|
||||
<template v-for="(fragment, i) in text.toString().split(new RegExp(`(?<=${columnSearchText.name})|(?=${columnSearchText.name})`, 'i'))">
|
||||
<mark v-if="fragment.toLowerCase() === columnSearchText.name.toLowerCase()" :key="i" class="highlight">{{ fragment }}</mark>
|
||||
<template v-else>{{ fragment }}</template>
|
||||
</template>
|
||||
</span>
|
||||
<template v-else>{{ text }}</template>
|
||||
</template> -->
|
||||
<!-- <template slot="permissions" slot-scope="record">
|
||||
<a-tag color="cyan" v-for="(r, index) in record" :key="index">{{ r }}</a-tag>
|
||||
</template>
|
||||
</a-table> -->
|
||||
<!-- <div
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
borderTop: '1px solid #e9e9e9',
|
||||
padding: '10px 16px',
|
||||
background: '#fff',
|
||||
textAlign: 'right',
|
||||
}"
|
||||
>
|
||||
<a-button :style="{marginRight: '8px'}" @click="handleCancel">
|
||||
取消
|
||||
</a-button>
|
||||
<a-button @click="handleOk" type="primary">确定</a-button>
|
||||
</div> -->
|
||||
</ops-table>
|
||||
</CustomDrawer>
|
||||
</template>
|
||||
<script>
|
||||
@@ -141,38 +74,11 @@ export default {
|
||||
name: '',
|
||||
},
|
||||
filterName: '',
|
||||
// columns: [
|
||||
// {
|
||||
// title: '资源名',
|
||||
// field: 'name',
|
||||
// sorter: false,
|
||||
// width: '30%',
|
||||
// // scopedSlots: {
|
||||
// // customRender: 'nameSearchRender',
|
||||
// // filterDropdown: 'filterDropdown',
|
||||
// // filterIcon: 'filterIcon'
|
||||
// // },
|
||||
// // onFilter: (value, record) => record.name && record.name.toLowerCase().includes(value.toLowerCase()),
|
||||
// // onFilterDropdownVisibleChange: (visible) => {
|
||||
// // if (visible) {
|
||||
// // setTimeout(() => {
|
||||
// // this.searchInput.focus()
|
||||
// // }, 0)
|
||||
// // }
|
||||
// // }
|
||||
// },
|
||||
// {
|
||||
// title: '权限列表',
|
||||
// field: 'permissions',
|
||||
// width: '70%',
|
||||
// slots: { default: 'permissions_default' },
|
||||
// },
|
||||
// ],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
windowHeight: state => state.windowHeight,
|
||||
windowHeight: (state) => state.windowHeight,
|
||||
}),
|
||||
},
|
||||
mounted() {
|
||||
@@ -184,18 +90,10 @@ export default {
|
||||
this.rid = record.id
|
||||
this.refresh()
|
||||
},
|
||||
// handleSearch(selectedKeys, confirm, column) {
|
||||
// confirm()
|
||||
// this.columnSearchText[column.dataIndex] = selectedKeys[0]
|
||||
// },
|
||||
// handleReset(clearFilters, column) {
|
||||
// clearFilters()
|
||||
// this.columnSearchText[column.dataIndex] = ''
|
||||
// },
|
||||
loadResourceTypes() {
|
||||
this.resourceTypes = []
|
||||
const appId = this.$route.name.split('_')[0]
|
||||
searchResourceType({ app_id: appId }).then(res => {
|
||||
searchResourceType({ app_id: appId }).then((res) => {
|
||||
this.resourceTypes = res.groups
|
||||
if (res.groups && res.groups.length > 0) {
|
||||
this.typeSelected = res.groups[0].id
|
||||
@@ -204,7 +102,6 @@ export default {
|
||||
this.typeSelected = null
|
||||
}
|
||||
})
|
||||
// .catch(err => this.$httpError(err))
|
||||
},
|
||||
handleOk() {
|
||||
this.visible = false
|
||||
@@ -214,10 +111,9 @@ export default {
|
||||
searchPermResourceByRoleId(this.rid, {
|
||||
resource_type_id: this.typeSelected,
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
}).then(res => {
|
||||
}).then((res) => {
|
||||
this.records = res.resources
|
||||
})
|
||||
// .catch(err=>this.$httpError(err))
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
@@ -233,12 +129,12 @@ export default {
|
||||
},
|
||||
copyResourceName() {
|
||||
const val = this.records
|
||||
.filter(item => item.name.toLowerCase().includes(this.filterName.toLowerCase()))
|
||||
.map(item => item.name)
|
||||
.filter((item) => item.name.toLowerCase().includes(this.filterName.toLowerCase()))
|
||||
.map((item) => item.name)
|
||||
.join('\n')
|
||||
|
||||
this.copy(val, () => {
|
||||
this.$message.success('复制成功')
|
||||
this.$message.success(this.$t('copySuccess'))
|
||||
})
|
||||
},
|
||||
copy(value, cb) {
|
||||
|
@@ -8,40 +8,29 @@
|
||||
width="500px"
|
||||
>
|
||||
<a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }" @submit="handleSubmit">
|
||||
<a-form-item label="角色名">
|
||||
<a-form-item :label="$t('acl.role')">
|
||||
<a-input
|
||||
name="name"
|
||||
placeholder="角色名"
|
||||
v-decorator="['name', { rules: [{ required: true, message: '请输入角色名' }] }]"
|
||||
:placeholder="$t('acl.role_placeholder1')"
|
||||
v-decorator="['name', { rules: [{ required: true, message: $t('acl.role_placeholder1') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="$route.name.split('_')[0] !== 'acl'" label="密码">
|
||||
<a-input name="password" placeholder="密码" v-decorator="['password', { rules: [{ required: false }] }]" />
|
||||
<a-form-item v-if="$route.name.split('_')[0] !== 'acl'" :label="$t('acl.password')">
|
||||
<a-input name="password" :placeholder="$t('acl.password')" v-decorator="['password', { rules: [{ required: false }] }]" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="继承自">
|
||||
<a-select
|
||||
showSearch
|
||||
v-model="selectedParents"
|
||||
:filterOption="false"
|
||||
placeholder="可选择继承角色"
|
||||
mode="multiple"
|
||||
>
|
||||
<a-select-option v-for="role in scrollData" :key="role.id">{{ role.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item> -->
|
||||
<a-form-item label="继承自">
|
||||
<a-form-item :label="$t('acl.inheritedFrom')">
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
size="small"
|
||||
v-model="selectedParents"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="可选择继承角色"
|
||||
:placeholder="$t('acl.selectedParents')"
|
||||
>
|
||||
<el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="是否应用管理员">
|
||||
<a-form-item :label="$t('acl.isAppAdmin')">
|
||||
<a-switch
|
||||
@change="onChange"
|
||||
name="is_app_admin"
|
||||
@@ -53,8 +42,8 @@
|
||||
</a-form-item>
|
||||
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">确定</a-button>
|
||||
<a-button @click="onClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
@@ -93,7 +82,7 @@ export default {
|
||||
// return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
// },
|
||||
handleCreate() {
|
||||
this.drawerTitle = '新增角色'
|
||||
this.drawerTitle = this.$t('acl.addRole')
|
||||
this.drawerVisible = true
|
||||
},
|
||||
onClose() {
|
||||
@@ -107,7 +96,7 @@ export default {
|
||||
},
|
||||
|
||||
handleEdit(record) {
|
||||
this.drawerTitle = `编辑:${record.name}`
|
||||
this.drawerTitle = `${this.$t('edit')}: ${record.name}`
|
||||
this.drawerVisible = true
|
||||
this.current_id = record.id
|
||||
const _parents = this.id2parents[record.id]
|
||||
@@ -142,7 +131,7 @@ export default {
|
||||
updateRole(id, data) {
|
||||
this.updateParents(id)
|
||||
updateRoleById(id, { ...data, app_id: this.$route.name.split('_')[0] }).then((res) => {
|
||||
this.$message.success(`更新成功`)
|
||||
this.$message.success(this.$t('updateSuccess'))
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
})
|
||||
@@ -151,7 +140,7 @@ export default {
|
||||
|
||||
createRole(data) {
|
||||
addRole({ ...data, app_id: this.$route.name.split('_')[0] }).then((res) => {
|
||||
this.$message.success(`添加成功`)
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.updateParents(res.id)
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
@@ -171,16 +160,9 @@ export default {
|
||||
child_ids: [id],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
})
|
||||
// addParentRole(id, item, { app_id: this.$route.name.split('_')[0] })
|
||||
// .catch(err => this.requestFailed(err))
|
||||
}
|
||||
})
|
||||
},
|
||||
// requestFailed(err) {
|
||||
// console.log(err)
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// },
|
||||
},
|
||||
watch: {},
|
||||
props: {
|
||||
|
@@ -4,7 +4,7 @@
|
||||
ref="child"
|
||||
:attrList="roleTableAttrList"
|
||||
:hasSwitch="true"
|
||||
switchValue="角色关系"
|
||||
:switchValue="$t('acl.roleRelation')"
|
||||
@onSwitchChange="onSwitchChange"
|
||||
@search="handleSearch"
|
||||
@searchFormReset="searchFormReset"
|
||||
@@ -19,16 +19,16 @@
|
||||
resizable
|
||||
:height="`${windowHeight - 310}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" title="操作员" width="130px"></vxe-column>
|
||||
<vxe-column field="operate_type" title="操作" width="112px">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" :title="$t('acl.operator')" width="130px"></vxe-column>
|
||||
<vxe-column field="operate_type" :title="$t('operation')" width="112px">
|
||||
<template #default="{ row }">
|
||||
<template>
|
||||
<a-tag :color="handleTagColor(row.operate_type)">{{ operateTypeMap.get(row.operate_type) }}</a-tag>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column :title="checked ? '角色' : '角色'">
|
||||
<vxe-column :title="checked ? $t('acl.role2') : $t('acl.role2')">
|
||||
<template #default="{ row }">
|
||||
<template v-if="!checked">
|
||||
<a-tag color="blue">{{ row.current.name || row.origin.name }}</a-tag>
|
||||
@@ -40,7 +40,7 @@
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column :title="checked ? '继承自' : '管理员'" :width="checked ? '350px' : '80px'">
|
||||
<vxe-column :title="checked ? $t('acl.inheritedFrom') : $t('acl.admin')" :width="checked ? '350px' : '80px'">
|
||||
<template #default="{ row }">
|
||||
<template v-if="!checked">
|
||||
<a-icon type="check" v-if="row.current.is_app_admin" />
|
||||
@@ -52,14 +52,14 @@
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述" v-if="!checked">
|
||||
<vxe-column :title="$t('desc')" v-if="!checked">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.description }}
|
||||
</p>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" title="来源" width="100px"></vxe-column>
|
||||
<vxe-column field="source" :title="$t('acl.source')" width="100px"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from './pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from './searchForm.vue'
|
||||
import { searchRoleHistory } from '@/modules/acl/api/history'
|
||||
export default {
|
||||
@@ -105,13 +105,6 @@ export default {
|
||||
checked: false,
|
||||
tableData: [],
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['delete', '删除'],
|
||||
['update', '修改'],
|
||||
['role_relation_add', '添加角色关系'],
|
||||
['role_relation_delete', '删除角色关系'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['delete', 'red'],
|
||||
@@ -127,42 +120,53 @@ export default {
|
||||
start: '',
|
||||
end: '',
|
||||
},
|
||||
roleTableAttrList: [
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
['role_relation_add', this.$t('acl.roleRelationAdd')],
|
||||
['role_relation_delete', this.$t('acl.roleRelationDelete')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableDataLength() {
|
||||
return this.tableData.length
|
||||
},
|
||||
roleTableAttrList() {
|
||||
return [
|
||||
{
|
||||
alias: '日期',
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ 新建: 'create' },
|
||||
{ 修改: 'update' },
|
||||
{ 删除: 'delete' },
|
||||
{ 添加角色关系: 'role_relation_add' },
|
||||
{ 删除角色关系: 'role_relation_delete' },
|
||||
{ [this.$t('create')]: 'create' },
|
||||
{ [this.$t('update')]: 'update' },
|
||||
{ [this.$t('delete')]: 'delete' },
|
||||
{ [this.$t('acl.roleRelationAdd')]: 'role_relation_add' },
|
||||
{ [this.$t('acl.roleRelationDelete')]: 'role_relation_delete' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableDataLength() {
|
||||
return this.tableData.length
|
||||
]
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
@@ -273,7 +277,7 @@ export default {
|
||||
switch (operate_type) {
|
||||
// create
|
||||
case 'create': {
|
||||
item.description = `新建角色:${item.current.name}`
|
||||
item.description = `${this.$t('acl.addRole')}${item.current.name}`
|
||||
break
|
||||
}
|
||||
case 'update': {
|
||||
@@ -283,15 +287,15 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null) {
|
||||
const str = ` 【 ${key} : 改为 ${newVal} 】 `
|
||||
const str = ` 【 ${key} : -> ${newVal} 】 `
|
||||
item.description += str
|
||||
} else {
|
||||
const str = ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 `
|
||||
item.description += str
|
||||
const str = ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
|
||||
item.description += ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!item.description) item.description = '没有修改'
|
||||
if (!item.description) item.description = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
@@ -321,7 +325,7 @@ export default {
|
||||
resourceMap.forEach((value, key) => {
|
||||
permsArr.push(`${id2resources[key].name}:${value}`)
|
||||
})
|
||||
item.description = `继承者:${child_ids}\n继承自:${parent_ids}\n涉及资源及权限:\n${permsArr.join(`\n`)}`
|
||||
item.description = `${this.$t('acl.heir')}:${child_ids}\n${this.$t('acl.inheritedFrom')}:${parent_ids}\n${this.$t('acl.involvingRP')}:\n${permsArr.join(`\n`)}`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@
|
||||
@popupScroll="loadMoreData(attr.name, $event)"
|
||||
@search="(value) => fetchData(value, attr.name)"
|
||||
v-model="queryParams[attr.name]"
|
||||
placeholder="请选择"
|
||||
:placeholder="$t('placeholder2')"
|
||||
v-if="attr.is_choice"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
@@ -38,7 +38,6 @@
|
||||
@change="onChange"
|
||||
:style="{ width: '100%' }"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
:show-time="{
|
||||
hideDisabledOptions: true,
|
||||
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
|
||||
@@ -67,7 +66,7 @@
|
||||
@popupScroll="loadMoreData(item.name, $event)"
|
||||
@search="(value) => fetchData(value, item.name)"
|
||||
v-model="queryParams[item.name]"
|
||||
placeholder="请选择"
|
||||
:placeholder="$t('placeholder2')"
|
||||
v-if="item.is_choice"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
@@ -85,7 +84,7 @@
|
||||
:style="{ width: '100%' }"
|
||||
@change="onChange"
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
:placeholder="[$t('acl.startAt'), $t('acl.endAt')]"
|
||||
v-else-if="valueTypeMap[item.value_type] == 'date' || valueTypeMap[item.value_type] == 'datetime'"
|
||||
:show-time="{
|
||||
hideDisabledOptions: true,
|
||||
@@ -107,13 +106,13 @@
|
||||
v-model="checked"
|
||||
/>
|
||||
<a-button :style="{ marginLeft: '8px' }" type="primary" html-type="submit" @click="handleSearch">
|
||||
查询
|
||||
{{ $t('query') }}
|
||||
</a-button>
|
||||
<a-button :style="{ marginLeft: '8px' }" @click="handleReset">
|
||||
重置
|
||||
{{ $t('reset') }}
|
||||
</a-button>
|
||||
<a :style="{ marginLeft: '8px', fontSize: '12px' }" @click="toggle" v-if="attrList.length >= 5">
|
||||
{{ expand ? '隐藏' : '展开' }} <a-icon :type="expand ? 'up' : 'down'" />
|
||||
{{ expand ? $t('expand') : $t('expand') }} <a-icon :type="expand ? 'up' : 'down'" />
|
||||
</a>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
@@ -2,30 +2,40 @@
|
||||
<CustomDrawer
|
||||
@close="handleClose"
|
||||
width="500"
|
||||
:title="`${triggerId ? '修改' : '新建'}触发器`"
|
||||
:title="`${triggerId ? $t('update') : $t('create')}${$t('acl.trigger')}`"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }">
|
||||
<a-form-item label="触发器名">
|
||||
<a-input size="large" v-decorator="['name', { rules: [{ required: true, message: '请输入触发器名' }] }]">
|
||||
<a-form-item :label="$t('name')">
|
||||
<a-input
|
||||
size="large"
|
||||
v-decorator="['name', { rules: [{ required: true, message: $t('acl.triggerNameInput') }] }]"
|
||||
>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="资源名">
|
||||
<a-input size="large" v-decorator="['wildcard']" placeholder="优先正则模式(次通配符)"> </a-input>
|
||||
<a-form-item :label="$t('acl.resourceName')">
|
||||
<a-input size="large" v-decorator="['wildcard']" :placeholder="$t('acl.triggerTips1')"> </a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="创建人">
|
||||
<el-select :style="{ width: '100%' }" filterable multiple v-decorator="['uid']">
|
||||
<a-form-item :label="$t('acl.creator')">
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
filterable
|
||||
multiple
|
||||
v-decorator="['uid']"
|
||||
:placeholder="$t('placeholder2')"
|
||||
>
|
||||
<template v-for="role in roles">
|
||||
<el-option v-if="role.uid" :key="role.id" :value="role.uid" :label="role.name">{{ role.name }}</el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="资源类型">
|
||||
<a-form-item :label="$t('acl.resourceType')">
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
@change="handleRTChange"
|
||||
v-decorator="['resource_type_id', { rules: [{ required: true, message: '请选择资源类型' }] }]"
|
||||
:placeholder="$t('placeholder2')"
|
||||
v-decorator="['resource_type_id', { rules: [{ required: true, message: $t('acl.pleaseSelectType') }] }]"
|
||||
>
|
||||
<el-option
|
||||
v-for="resourceType in resourceTypeList"
|
||||
@@ -34,25 +44,27 @@
|
||||
:label="resourceType.name"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<a-tooltip title="查看正则匹配结果">
|
||||
<a-tooltip :title="$t('acl.viewMatchResult')">
|
||||
<a class="trigger-form-pattern" @click="handlePattern"><a-icon type="eye"/></a>
|
||||
</a-tooltip>
|
||||
</a-form-item>
|
||||
<a-form-item label="角色">
|
||||
<a-form-item :label="$t('acl.role2')">
|
||||
<el-select
|
||||
:style="{ width: '100%' }"
|
||||
filterable
|
||||
multiple
|
||||
v-decorator="['roles', { rules: [{ required: true, message: '请选择角色' }] }]"
|
||||
:placeholder="$t('placeholder2')"
|
||||
v-decorator="['roles', { rules: [{ required: true, message: $t('acl.role_placeholder2') }] }]"
|
||||
>
|
||||
<el-option v-for="role in roles" :key="role.id" :value="role.id" :label="role.name"></el-option>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="权限">
|
||||
<a-form-item :label="$t('acl.permission')">
|
||||
<el-select
|
||||
:placeholder="$t('placeholder2')"
|
||||
:style="{ width: '100%' }"
|
||||
multiple
|
||||
v-decorator="['permissions', { rules: [{ required: true, message: '请选择权限' }] }]"
|
||||
v-decorator="['permissions', { rules: [{ required: true, message: $t('acl.permission_placeholder') }] }]"
|
||||
>
|
||||
<el-option
|
||||
v-for="perm in selectResourceTypePerms"
|
||||
@@ -62,13 +74,13 @@
|
||||
></el-option>
|
||||
</el-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="启用/禁用">
|
||||
<a-form-item :label="`${$t('acl.enable')} / ${$t('acl.disable')}`">
|
||||
<a-switch v-decorator="['enabled', { rules: [], valuePropName: 'checked', initialValue: true }]" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="handleClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">提交</a-button>
|
||||
<a-button @click="handleClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('submit') }}</a-button>
|
||||
</div>
|
||||
<TriggerPattern ref="triggerPattern" :roles="roles" />
|
||||
</CustomDrawer>
|
||||
@@ -159,13 +171,13 @@ export default {
|
||||
if (this.triggerId) {
|
||||
updateTrigger(this.triggerId, { ...values, app_id: this.app_id }).then((res) => {
|
||||
this.visible = false
|
||||
this.$message.success('修改成功!')
|
||||
this.$message.success(this.$t('updateSuccess'))
|
||||
this.$emit('refresh')
|
||||
})
|
||||
} else {
|
||||
addTrigger({ ...values, app_id: this.app_id }).then((res) => {
|
||||
this.visible = false
|
||||
this.$message.success('创建成功!')
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.$emit('refresh')
|
||||
})
|
||||
}
|
||||
|
@@ -16,23 +16,23 @@
|
||||
resizable
|
||||
:height="`${windowHeight - 310}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="handleTagColor(row.operate_type)">
|
||||
{{ operateTypeMap.get(row.operate_type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="trigger_id" width="250px" title="触发器">
|
||||
<vxe-column field="trigger_id" width="250px" :title="$t('acl.trigger')">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.current.name || row.origin.name }}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述">
|
||||
<vxe-column :title="$t('desc')">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.changeDescription }}
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from './pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from './searchForm.vue'
|
||||
import { searchTriggerHistory } from '@/modules/acl/api/history'
|
||||
export default {
|
||||
@@ -95,13 +95,6 @@ export default {
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
loading: true,
|
||||
tableData: [],
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['update', '修改'],
|
||||
['delete', '删除'],
|
||||
['trigger_apply', '应用'],
|
||||
['trigger_cancel', '取消'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['delete', 'red'],
|
||||
@@ -109,41 +102,6 @@ export default {
|
||||
['trigger_apply', 'green'],
|
||||
['trigger_cancel', 'red'],
|
||||
]),
|
||||
triggerTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ 新建: 'create' },
|
||||
{ 修改: 'update' },
|
||||
{ 删除: 'delete' },
|
||||
{ 应用: 'trigger_apply' },
|
||||
{ 取消: 'trigger_cancel' },
|
||||
],
|
||||
},
|
||||
{
|
||||
alias: '触发器',
|
||||
is_choice: true,
|
||||
name: 'trigger_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allTriggers,
|
||||
},
|
||||
],
|
||||
queryParams: {
|
||||
page: 1,
|
||||
page_size: 50,
|
||||
@@ -164,12 +122,58 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
['trigger_apply', this.$t('acl.apply')],
|
||||
['trigger_cancel', this.$t('cancel')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableDataLength() {
|
||||
return this.tableData.length
|
||||
},
|
||||
triggerTableAttrList() {
|
||||
return [
|
||||
{
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: this.allUsers,
|
||||
},
|
||||
{
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ [this.$t('create')]: 'create' },
|
||||
{ [this.$t('update')]: 'update' },
|
||||
{ [this.$t('delete')]: 'delete' },
|
||||
{ [this.$t('acl.apply')]: 'trigger_apply' },
|
||||
{ [this.$t('cancel')]: 'trigger_cancel' },
|
||||
],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.trigger'),
|
||||
is_choice: true,
|
||||
name: 'trigger_id',
|
||||
value_type: '2',
|
||||
choice_value: this.allTriggers,
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async getTable(queryParams) {
|
||||
@@ -220,9 +224,9 @@ export default {
|
||||
const str = item.current.roles
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join(',')
|
||||
item.changeDescription = `新增触发器:${item.current.name}\n资源类型:${this.allResourceTypesMap.get(
|
||||
item.changeDescription = `${this.$t('acl.addTrigger')}: ${item.current.name}\n${this.$t('acl.resourceType')}: :${this.allResourceTypesMap.get(
|
||||
item.current.resource_type_id
|
||||
)},资源名:${item.current.wildcard},角色:[${newStr}]\n权限:${item.current.permissions}\n状态:${
|
||||
)},this.$t('acl.resourceName'):${item.current.wildcard},${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.current.permissions}\n${this.$t('status')}: ${
|
||||
item.current.enabled
|
||||
}`
|
||||
break
|
||||
@@ -234,24 +238,24 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null) {
|
||||
const str = ` 【 ${key} : 改为 ${newVal} 】 `
|
||||
const str = ` 【 ${key} : -> ${newVal} 】 `
|
||||
item.changeDescription += str
|
||||
} else {
|
||||
const str = ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 `
|
||||
item.changeDescription += str
|
||||
const str = ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
|
||||
item.changeDescription += ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!item.changeDescription) item.changeDescription = '没有修改'
|
||||
if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
const str = item.origin.roles
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join(',')
|
||||
item.changeDescription = `删除触发器:${item.origin.name}\n资源类型:${this.allResourceTypesMap.get(
|
||||
item.changeDescription = `${this.$t('acl.deleteTrigger')}: ${item.origin.name}\n${this.$t('acl.resourceType')}: :${this.allResourceTypesMap.get(
|
||||
item.origin.resource_type_id
|
||||
)},资源名:${item.origin.wildcard},角色:[${newStr}]\n权限:${item.origin.permissions}\n状态:${
|
||||
)},this.$t('acl.resourceName'):${item.origin.wildcard},${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.origin.permissions}\n${this.$t('status')}: ${
|
||||
item.origin.enabled
|
||||
}`
|
||||
break
|
||||
@@ -260,9 +264,9 @@ export default {
|
||||
const str = item.current.roles
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join(',')
|
||||
item.changeDescription = `应用触发器:${item.current.name}\n资源类型:${this.allResourceTypesMap.get(
|
||||
item.changeDescription = `${this.$t('acl.applyTrigger')}: ${item.current.name}\n${this.$t('acl.resourceType')}: :${this.allResourceTypesMap.get(
|
||||
item.current.resource_type_id
|
||||
)},资源名:${item.current.wildcard},角色:[${newStr}]\n权限:${item.current.permissions}\n状态:${
|
||||
)},this.$t('acl.resourceName'):${item.current.wildcard},${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.current.permissions}\n${this.$t('status')}: ${
|
||||
item.current.enabled
|
||||
}`
|
||||
break
|
||||
@@ -271,9 +275,9 @@ export default {
|
||||
const str = item.current.roles
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join(',')
|
||||
item.changeDescription = `取消触发器:${item.current.name}\n资源类型:${this.allResourceTypesMap.get(
|
||||
item.changeDescription = `${this.$t('acl.cancelTrigger')}: ${item.current.name}\n${this.$t('acl.resourceType')}: :${this.allResourceTypesMap.get(
|
||||
item.current.resource_type_id
|
||||
)},资源名:${item.current.wildcard},角色:[${newStr}]\n权限:${item.current.permissions}\n状态:${
|
||||
)},this.$t('acl.resourceName'):${item.current.wildcard},${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.current.permissions}\n${this.$t('status')}: ${
|
||||
item.current.enabled
|
||||
}`
|
||||
break
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<CustomDrawer
|
||||
:hasFooter="false"
|
||||
title="正则匹配结果"
|
||||
:title="$t('acl.viewMatchResult')"
|
||||
:visible="patternVisible"
|
||||
width="500"
|
||||
@close="
|
||||
@@ -16,16 +16,16 @@
|
||||
class="ops-stripe-table"
|
||||
:data="tableData"
|
||||
:max-height="`${windowHeight - 110}px`">
|
||||
<vxe-table-column field="name" title="资源名"></vxe-table-column>
|
||||
<vxe-table-column field="uid" title="创建人">
|
||||
<vxe-table-column field="name" :title="$t('acl.resourceName')"></vxe-table-column>
|
||||
<vxe-table-column field="uid" :title="$t('acl.creator')">
|
||||
<template #default="{row}">
|
||||
{{ getRoleName(row.uid) }}
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="created_at" title="创建时间"></vxe-table-column>
|
||||
<vxe-table-column field="created_at" :title="$t('created_at')"></vxe-table-column>
|
||||
<template slot="empty">
|
||||
<img :src="require(`@/assets/data_empty.png`)" />
|
||||
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">暂无数据</p>
|
||||
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">{{ $t('noData') }}</p>
|
||||
</template>
|
||||
</vxe-table>
|
||||
</CustomDrawer>
|
||||
|
@@ -8,33 +8,38 @@
|
||||
width="500px"
|
||||
>
|
||||
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
|
||||
<a-form-item label="用户名(英文)">
|
||||
<a-form-item :label="$t('acl.username')">
|
||||
<a-input
|
||||
name="username"
|
||||
placeholder="英文名"
|
||||
v-decorator="['username', { rules: [{ required: true, message: '请输入用户名' }] }]"
|
||||
:placeholder="$t('acl.username_placeholder')"
|
||||
v-decorator="['username', { rules: [{ required: true, message: $t('acl.username_placeholder') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="中文名">
|
||||
<a-input name="nickname" v-decorator="['nickname', { rules: [] }]" />
|
||||
<a-form-item :label="$t('acl.nickname')">
|
||||
<a-input
|
||||
name="nickname"
|
||||
:placeholder="$t('acl.nickname_placeholder')"
|
||||
v-decorator="['nickname', { rules: [] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="密码">
|
||||
<a-form-item :label="$t('acl.password')">
|
||||
<a-input
|
||||
type="password"
|
||||
name="password"
|
||||
v-decorator="['password', { rules: [{ required: true, message: '请输入密码' }] }]"
|
||||
:placeholder="$t('acl.password_placeholder')"
|
||||
v-decorator="['password', { rules: [{ required: true, message: $t('acl.password_placeholder') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="部门">
|
||||
<a-form-item :label="$t('acl.department')">
|
||||
<a-input name="department" v-decorator="['department', { rules: [] }]" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="小组">
|
||||
<a-form-item :label="$t('acl.group')">
|
||||
<a-input name="catalog" v-decorator="['catalog', { rules: [] }]" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="邮箱">
|
||||
<a-form-item :label="$t('acl.email')">
|
||||
<a-input
|
||||
name="email"
|
||||
v-decorator="[
|
||||
@@ -43,11 +48,11 @@
|
||||
rules: [
|
||||
{
|
||||
type: 'email',
|
||||
message: '请输入正确的邮箱!',
|
||||
message: $t('acl.email_placeholder'),
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: '请输入邮箱',
|
||||
message: $t('acl.email_placeholder'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -55,14 +60,14 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="手机号码">
|
||||
<a-form-item :label="$t('acl.mobile')">
|
||||
<a-input
|
||||
name="mobile"
|
||||
v-decorator="['mobile', { rules: [{ message: '请输入正确的手机号码', pattern: /^1\d{10}$/ }] }]"
|
||||
v-decorator="['mobile', { rules: [{ message: $t('acl.mobileTips'), pattern: /^1\d{10}$/ }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="是否锁定">
|
||||
<a-form-item :label="$t('acl.isBlock')">
|
||||
<a-switch @change="onChange" name="block" v-decorator="['block', { rules: [], valuePropName: 'checked' }]" />
|
||||
</a-form-item>
|
||||
|
||||
@@ -71,8 +76,8 @@
|
||||
</a-form-item>
|
||||
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">确定</a-button>
|
||||
<a-button @click="onClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
@@ -85,7 +90,6 @@ export default {
|
||||
name: 'AttributeForm',
|
||||
data() {
|
||||
return {
|
||||
drawerTitle: '新增用户',
|
||||
drawerVisible: false,
|
||||
}
|
||||
},
|
||||
@@ -94,7 +98,11 @@ export default {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
|
||||
computed: {},
|
||||
computed: {
|
||||
drawerTitle() {
|
||||
return this.$t('acl.addUser')
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
handleCreate() {
|
||||
@@ -142,7 +150,7 @@ export default {
|
||||
},
|
||||
updateUser(attrId, data) {
|
||||
updateUserById(attrId, data).then((res) => {
|
||||
this.$message.success(`更新成功`)
|
||||
this.$message.success(this.$t('updateSuccess'))
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
})
|
||||
@@ -151,17 +159,11 @@ export default {
|
||||
|
||||
createUser(data) {
|
||||
addUser(data).then((res) => {
|
||||
this.$message.success(`添加成功`)
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.handleOk()
|
||||
this.onClose()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
},
|
||||
|
||||
// requestFailed (err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// }
|
||||
},
|
||||
watch: {},
|
||||
props: {
|
||||
|
@@ -1,9 +1,15 @@
|
||||
<template>
|
||||
<CustomDrawer :closable="true" :visible="visible" width="500px" @close="handleClose" title="组用户">
|
||||
<a-form-item label="添加用户" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||
<CustomDrawer :closable="true" :visible="visible" width="500px" @close="handleClose" :title="$t('acl.groupUser')">
|
||||
<a-form-item :label="$t('acl.addUser')" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||
<a-row>
|
||||
<a-col span="15">
|
||||
<el-select v-model="selectedChildrenRole" multiple collapse-tags size="small" filterable>
|
||||
<el-select
|
||||
v-model="selectedChildrenRole"
|
||||
multiple
|
||||
collapse-tags
|
||||
size="small"
|
||||
filterable
|
||||
:placeholder="$t('placeholder2')">
|
||||
<el-option
|
||||
class="drop-down-render"
|
||||
v-for="role in allRoles"
|
||||
@@ -14,14 +20,19 @@
|
||||
</el-select>
|
||||
</a-col>
|
||||
<a-col span="5" offset="1">
|
||||
<a-button style="display: inline-block" @click="handleAddRole">确定</a-button>
|
||||
<a-button style="display: inline-block" @click="handleAddRole">{{ $t('confirm') }}</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
<a-card>
|
||||
<a-row :gutter="24" v-for="(record, index) in records" :key="record.id" :style="{ marginBottom: '5px' }">
|
||||
<a-col :span="20">{{ index + 1 }}、{{ record.nickname }}</a-col>
|
||||
<a-col :span="4"><a-button type="danger" size="small" @click="handleRevokeUser(record)">移除</a-button></a-col>
|
||||
<a-col
|
||||
:span="4"
|
||||
><a-button type="danger" size="small" @click="handleRevokeUser(record)">{{
|
||||
$t('acl.remove')
|
||||
}}</a-button></a-col
|
||||
>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</CustomDrawer>
|
||||
@@ -63,34 +74,22 @@ export default {
|
||||
this.visible = true
|
||||
this.loadRecords(roleId)
|
||||
},
|
||||
// filterOption(input, option) {
|
||||
// return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
// },
|
||||
async handleAddRole() {
|
||||
// await this.selectedChildrenRole.forEach(item => {
|
||||
// addParentRole(item, this.roleId, { app_id: this.$route.name.split('_')[0] }).then(res => {
|
||||
// this.$message.success('添加成功')
|
||||
// })
|
||||
// // .catch(err=>{
|
||||
// // this.$httpError(err)
|
||||
// // })
|
||||
|
||||
// })
|
||||
await addBatchParentRole(this.roleId, {
|
||||
child_ids: this.selectedChildrenRole,
|
||||
app_id: this.$route.name.split('_')[0],
|
||||
})
|
||||
this.loadRecords(this.roleId)
|
||||
this.$message.success('添加完成')
|
||||
this.$message.success(this.$t('addSuccess'))
|
||||
this.selectedChildrenRole = []
|
||||
},
|
||||
handleRevokeUser(record) {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
content: '是否确定要移除该用户',
|
||||
content: that.$t('acl.deleteUserConfirm'),
|
||||
onOk() {
|
||||
delParentRole(record.role.id, that.roleId, { app_id: that.$route.name.split('_')[0] }).then((res) => {
|
||||
that.$message.success('删除成功!')
|
||||
that.$message.success(that.$t('deleteSuccess'))
|
||||
that.loadRecords(that.roleId)
|
||||
})
|
||||
// .catch(err=>that.$httpError(err))
|
||||
|
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div class="acl-operation-history">
|
||||
<a-tabs default-active-key="1">
|
||||
<a-tab-pane key="1" tab="权限变更">
|
||||
<a-tab-pane key="1" :tab="$t('acl.permissionChange')">
|
||||
<permisson-table></permisson-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="角色变更">
|
||||
<a-tab-pane key="2" :tab="$t('acl.roleChange')">
|
||||
<role-history-table></role-history-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3" tab="资源变更">
|
||||
<a-tab-pane key="3" :tab="$t('acl.resourceChange')">
|
||||
<resource-history-table></resource-history-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="4" tab="资源类型变更">
|
||||
<a-tab-pane key="4" :tab="$t('acl.resourceTypeChange')">
|
||||
<resource-type-history-table></resource-type-history-table>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="5" tab="触发器变更">
|
||||
<a-tab-pane key="5" :tab="$t('acl.triggerChange')">
|
||||
<trigger-history-table></trigger-history-table>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
@@ -22,22 +22,22 @@
|
||||
:height="`${windowHeight - windowHeightMinus}px`"
|
||||
:scroll-y="{ enabled: false }"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.deleted_at || row.updated_at || row.created_at }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="row.operate_type === 'grant' ? 'green' : 'red'">{{
|
||||
operateTypeMap.get(row.operate_type)
|
||||
}}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="rid" title="用户"></vxe-column>
|
||||
<vxe-column field="resource_type_id" title="资源类型"></vxe-column>
|
||||
<vxe-column field="resources" title="资源">
|
||||
<vxe-column field="rid" :title="$t('user')"></vxe-column>
|
||||
<vxe-column field="resource_type_id" :title="$t('acl.resourceType')"></vxe-column>
|
||||
<vxe-column field="resources" :title="$t('acl.resource')">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.resource_ids.length > 0">
|
||||
<a-tooltip placement="top">
|
||||
@@ -56,14 +56,14 @@
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="权限">
|
||||
<vxe-column :title="$t('acl.permission')">
|
||||
<template #default="{ row }">
|
||||
<a-tag v-for="(perm, index) in row.permission_ids" :key="'perms_' + perm + index">
|
||||
{{ perm }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" width="100px" title="来源"></vxe-column>
|
||||
<vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -81,7 +81,7 @@
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import debounce from 'lodash/debounce'
|
||||
import Pager from '../../module/pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from '../../module/searchForm.vue'
|
||||
import { searchApp } from '@/modules/acl/api/app'
|
||||
import { searchPermissonHistory } from '@/modules/acl/api/history'
|
||||
@@ -108,10 +108,6 @@ export default {
|
||||
allRolesMap: new Map(),
|
||||
allUsersMap: new Map(),
|
||||
allResourceTypesMap: new Map(),
|
||||
operateTypeMap: new Map([
|
||||
['grant', '授权'],
|
||||
['revoke', '撤销'],
|
||||
]),
|
||||
queryParams: {
|
||||
page: 1,
|
||||
page_size: 50,
|
||||
@@ -120,57 +116,63 @@ export default {
|
||||
},
|
||||
permissionTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '应用',
|
||||
alias: this.$t('acl.app'),
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '用户',
|
||||
alias: this.$t('user'),
|
||||
is_choice: true,
|
||||
name: 'rid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '资源类型',
|
||||
alias: this.$t('acl.resourceType'),
|
||||
is_choice: true,
|
||||
name: 'resource_type_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '资源',
|
||||
alias: this.$t('acl.resource'),
|
||||
is_choice: true,
|
||||
name: 'resource_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [{ 授权: 'grant' }, { 撤销: 'revoke' }],
|
||||
choice_value: [{ [this.$t('grant')]: 'grant' }, { [this.$t('acl.cancel')]: 'revoke' }],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['grant', this.$t('grant')],
|
||||
['revoke', this.$t('acl.cancel')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
|
@@ -4,7 +4,7 @@
|
||||
ref="child"
|
||||
:attrList="resourceTableAttrList"
|
||||
:hasSwitch="true"
|
||||
switchValue="组"
|
||||
:switchValue="$t('acl.group2')"
|
||||
@onSwitchChange="onSwitchChange"
|
||||
@expandChange="handleExpandChange"
|
||||
@search="handleSearch"
|
||||
@@ -24,30 +24,30 @@
|
||||
:data="tableData"
|
||||
:height="`${windowHeight - windowHeightMinus}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="handleTagColor(row.operate_type)">
|
||||
{{ operateTypeMap.get(row.operate_type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="link_id" title="资源名">
|
||||
<vxe-column field="link_id" :title="$t('acl.resourceName')">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.current.name || row.origin.name }}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述">
|
||||
<vxe-column :title="$t('desc')">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.description }}
|
||||
</p>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" width="100px" title="来源"></vxe-column>
|
||||
<vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from '../../module/pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from '../../module/searchForm.vue'
|
||||
import { searchResourceHistory } from '@/modules/acl/api/history'
|
||||
import { searchUser } from '@/modules/acl/api/user'
|
||||
@@ -87,47 +87,6 @@ export default {
|
||||
allApps: [],
|
||||
allUsersMap: new Map(),
|
||||
allResourcesMap: new Map(),
|
||||
resourceTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '应用',
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '资源名',
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
|
||||
},
|
||||
],
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['update', '修改'],
|
||||
['delete', '删除'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['update', 'orange'],
|
||||
@@ -140,6 +99,46 @@ export default {
|
||||
start: '',
|
||||
end: '',
|
||||
},
|
||||
resourceTableAttrList: [
|
||||
{
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.app'),
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.resourceName'),
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ [this.$t('create')]: 'create' },
|
||||
{ [this.$t('update')]: 'update' },
|
||||
{ [this.$t('delete')]: 'delete' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
@@ -158,6 +157,13 @@ export default {
|
||||
this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
@@ -347,7 +353,7 @@ export default {
|
||||
switch (operate_type) {
|
||||
// create
|
||||
case 'create': {
|
||||
item.description = `新建资源:${item.current.name}`
|
||||
item.description = `${this.$t('acl.newResource')}${item.current.name}`
|
||||
break
|
||||
}
|
||||
case 'update': {
|
||||
@@ -357,10 +363,10 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null) {
|
||||
const str = ` 【 ${key} : 改为 ${newVal} 】 `
|
||||
const str = ` 【 ${key} : -> ${newVal} 】 `
|
||||
item.description += str
|
||||
} else {
|
||||
const str = ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 `
|
||||
const str = ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
|
||||
item.description += str
|
||||
}
|
||||
}
|
||||
@@ -369,18 +375,18 @@ export default {
|
||||
const currentResource_ids = item.currentResource_ids
|
||||
if (!_.isEqual(originResource_ids, currentResource_ids)) {
|
||||
if (originResource_ids.length === 0) {
|
||||
const str = ` 【 resource_ids : 新增 ${currentResource_ids} 】 `
|
||||
const str = ` 【 resource_ids : ${this.$t('new')} ${currentResource_ids} 】 `
|
||||
item.description += str
|
||||
} else {
|
||||
const str = ` 【 resource_ids : 由 ${originResource_ids} 改为 ${currentResource_ids} 】 `
|
||||
const str = ` 【 resource_ids : ${originResource_ids} -> ${currentResource_ids} 】 `
|
||||
item.description += str
|
||||
}
|
||||
}
|
||||
if (!item.description) item.description = '没有修改'
|
||||
if (!item.description) item.description = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
item.description = `删除资源:${item.origin.name}`
|
||||
item.description = `${this.$t('acl.deleteResource')}${item.origin.name}`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -18,30 +18,30 @@
|
||||
:loading="loading"
|
||||
:height="`${windowHeight - windowHeightMinus}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="handleTagColor(row.operate_type)">
|
||||
{{ operateTypeMap.get(row.operate_type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="link_id" width="159px" title="资源类型名">
|
||||
<vxe-column field="link_id" width="159px" :title="$t('acl.resourceTypeName')">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.current.name || row.origin.name }}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述">
|
||||
<vxe-column :title="$t('desc')">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.changeDescription }}
|
||||
</p>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" width="100px" title="来源"></vxe-column>
|
||||
<vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from '../../module/pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from '../../module/searchForm.vue'
|
||||
import { searchResourceHistory } from '@/modules/acl/api/history'
|
||||
import { searchUser } from '@/modules/acl/api/user'
|
||||
@@ -78,47 +78,6 @@ export default {
|
||||
allApps: [],
|
||||
allUsersMap: new Map(),
|
||||
allResourcesMap: new Map(),
|
||||
resourceTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '应用',
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '资源类型',
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
|
||||
},
|
||||
],
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['update', '修改'],
|
||||
['delete', '删除'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['update', 'orange'],
|
||||
@@ -131,6 +90,46 @@ export default {
|
||||
start: '',
|
||||
end: '',
|
||||
},
|
||||
resourceTableAttrList: [
|
||||
{
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.app'),
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.resourceType'),
|
||||
is_choice: true,
|
||||
name: 'link_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ [this.$t('create')]: 'create' },
|
||||
{ [this.$t('update')]: 'update' },
|
||||
{ [this.$t('delete')]: 'delete' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
@@ -149,6 +148,13 @@ export default {
|
||||
this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
@@ -283,10 +289,12 @@ export default {
|
||||
switch (operate_type) {
|
||||
// create
|
||||
case 'create': {
|
||||
const description = item.current?.description === undefined ? '无' : item.current?.description
|
||||
const description = item.current?.description === undefined ? this.$t('acl.none') : item.current?.description
|
||||
const permission =
|
||||
item.extra.permission_ids?.current === undefined ? '无' : item.extra.permission_ids?.current
|
||||
item.changeDescription = `新增资源类型:${item.current.name}\n描述:${description}\n权限:${permission}`
|
||||
item.extra.permission_ids?.current === undefined ? this.$t('acl.none') : item.extra.permission_ids?.current
|
||||
item.changeDescription = `${this.$t('acl.addResourceType')}:${item.current.name}\n${this.$t(
|
||||
'desc'
|
||||
)}:${description}\n${this.$t('acl.permission')}:${permission}`
|
||||
break
|
||||
}
|
||||
case 'update': {
|
||||
@@ -296,27 +304,31 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null || oldVal === '') {
|
||||
const str = ` 【 ${key} : 改为 ${newVal} 】 \n`
|
||||
const str = ` 【 ${key} : -> ${newVal} 】 \n`
|
||||
item.changeDescription += str
|
||||
} else {
|
||||
const str = ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 \n`
|
||||
const str = ` 【 ${key} : ${oldVal} -> ${newVal} 】 \n`
|
||||
item.changeDescription += str
|
||||
}
|
||||
}
|
||||
}
|
||||
const currentPerms =
|
||||
item.extra.permission_ids?.current === undefined ? '无' : item.extra.permission_ids?.current
|
||||
const originPerms = item.extra.permission_ids?.origin === undefined ? '无' : item.extra.permission_ids?.origin
|
||||
item.extra.permission_ids?.current === undefined ? this.$t('acl.none') : item.extra.permission_ids?.current
|
||||
const originPerms =
|
||||
item.extra.permission_ids?.origin === undefined ? this.$t('acl.none') : item.extra.permission_ids?.origin
|
||||
if (!_.isEqual(currentPerms, originPerms)) {
|
||||
item.changeDescription += ` 【 permission_ids : 由 ${originPerms} 改为 ${currentPerms} 】 `
|
||||
item.changeDescription += ` 【 permission_ids : ${originPerms} -> ${currentPerms} 】 `
|
||||
}
|
||||
if (!item.changeDescription) item.changeDescription = '没有修改'
|
||||
if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
const description = item.origin?.description === undefined ? '无' : item.origin?.description
|
||||
const permission = item.extra.permission_ids?.origin === undefined ? '无' : item.extra.permission_ids?.origin
|
||||
item.changeDescription = `删除资源类型:${item.origin.name}\n描述:${description}\n权限:${permission}`
|
||||
const description = item.origin?.description === undefined ? this.$t('acl.none') : item.origin?.description
|
||||
const permission =
|
||||
item.extra.permission_ids?.origin === undefined ? this.$t('acl.none') : item.extra.permission_ids?.origin
|
||||
item.changeDescription = `${this.$t('acl.deleteResourceType')}: ${item.origin.name}\n${this.$t(
|
||||
'desc'
|
||||
)}:${description}\n${this.$t('acl.permission')}: ${permission}`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
ref="child"
|
||||
:attrList="roleTableAttrList"
|
||||
:hasSwitch="true"
|
||||
switchValue="角色关系"
|
||||
:switchValue="$t('acl.roleRelation')"
|
||||
@onSwitchChange="onSwitchChange"
|
||||
@search="handleSearch"
|
||||
@searchFormReset="searchFormReset"
|
||||
@@ -19,16 +19,16 @@
|
||||
:loading="loading"
|
||||
:height="`${windowHeight - 310}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="112px" title="操作">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="112px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<template>
|
||||
<a-tag :color="handleTagColor(row.operate_type)">{{ operateTypeMap.get(row.operate_type) }}</a-tag>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column :title="checked ? '角色' : '角色'">
|
||||
<vxe-column :title="checked ? $t('acl.role2') : $t('acl.role2')">
|
||||
<template #default="{ row }">
|
||||
<template v-if="!checked">
|
||||
<a-tag color="blue">{{ row.current.name || row.origin.name }}</a-tag>
|
||||
@@ -40,7 +40,7 @@
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column :title="checked ? '继承自' : '管理员'" :width="checked ? '350px' : '80px'">
|
||||
<vxe-column :title="checked ? $t('acl.inheritedFrom') : $t('acl.admin')" :width="checked ? '350px' : '80px'">
|
||||
<template #default="{ row }">
|
||||
<template v-if="!checked">
|
||||
<a-icon type="check" v-if="row.current.is_app_admin" />
|
||||
@@ -52,14 +52,14 @@
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述" v-if="!checked">
|
||||
<vxe-column :title="$t('desc')" v-if="!checked">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.description }}
|
||||
</p>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="source" width="100px" title="来源"></vxe-column>
|
||||
<vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
|
||||
</vxe-table>
|
||||
<pager
|
||||
:current-page.sync="queryParams.page"
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from '../../module/pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from '../../module/searchForm.vue'
|
||||
import { searchRoleHistory } from '@/modules/acl/api/history'
|
||||
import { searchApp } from '@/modules/acl/api/app'
|
||||
@@ -94,13 +94,6 @@ export default {
|
||||
allRoles: [],
|
||||
allRolesMap: new Map(),
|
||||
allUsersMap: new Map(),
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['delete', '删除'],
|
||||
['update', '修改'],
|
||||
['role_relation_add', '添加角色关系'],
|
||||
['role_relation_delete', '删除角色关系'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['delete', 'red'],
|
||||
@@ -117,42 +110,51 @@ export default {
|
||||
},
|
||||
roleTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '应用',
|
||||
alias: this.$t('acl.app'),
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ 新建: 'create' },
|
||||
{ 修改: 'update' },
|
||||
{ 删除: 'delete' },
|
||||
{ 添加角色关系: 'role_relation_add' },
|
||||
{ 删除角色关系: 'role_relation_delete' },
|
||||
{ [this.$t('create')]: 'create' },
|
||||
{ [this.$t('update')]: 'update' },
|
||||
{ [this.$t('delete')]: 'delete' },
|
||||
{ [this.$t('acl.roleRelationAdd')]: 'role_relation_add' },
|
||||
{ [this.$t('acl.roleRelationDelete')]: 'role_relation_delete' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
['role_relation_add', this.$t('acl.roleRelationAdd')],
|
||||
['role_relation_delete', this.$t('acl.roleRelationDelete')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
@@ -277,7 +279,7 @@ export default {
|
||||
switch (operate_type) {
|
||||
// create
|
||||
case 'create': {
|
||||
item.description = `新建角色:${item.current.name}`
|
||||
item.description = `${this.$t('acl.addRole')}${item.current.name}`
|
||||
break
|
||||
}
|
||||
case 'update': {
|
||||
@@ -287,15 +289,14 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null) {
|
||||
const str = ` 【 ${key} : 改为 ${newVal} 】 `
|
||||
const str = ` 【 ${key} : -> ${newVal} 】 `
|
||||
item.description += str
|
||||
} else {
|
||||
const str = ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 `
|
||||
item.description += str
|
||||
item.description += ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!item.description) item.description = '没有修改'
|
||||
if (!item.description) item.description = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
@@ -325,7 +326,9 @@ export default {
|
||||
resourceMap.forEach((value, key) => {
|
||||
permsArr.push(`${id2resources[key].name}:${value}`)
|
||||
})
|
||||
item.description = `继承者:${child_ids}\n继承自:${parent_ids}\n涉及资源及权限:\n${permsArr.join(`\n`)}`
|
||||
item.description = `${this.$t('acl.heir')}:${child_ids}\n${this.$t(
|
||||
'acl.inheritedFrom'
|
||||
)}:${parent_ids}\n${this.$t('acl.involvingRP')}:\n${permsArr.join(`\n`)}`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -18,23 +18,23 @@
|
||||
:loading="loading"
|
||||
:height="`${windowHeight - windowHeightMinus}px`"
|
||||
>
|
||||
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column>
|
||||
<vxe-column field="operate_type" width="80px" title="操作">
|
||||
<vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
|
||||
<vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
|
||||
<vxe-column field="operate_type" width="100px" :title="$t('operation')">
|
||||
<template #default="{ row }">
|
||||
<a-tag :color="handleTagColor(row.operate_type)">
|
||||
{{ operateTypeMap.get(row.operate_type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="trigger_id" width="250px" title="触发器">
|
||||
<vxe-column field="trigger_id" width="250px" :title="$t('acl.trigger')">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.current.name || row.origin.name }}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="描述">
|
||||
<vxe-column :title="$t('desc')">
|
||||
<template #default="{ row }">
|
||||
<p>
|
||||
{{ row.changeDescription }}
|
||||
@@ -57,13 +57,14 @@
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import Pager from '../../module/pager.vue'
|
||||
import Pager from '@/components/Pager'
|
||||
import SearchForm from '../../module/searchForm.vue'
|
||||
import { searchTriggerHistory } from '@/modules/acl/api/history'
|
||||
import { getTriggers } from '@/modules/acl/api/trigger'
|
||||
import { searchUser } from '@/modules/acl/api/user'
|
||||
import { searchApp } from '@/modules/acl/api/app'
|
||||
export default {
|
||||
name: 'TriggerHistoryTable',
|
||||
components: { SearchForm, Pager },
|
||||
data() {
|
||||
return {
|
||||
@@ -82,13 +83,6 @@ export default {
|
||||
allResourceTypesMap: new Map(),
|
||||
allResourcesMap: new Map(),
|
||||
allTriggersMap: new Map(),
|
||||
operateTypeMap: new Map([
|
||||
['create', '新建'],
|
||||
['update', '修改'],
|
||||
['delete', '删除'],
|
||||
['trigger_apply', '应用'],
|
||||
['trigger_cancel', '取消'],
|
||||
]),
|
||||
colorMap: new Map([
|
||||
['create', 'green'],
|
||||
['delete', 'red'],
|
||||
@@ -96,54 +90,54 @@ export default {
|
||||
['trigger_apply', 'green'],
|
||||
['trigger_cancel', 'red'],
|
||||
]),
|
||||
triggerTableAttrList: [
|
||||
{
|
||||
alias: '日期',
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: '应用',
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作员',
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '触发器',
|
||||
is_choice: true,
|
||||
name: 'trigger_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: '操作',
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ 新建: 'create' },
|
||||
{ 修改: 'update' },
|
||||
{ 删除: 'delete' },
|
||||
{ 应用: 'trigger_apply' },
|
||||
{ 取消: 'trigger_cancel' },
|
||||
],
|
||||
},
|
||||
],
|
||||
queryParams: {
|
||||
page: 1,
|
||||
page_size: 50,
|
||||
start: '',
|
||||
end: '',
|
||||
},
|
||||
triggerTableAttrList: [
|
||||
{
|
||||
alias: this.$t('acl.date'),
|
||||
is_choice: false,
|
||||
name: 'datetime',
|
||||
value_type: '3',
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.app'),
|
||||
is_choice: true,
|
||||
name: 'app_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.operator'),
|
||||
is_choice: true,
|
||||
name: 'operate_uid',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('acl.trigger'),
|
||||
is_choice: true,
|
||||
name: 'trigger_id',
|
||||
value_type: '2',
|
||||
choice_value: [],
|
||||
},
|
||||
{
|
||||
alias: this.$t('operation'),
|
||||
is_choice: true,
|
||||
name: 'operate_type',
|
||||
value_type: '2',
|
||||
choice_value: [
|
||||
{ [this.$t('create')]: 'create' },
|
||||
{ [this.$t('update')]: 'update' },
|
||||
{ [this.$t('delete')]: 'delete' },
|
||||
{ [this.$t('acl.apply')]: 'trigger_apply' },
|
||||
{ [this.$t('cancel')]: 'trigger_cancel' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
@@ -162,6 +156,15 @@ export default {
|
||||
this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0
|
||||
},
|
||||
computed: {
|
||||
operateTypeMap() {
|
||||
return new Map([
|
||||
['create', this.$t('create')],
|
||||
['update', this.$t('update')],
|
||||
['delete', this.$t('delete')],
|
||||
['trigger_apply', this.$t('acl.apply')],
|
||||
['trigger_cancel', this.$t('cancel')],
|
||||
])
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
@@ -270,9 +273,11 @@ export default {
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => id2roles[i].name).join(',')
|
||||
const { name, resource_type_id, wildcard, permissions, enabled } = item.current
|
||||
item.changeDescription = `新增触发器:${name}\n资源类型:${
|
||||
item.changeDescription = `${this.$t('acl.addTrigger')}:${name}\n${this.$t('acl.resourceType')}: ${
|
||||
id2resource_types[resource_type_id].name
|
||||
},资源名:${wildcard || ''},角色:[${newStr}]\n权限:${permissions}\n状态:${enabled}`
|
||||
},this.$t('acl.resourceName'):${wildcard || ''},${this.$t(
|
||||
'acl.role2'
|
||||
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
|
||||
break
|
||||
}
|
||||
case 'update': {
|
||||
@@ -282,15 +287,14 @@ export default {
|
||||
const oldVal = item.origin[key]
|
||||
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
|
||||
if (oldVal === null) {
|
||||
const str = ` 【 ${key} : 改为 ${newVal} 】 `
|
||||
const str = ` 【 ${key} : -> ${newVal} 】 `
|
||||
item.changeDescription += str
|
||||
} else {
|
||||
const str = ` 【 ${key} : 由 ${oldVal} 改为 ${newVal} 】 `
|
||||
item.changeDescription += str
|
||||
item.changeDescription += ` 【 ${key} :${oldVal} -> ${newVal} 】 `
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!item.changeDescription) item.changeDescription = '没有修改'
|
||||
if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
|
||||
break
|
||||
}
|
||||
case 'delete': {
|
||||
@@ -298,9 +302,11 @@ export default {
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => id2roles[i].name).join(',')
|
||||
const { name, resource_type_id, wildcard, permissions, enabled } = item.origin
|
||||
item.changeDescription = `删除触发器:${name}\n资源类型:${
|
||||
item.changeDescription = `${this.$t('acl.deleteTrigger')}: ${name}\n${this.$t('acl.resourceType')}: ${
|
||||
id2resource_types[resource_type_id].name
|
||||
},资源名:${wildcard || ''},角色:[${newStr}]\n权限:${permissions}\n状态:${enabled}`
|
||||
},${this.$t('acl.resourceName')}: ${wildcard || ''},${this.$t(
|
||||
'acl.role2'
|
||||
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
|
||||
break
|
||||
}
|
||||
case 'trigger_apply': {
|
||||
@@ -308,9 +314,11 @@ export default {
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => id2roles[i].name).join(',')
|
||||
const { name, resource_type_id, wildcard, permissions, enabled } = item.current
|
||||
item.changeDescription = `应用触发器:${name}\n资源类型:${
|
||||
item.changeDescription = `${this.$t('acl.applyTrigger')}: ${name}\n${this.$t('acl.resourceType')}: ${
|
||||
id2resource_types[resource_type_id].name
|
||||
},资源名:${wildcard || ''},角色:[${newStr}]\n权限:${permissions}\n状态:${enabled}`
|
||||
},${this.$t('acl.resourceName')}: ${wildcard || ''},${this.$t(
|
||||
'acl.role2'
|
||||
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
|
||||
break
|
||||
}
|
||||
case 'trigger_cancel': {
|
||||
@@ -318,9 +326,11 @@ export default {
|
||||
const newArr = str.slice(1, str.length - 1).split(', ')
|
||||
const newStr = newArr.map((i) => id2roles[i].name).join(',')
|
||||
const { name, resource_type_id, wildcard, permissions, enabled } = item.current
|
||||
item.changeDescription = `取消触发器:${name}\n资源类型:${
|
||||
item.changeDescription = `${this.$t('acl.cancelTrigger')}: ${name}\n${this.$t('acl.resourceType')}: ${
|
||||
id2resource_types[resource_type_id].name
|
||||
},资源名:${wildcard || ''},角色:[${newStr}]\n权限:${permissions}\n状态:${enabled}`
|
||||
},${this.$t('acl.resourceName')}: ${wildcard || ''},${this.$t(
|
||||
'acl.role2'
|
||||
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div class="acl-resource-types">
|
||||
<div class="acl-resource-types-header">
|
||||
<a-button @click="handleCreate" type="primary" style="margin-right: 0.3rem">{{ btnName }}</a-button>
|
||||
<a-button @click="handleCreate" type="primary" style="margin-right: 0.3rem">{{
|
||||
$t('acl.addResourceType')
|
||||
}}</a-button>
|
||||
<a-input-search
|
||||
class="ops-input"
|
||||
:style="{ display: 'inline', marginLeft: '10px', width: '200px' }"
|
||||
placeholder="搜索 | 资源类型名"
|
||||
:placeholder="`${$t('search')} | ${$t('acl.resourceType')}`"
|
||||
v-model="searchName"
|
||||
allowClear
|
||||
@search="
|
||||
@@ -28,28 +30,28 @@
|
||||
<!-- 1 -->
|
||||
<vxe-table-column
|
||||
field="name"
|
||||
title="资源类型名"
|
||||
:title="$t('acl.resourceType')"
|
||||
:min-width="175"
|
||||
fixed="left"
|
||||
show-overflow
|
||||
></vxe-table-column>
|
||||
|
||||
<!-- 2 -->
|
||||
<vxe-table-column field="description" title="描述" :min-width="175"></vxe-table-column>
|
||||
<vxe-table-column field="description" :title="$t('desc')" :min-width="175"></vxe-table-column>
|
||||
|
||||
<!-- 3 -->
|
||||
<vxe-table-column field="id" title="权限" :min-width="300">
|
||||
<vxe-table-column field="id" :title="$t('acl.permission')" :min-width="300">
|
||||
<template #default="{ row }">
|
||||
<a-tag color="cyan" v-for="perm in id2perms[row.id]" :key="perm.id">{{ perm.name }}</a-tag>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
||||
<!-- 4 -->
|
||||
<vxe-table-column field="action" title="操作" :width="100" fixed="right">
|
||||
<vxe-table-column field="action" :title="$t('operation')" :width="100" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a @click="handleEdit(row)"><a-icon type="edit"/></a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm title="确认删除?" @confirm="handleDelete(row)" okText="是" cancelText="否">
|
||||
<a-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete(row)">
|
||||
<a style="color: red"><a-icon type="delete"/></a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
@@ -87,42 +89,12 @@ export default {
|
||||
loading: false,
|
||||
groups: [],
|
||||
id2perms: {},
|
||||
btnName: '新增资源类型',
|
||||
pageSizeOptions: [10, 25, 50, 100],
|
||||
tablePage: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 50,
|
||||
},
|
||||
tableColumns: [
|
||||
{
|
||||
title: '资源类型名',
|
||||
field: 'name',
|
||||
minWidth: '175px',
|
||||
fixed: 'left',
|
||||
showOverflow: 'tooltip',
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
field: 'description',
|
||||
minWidth: '175px',
|
||||
},
|
||||
{
|
||||
title: '权限',
|
||||
field: 'id',
|
||||
minWidth: '300px',
|
||||
slots: {
|
||||
default: 'id_default',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
field: 'action',
|
||||
minWidth: '175px',
|
||||
slots: { default: 'action_default' },
|
||||
fixed: 'right',
|
||||
},
|
||||
],
|
||||
searchName: '',
|
||||
}
|
||||
},
|
||||
@@ -200,15 +172,10 @@ export default {
|
||||
},
|
||||
deleteResourceType(id) {
|
||||
deleteResourceTypeById(id).then((res) => {
|
||||
this.$message.success(`删除成功`)
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
this.handleOk()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
},
|
||||
// requestFailed(err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// },
|
||||
handlePageChange({ currentPage, pageSize }) {
|
||||
this.tablePage.currentPage = currentPage
|
||||
this.tablePage.pageSize = pageSize
|
||||
|
@@ -6,10 +6,10 @@
|
||||
</a-tabs>
|
||||
<div class="acl-resources-header">
|
||||
<a-space>
|
||||
<a-button @click="handleCreate" type="primary">{{ btnName }}</a-button>
|
||||
<a-button @click="handleCreate" type="primary">{{ $t('acl.addResource') }}</a-button>
|
||||
<a-input-search
|
||||
class="ops-input"
|
||||
placeholder="搜索 | 资源名"
|
||||
:placeholder="`${$t('search')} | ${$t('acl.resource')}`"
|
||||
v-model="searchName"
|
||||
@search="
|
||||
() => {
|
||||
@@ -20,10 +20,10 @@
|
||||
></a-input-search>
|
||||
|
||||
<div v-if="!!selectedRows.length" class="ops-list-batch-action">
|
||||
<span @click="handleBatchPerm">授权</span>
|
||||
<span @click="handleBatchPerm">{{ $t('grant') }}</span>
|
||||
<a-divider type="vertical" />
|
||||
<span @click="handleBatchRevoke">权限回收</span>
|
||||
<span>选取: {{ selectedRows.length }} 项</span>
|
||||
<span @click="handleBatchRevoke">{{ $t('acl.revoke') }}</span>
|
||||
<span>{{ $t('selectRows', { rows: selectedRows.length }) }}</span>
|
||||
</div>
|
||||
</a-space>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
$refs.resourceBatchPerm.open(currentType.id)
|
||||
}
|
||||
"
|
||||
>便捷授权</a-button
|
||||
>{{ $t('acl.convenient') }}</a-button
|
||||
>
|
||||
<a-switch
|
||||
v-model="isGroup"
|
||||
@@ -50,7 +50,7 @@
|
||||
$refs.xTable && $refs.xTable.getVxetableRef().clearCheckboxReserve()
|
||||
}
|
||||
"
|
||||
un-checked-children="组"
|
||||
:un-checked-children="$t('acl.group2')"
|
||||
></a-switch>
|
||||
</a-space>
|
||||
</div>
|
||||
@@ -62,61 +62,62 @@
|
||||
:data="tableData"
|
||||
highlight-hover-row
|
||||
:height="`${windowHeight - 250}px`"
|
||||
:checkbox-config="{ reserve: true }"
|
||||
:checkbox-config="{ reserve: true, highlight: true, range: true }"
|
||||
@checkbox-change="changeCheckbox"
|
||||
@checkbox-all="changeCheckbox"
|
||||
@checkbox-range-end="onSelectRangeEnd"
|
||||
ref="xTable"
|
||||
row-id="id"
|
||||
show-overflow
|
||||
resizable
|
||||
>
|
||||
<!-- 1 -->
|
||||
<vxe-table-column type="checkbox" fixed="left" :width="45"></vxe-table-column>
|
||||
<vxe-table-column type="checkbox" fixed="left" :width="60"></vxe-table-column>
|
||||
|
||||
<!-- 2 -->
|
||||
|
||||
<vxe-table-column field="name" title="资源名" :min-widh="150" fixed="left" show-overflow>
|
||||
<vxe-table-column field="name" :title="$t('acl.resourceName')" :min-widh="150" fixed="left" show-overflow>
|
||||
<template #title="{row}">
|
||||
{{ row.isGroup ? '资源组名' : '资源名' }}
|
||||
{{ row.isGroup ? $t('acl.groupName') : $t('acl.resourceName') }}
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
||||
<!-- 3 -->
|
||||
<vxe-table-column field="user" title="创建者" :min-widh="100"> </vxe-table-column>
|
||||
<vxe-table-column field="user" :title="$t('acl.creator')" :min-widh="100"> </vxe-table-column>
|
||||
|
||||
<!-- 4 -->
|
||||
<vxe-table-column field="created_at" title="创建时间" :min-widh="220" align="center"> </vxe-table-column>
|
||||
<vxe-table-column field="created_at" :title="$t('created_at')" :min-widh="220" align="center"> </vxe-table-column>
|
||||
|
||||
<!-- 5 -->
|
||||
<vxe-table-column field="updated_at" title="最后修改时间" :min-widh="220" fixed="center"> </vxe-table-column>
|
||||
<vxe-table-column field="updated_at" :title="$t('updated_at')" :min-widh="220" fixed="center"> </vxe-table-column>
|
||||
|
||||
<!-- 6 -->
|
||||
|
||||
<vxe-table-column
|
||||
field="action"
|
||||
title="操作"
|
||||
:title="$t('operation')"
|
||||
:min-widh="200"
|
||||
fixed="right"
|
||||
align="center"
|
||||
show-overflow>
|
||||
<template #default="{row}">
|
||||
<span v-show="isGroup">
|
||||
<a @click="handleDisplayMember(row)">成员</a>
|
||||
<a @click="handleDisplayMember(row)">{{ $t('acl.member') }}</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="handleGroupEdit(row)">编辑</a>
|
||||
<a @click="handleGroupEdit(row)">{{ $t('edit') }}</a>
|
||||
<a-divider type="vertical" />
|
||||
</span>
|
||||
<a-tooltip title="查看授权">
|
||||
<a-tooltip :title="$t('acl.viewAuth')">
|
||||
<a @click="handlePerm(row)"><a-icon type="eye"/></a>
|
||||
</a-tooltip>
|
||||
<a-divider type="vertical" />
|
||||
<a-tooltip title="授权">
|
||||
<a-tooltip :title="$t('grant')">
|
||||
<a :style="{ color: '#4bbb13' }" @click="handlePermManage(row)">
|
||||
<a-icon type="usergroup-add" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm title="确认删除?" @confirm="handleDelete(row)" @cancel="cancel" okText="是" cancelText="否">
|
||||
<a-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete(row)" @cancel="cancel" :okText="$t('yes')" :cancelText="$t('no')">
|
||||
<a style="color: red"><a-icon type="delete"/></a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
@@ -137,7 +138,7 @@
|
||||
</div>
|
||||
<div v-else style="text-align: center;margin-top:20%">
|
||||
<a-icon style="font-size:50px; margin-bottom: 20px; color: orange" type="info-circle" />
|
||||
<h3>暂无类型信息,请先添加资源类型!</h3>
|
||||
<h3>{{ $t('acl.addTypeTips') }}</h3>
|
||||
</div>
|
||||
<resourceForm ref="resourceForm" @fresh="handleOk"> </resourceForm>
|
||||
<resourcePermForm ref="resourcePermForm"> </resourcePermForm>
|
||||
@@ -187,7 +188,6 @@ export default {
|
||||
pageSize: 50,
|
||||
},
|
||||
tableData: [],
|
||||
btnName: '新增资源',
|
||||
isGroup: false,
|
||||
allResourceTypes: [],
|
||||
currentType: { id: 0 },
|
||||
@@ -196,7 +196,6 @@ export default {
|
||||
selectedRows: [],
|
||||
}
|
||||
},
|
||||
|
||||
beforeCreate() {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
@@ -281,22 +280,16 @@ export default {
|
||||
deleteResource(id) {
|
||||
if (!this.isGroup) {
|
||||
deleteResourceById(id, { app_id: this.$route.name.split('_')[0] }).then((res) => {
|
||||
this.$message.success(`删除成功`)
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
this.handleOk()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
} else {
|
||||
deleteResourceGroup(id).then((res) => {
|
||||
this.$message.success(`删除成功`)
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
this.handleOk()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
}
|
||||
},
|
||||
// requestFailed(err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// },
|
||||
cancel() {},
|
||||
handlePageChange({ currentPage, pageSize }) {
|
||||
this.tablePage.currentPage = currentPage
|
||||
@@ -309,6 +302,10 @@ export default {
|
||||
.getVxetableRef()
|
||||
.getCheckboxRecords()
|
||||
.concat(this.$refs.xTable.getVxetableRef().getCheckboxReserveRecords())
|
||||
console.log(this.selectedRows)
|
||||
},
|
||||
onSelectRangeEnd({ records }) {
|
||||
this.selectedRows = records
|
||||
},
|
||||
handleBatchPerm() {
|
||||
this.$refs['resourcePermManageForm'].editPerm(this.selectedRows, this.isGroup)
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="acl-roles">
|
||||
<div class="acl-roles-header">
|
||||
<a-button @click="handleCreate" type="primary">{{ btnName }}</a-button>
|
||||
<a-button @click="handleCreate" type="primary">{{ $t('acl.addVisualRole') }}</a-button>
|
||||
<a-input-search
|
||||
class="ops-input"
|
||||
allowClear
|
||||
:style="{ display: 'inline', marginLeft: '10px', width: '200px' }"
|
||||
placeholder="搜索 | 角色名"
|
||||
:placeholder="`${$t('search')} | ${$t('acl.role')}`"
|
||||
v-model="searchName"
|
||||
@search="
|
||||
() => {
|
||||
@@ -15,7 +15,7 @@
|
||||
}
|
||||
"
|
||||
></a-input-search>
|
||||
<a-checkbox :checked="is_all" @click="handleClickBoxChange">所有角色</a-checkbox>
|
||||
<a-checkbox :checked="is_all" @click="handleClickBoxChange">{{ $t('acl.allRole') }}</a-checkbox>
|
||||
</div>
|
||||
<a-spin :spinning="loading">
|
||||
<ops-table
|
||||
@@ -31,22 +31,23 @@
|
||||
>
|
||||
<vxe-table-column
|
||||
field="name"
|
||||
title="角色名"
|
||||
:title="$t('acl.role')"
|
||||
:min-width="150"
|
||||
align="left"
|
||||
fixed="left"
|
||||
sortable
|
||||
show-overflow>
|
||||
show-overflow
|
||||
>
|
||||
</vxe-table-column>
|
||||
|
||||
<!-- 2 -->
|
||||
<vxe-table-column field="is_app_admin" title="管理员" :min-width="100" align="center">
|
||||
<vxe-table-column field="is_app_admin" :title="$t('admin')" :min-width="100" align="center">
|
||||
<template #default="{row}">
|
||||
<a-icon type="check" v-if="row.is_app_admin" />
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
||||
<vxe-table-column field="id" title="继承自" :min-width="150">
|
||||
<vxe-table-column field="id" :title="$t('acl.inheritedFrom')" :min-width="150">
|
||||
<template #default="{row}">
|
||||
<a-tag color="cyan" v-for="role in id2parents[row.id]" :key="role.id">{{ role.name }}</a-tag>
|
||||
</template>
|
||||
@@ -54,12 +55,12 @@
|
||||
|
||||
<vxe-table-column
|
||||
field="uid"
|
||||
title="虚拟角色"
|
||||
:width="100"
|
||||
:title="$t('acl.visualRole')"
|
||||
:width="120"
|
||||
align="center"
|
||||
:filters="[
|
||||
{ label: '是', value: 1 },
|
||||
{ label: '否', value: 0 },
|
||||
{ label: $t('yes'), value: 1 },
|
||||
{ label: $t('no'), value: 0 },
|
||||
]"
|
||||
:filterMultiple="false"
|
||||
:filter-method="
|
||||
@@ -69,14 +70,14 @@
|
||||
"
|
||||
>
|
||||
<template #default="{row}">
|
||||
{{ row.uid ? '否' : '是' }}
|
||||
{{ row.uid ? $t('no') : $t('yes') }}
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
||||
<vxe-table-column field="action" title="操作" :width="120" fixed="right">
|
||||
<vxe-table-column field="action" :title="$t('operation')" :width="120" fixed="right">
|
||||
<template #default="{row}">
|
||||
<a-space>
|
||||
<a-tooltip title="资源列表">
|
||||
<a-tooltip :title="$t('acl.resourceList')">
|
||||
<a
|
||||
v-if="$route.name !== 'acl_roles'"
|
||||
@click="handleDisplayUserResource(row)"
|
||||
@@ -85,12 +86,18 @@
|
||||
/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
title="用户列表"
|
||||
:title="$t('acl.userList')"
|
||||
v-if="!row.uid"
|
||||
><a @click="handleDisplayUserUnderRole(row)"><a-icon type="team"/></a
|
||||
></a-tooltip>
|
||||
<a @click="handleEdit(row)"><a-icon type="edit"/></a>
|
||||
<a-popconfirm title="确认删除?" @confirm="handleDelete(row)" @cancel="cancel" okText="是" cancelText="否">
|
||||
<a-popconfirm
|
||||
:title="$t('confirmDelete')"
|
||||
@confirm="handleDelete(row)"
|
||||
@cancel="cancel"
|
||||
:okText="$t('yes')"
|
||||
:cancelText="$t('no')"
|
||||
>
|
||||
<a style="color: red"><a-icon type="delete"/></a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
@@ -138,52 +145,6 @@ export default {
|
||||
currentPage: 1,
|
||||
pageSize: 50,
|
||||
},
|
||||
tableColumns: [
|
||||
{
|
||||
title: '角色名',
|
||||
field: 'name',
|
||||
sortable: true,
|
||||
minWidth: '150px',
|
||||
fixed: 'left',
|
||||
showOverflow: 'tooltip',
|
||||
},
|
||||
{
|
||||
title: '管理员',
|
||||
field: 'is_app_admin',
|
||||
minWidth: '100px',
|
||||
align: 'center',
|
||||
slots: { default: 'is_app_admin_default' },
|
||||
},
|
||||
{
|
||||
title: '继承自',
|
||||
field: 'id',
|
||||
minWidth: '150px',
|
||||
slots: { default: 'inherit_default' },
|
||||
},
|
||||
{
|
||||
title: '虚拟角色',
|
||||
field: 'uid',
|
||||
minWidth: '100px',
|
||||
align: 'center',
|
||||
filters: [
|
||||
{ label: '是', value: 1 },
|
||||
{ label: '否', value: 0 },
|
||||
],
|
||||
filterMultiple: false,
|
||||
filterMethod: ({ value, row }) => {
|
||||
return value === !row.uid
|
||||
},
|
||||
slots: { default: 'isVisualRole_default' },
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
minWidth: '280px',
|
||||
field: 'action',
|
||||
fixed: 'right',
|
||||
slots: { default: 'action_default' },
|
||||
},
|
||||
],
|
||||
btnName: '新增虚拟角色',
|
||||
is_all: this.$route.name === 'acl_roles',
|
||||
tableData: [],
|
||||
allRoles: [],
|
||||
@@ -286,15 +247,10 @@ export default {
|
||||
|
||||
deleteRole(id) {
|
||||
deleteRoleById(id, { app_id: this.$route.name.split('_')[0] }).then((res) => {
|
||||
this.$message.success(`删除成功`)
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
this.handleOk()
|
||||
})
|
||||
// .catch(err => this.requestFailed(err))
|
||||
},
|
||||
// requestFailed(err) {
|
||||
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
|
||||
// this.$message.error(`${msg}`)
|
||||
// },
|
||||
cancel(e) {
|
||||
return false
|
||||
},
|
||||
|
@@ -15,9 +15,9 @@
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label=" " :colon="false">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="changeVisible">{{ !visible ? '查看' : '隐藏' }}</a-button>
|
||||
<a-button type="danger" ghost @click="handleSumbit">重置</a-button>
|
||||
<!-- <a-button @click="handleCancel">取消</a-button> -->
|
||||
<a-button type="primary" @click="changeVisible">{{ !visible ? $t('view') : $t('hide') }}</a-button>
|
||||
<a-button type="danger" ghost @click="handleSumbit">{{ $t('reset') }}</a-button>
|
||||
<!-- <a-button @click="handleCancel">{{ $t('cancel') }}</a-button> -->
|
||||
</a-space>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
@@ -62,13 +62,13 @@ export default {
|
||||
handleSumbit() {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: '重置',
|
||||
content: '确定重置用户密钥?',
|
||||
title: that.$t('reset'),
|
||||
content: that.$t('acl.confirmResetSecret'),
|
||||
onOk() {
|
||||
that.$refs.secretKeyForm.validate((valid) => {
|
||||
if (valid) {
|
||||
updateSecret().then((res) => {
|
||||
that.$message.success('重置成功')
|
||||
that.$message.success(that.$t('operateSuccess'))
|
||||
const { key, secret } = res
|
||||
that.form = { key, secret }
|
||||
})
|
||||
|
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="acl-trigger">
|
||||
<div class="acl-trigger-header">
|
||||
<a-button type="primary" @click="handleCreateTrigger">新增触发器</a-button>
|
||||
<a-button type="primary" @click="handleCreateTrigger">{{ $t('acl.addTrigger') }}</a-button>
|
||||
<a-input-search
|
||||
class="ops-input"
|
||||
:style="{ display: 'inline', marginLeft: '10px', width: '200px' }"
|
||||
placeholder="搜索 | 名称"
|
||||
:placeholder="`${$t('search')} | ${$t('name')}`"
|
||||
v-model="searchName"
|
||||
allowClear
|
||||
@search="filter"
|
||||
@@ -46,18 +46,18 @@
|
||||
<a-tag v-for="(p, index) in row.permissions" :key="index">{{ p }}</a-tag>
|
||||
</template>
|
||||
<template #enabled_default="{row}">
|
||||
<a-tag v-if="row.enabled" color="#2db7f5">启用</a-tag>
|
||||
<a-tag v-else color="grey">禁用</a-tag>
|
||||
<a-tag v-if="row.enabled" color="#2db7f5">{{ $t('acl.enable') }}</a-tag>
|
||||
<a-tag v-else color="grey">{{ $t('acl.disable') }}</a-tag>
|
||||
</template>
|
||||
<template #action_default="{row}">
|
||||
<a-space>
|
||||
<a-tooltip title="应用">
|
||||
<a-tooltip :title="$t('acl.apply')">
|
||||
<a @click="handleApplyTrigger(row)" :style="{ color: '#0f9d58' }"><a-icon type="appstore"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="取消">
|
||||
<a-tooltip :title="$t('cancel')">
|
||||
<a @click="handleCancelTrigger(row)" :style="{ color: 'orange' }"><a-icon type="stop"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="查看正则匹配结果">
|
||||
<a-tooltip :title="$t('acl.viewMatchResult')">
|
||||
<a @click="handlePattern(row)" :style="{ color: 'purple' }"><a-icon type="eye"/></a>
|
||||
</a-tooltip>
|
||||
<a @click="handleEditTrigger(row)"><a-icon type="edit"/></a>
|
||||
@@ -67,7 +67,7 @@
|
||||
<template slot="empty">
|
||||
<div>
|
||||
<img :style="{ width: '100px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>暂无数据</div>
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-grid>
|
||||
@@ -102,9 +102,19 @@ export default {
|
||||
triggers: [],
|
||||
id2parents: [],
|
||||
id2perms: {},
|
||||
tableColumns: [
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
windowHeight: (state) => state.windowHeight,
|
||||
}),
|
||||
app_id() {
|
||||
return this.$route.name.split('_')[0]
|
||||
},
|
||||
tableColumns() {
|
||||
return [
|
||||
{
|
||||
title: '名称',
|
||||
title: this.$t('name'),
|
||||
field: 'name',
|
||||
sortable: true,
|
||||
minWidth: '150px',
|
||||
@@ -112,7 +122,7 @@ export default {
|
||||
showOverflow: 'tooltip',
|
||||
},
|
||||
{
|
||||
title: '资源名',
|
||||
title: this.$t('acl.resource'),
|
||||
field: 'wildcard',
|
||||
minWidth: '250px',
|
||||
showOverflow: 'tooltip',
|
||||
@@ -121,15 +131,15 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '资源类型',
|
||||
title: this.$t('acl.resourceType'),
|
||||
field: 'resource_type_id',
|
||||
minWidth: '100px',
|
||||
minWidth: '120px',
|
||||
slots: {
|
||||
default: 'resourceTypeRender_default',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
title: this.$t('acl.creator'),
|
||||
field: 'users',
|
||||
minWidth: '150px',
|
||||
showOverflow: 'tooltip',
|
||||
@@ -138,7 +148,7 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
title: this.$t('acl.allRole'),
|
||||
field: 'roles',
|
||||
minWidth: '150px',
|
||||
slots: {
|
||||
@@ -172,7 +182,7 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '权限',
|
||||
title: this.$t('acl.permission'),
|
||||
field: 'permissions',
|
||||
minWidth: '250px',
|
||||
slots: {
|
||||
@@ -180,7 +190,7 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
title: this.$t('status'),
|
||||
field: 'enabled',
|
||||
minWidth: '100px',
|
||||
slots: {
|
||||
@@ -188,7 +198,7 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
title: this.$t('operation'),
|
||||
field: 'action',
|
||||
width: '120px',
|
||||
fixed: 'right',
|
||||
@@ -196,8 +206,8 @@ export default {
|
||||
default: 'action_default',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadRoles()
|
||||
@@ -206,15 +216,6 @@ export default {
|
||||
beforeMount() {
|
||||
this.loadTriggers()
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState({
|
||||
windowHeight: (state) => state.windowHeight,
|
||||
}),
|
||||
app_id() {
|
||||
return this.$route.name.split('_')[0]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadTriggers() {
|
||||
this.searchName = ''
|
||||
@@ -244,11 +245,11 @@ export default {
|
||||
handleDeleteTrigger(record) {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: '删除',
|
||||
content: '确认删除该触发器吗?',
|
||||
title: that.$t('warning'),
|
||||
content: that.$t('acl.confirmDeleteTrigger'),
|
||||
onOk() {
|
||||
deleteTrigger(record.id).then((res) => {
|
||||
that.$message.success('删除成功')
|
||||
that.$message.success(that.$t('deleteSuccess'))
|
||||
that.loadTriggers()
|
||||
})
|
||||
// .catch(err => that.$httpError(err))
|
||||
@@ -258,11 +259,11 @@ export default {
|
||||
handleApplyTrigger(record) {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: '规则应用',
|
||||
content: '是否确定应用该触发器?',
|
||||
title: that.$t('acl.ruleApply'),
|
||||
content: that.$t('acl.triggerTip1'),
|
||||
onOk() {
|
||||
applyTrigger(record.id).then((res) => {
|
||||
that.$message.success('提交成功!')
|
||||
that.$message.success(that.$t('operateSuccess'))
|
||||
})
|
||||
// .catch(err => that.$httpError(err))
|
||||
},
|
||||
@@ -271,11 +272,11 @@ export default {
|
||||
handleCancelTrigger(record) {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: '规则应用',
|
||||
content: '是否取消应用该触发器?',
|
||||
title: that.$t('acl.ruleApply'),
|
||||
content: that.$t('acl.triggerTip2'),
|
||||
onOk() {
|
||||
cancelTrigger(record.id).then((res) => {
|
||||
that.$message.success('提交成功!')
|
||||
that.$message.success(that.$t('operateSuccess'))
|
||||
})
|
||||
// .catch(err => that.$httpError(err))
|
||||
},
|
||||
|
@@ -5,8 +5,8 @@
|
||||
<a-input-search
|
||||
class="ops-input"
|
||||
allowClear
|
||||
:style="{ display: 'inline', marginLeft: '10px' }"
|
||||
placeholder="搜索 | 用户名、中文名"
|
||||
:style="{ width: '300px', display: 'inline', marginLeft: '10px' }"
|
||||
:placeholder="`${$t('search')} | ${$t('acl.nickname')} 、 ${$t('acl.username')}`"
|
||||
v-model="searchName"
|
||||
></a-input-search>
|
||||
</div>
|
||||
@@ -29,10 +29,10 @@
|
||||
<a :disabled="isAclAdmin ? false : true" @click="handleEdit(row)">
|
||||
<a-icon type="edit" />
|
||||
</a>
|
||||
<a-tooltip title="权限汇总">
|
||||
<a-tooltip :title="$t('acl.summaryPermissions')">
|
||||
<a @click="handlePermCollect(row)"><a-icon type="solution"/></a>
|
||||
</a-tooltip>
|
||||
<a-popconfirm :title="`确认删除【${row.nickname || row.username}】?`" @confirm="deleteUser(row.uid)">
|
||||
<a-popconfirm :title="$t('confirmDelete')" @confirm="deleteUser(row.uid)">
|
||||
<a :style="{ color: 'red' }"><ops-icon type="icon-xianxing-delete"/></a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
@@ -59,48 +59,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
tableColumns: [
|
||||
{
|
||||
title: '用户名',
|
||||
field: 'username',
|
||||
sortable: true,
|
||||
minWidth: '100px',
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: '中文名',
|
||||
field: 'nickname',
|
||||
minWidth: '100px',
|
||||
},
|
||||
{
|
||||
title: '加入时间',
|
||||
field: 'date_joined',
|
||||
minWidth: '160px',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
title: '锁定',
|
||||
field: 'block',
|
||||
width: '150px',
|
||||
align: 'center',
|
||||
slots: {
|
||||
default: 'block_default',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
field: 'action',
|
||||
width: '150px',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
slots: {
|
||||
default: 'action_default',
|
||||
},
|
||||
},
|
||||
],
|
||||
onDutuUids: [],
|
||||
btnName: '新增用户',
|
||||
allUsers: [],
|
||||
tableData: [],
|
||||
searchName: '',
|
||||
@@ -125,6 +84,51 @@ export default {
|
||||
return false
|
||||
}
|
||||
},
|
||||
tableColumns() {
|
||||
return [
|
||||
{
|
||||
title: this.$t('acl.username'),
|
||||
field: 'username',
|
||||
sortable: true,
|
||||
minWidth: '100px',
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: this.$t('acl.nickname'),
|
||||
field: 'nickname',
|
||||
minWidth: '100px',
|
||||
},
|
||||
{
|
||||
title: this.$t('acl.joined_at'),
|
||||
field: 'date_joined',
|
||||
minWidth: '160px',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
title: this.$t('acl.block'),
|
||||
field: 'block',
|
||||
width: '150px',
|
||||
align: 'center',
|
||||
slots: {
|
||||
default: 'block_default',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: this.$t('operation'),
|
||||
field: 'action',
|
||||
width: '150px',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
slots: {
|
||||
default: 'action_default',
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
btnName() {
|
||||
return this.$t('acl.addUser')
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
searchName: {
|
||||
@@ -175,7 +179,7 @@ export default {
|
||||
},
|
||||
deleteUser(uid) {
|
||||
deleteUserById(uid).then((res) => {
|
||||
this.$message.success(`删除成功!`)
|
||||
this.$message.success(this.$t('deleteSuccess'))
|
||||
this.handleOk()
|
||||
})
|
||||
},
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 30 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 143 KiB |
@@ -63,7 +63,7 @@ export default {
|
||||
updateCI(this.row.ci_id || this.row._id, {
|
||||
[`${this.column.property}`]: this.default_value_json_right ? this.jsonData : {},
|
||||
}).then(() => {
|
||||
this.$message.success('保存成功!')
|
||||
this.$message.success(this.$t('saveSuccess'))
|
||||
this.handleCancel()
|
||||
this.$emit('jsonEditorOk', this.row, this.column, this.default_value_json_right ? this.jsonData : {})
|
||||
})
|
||||
|
@@ -7,7 +7,7 @@
|
||||
width: '200px',
|
||||
height: `${height}px`,
|
||||
}"
|
||||
:titles="['未选属性', '已选属性']"
|
||||
:titles="[$t('cmdb.components.unselectAttributes'), $t('cmdb.components.selectAttributes')]"
|
||||
:render="(item) => item.title"
|
||||
:targetKeys="targetKeys"
|
||||
@change="handleChange"
|
||||
@@ -16,7 +16,7 @@
|
||||
:filterOption="filterOption"
|
||||
class="cmdb-transfer"
|
||||
>
|
||||
<span slot="notFoundContent">暂无数据</span>
|
||||
<span slot="notFoundContent">{{ $t('noData') }}</span>
|
||||
<template slot="children" slot-scope="{ props: { direction, filteredItems } }">
|
||||
<div class="ant-transfer-list-content" v-if="direction === 'right'">
|
||||
<draggable :value="targetKeys" animation="300" @end="dragEnd" :disabled="!isSortable">
|
||||
@@ -27,10 +27,11 @@
|
||||
:style="{ height: '38px' }"
|
||||
>
|
||||
<li
|
||||
:class="{
|
||||
'ant-transfer-list-content-item': true,
|
||||
'ant-transfer-list-content-item-selected': selectedKeys.includes(item.key),
|
||||
}"
|
||||
:class="
|
||||
`ant-transfer-list-content-item ${
|
||||
selectedKeys.includes(item.key) ? 'ant-transfer-list-content-item-selected' : ''
|
||||
}`
|
||||
"
|
||||
@click="setSelectedKeys(item)"
|
||||
>
|
||||
<OpsMoveIcon class="move-icon" />
|
||||
@@ -62,9 +63,11 @@
|
||||
:style="{ height: '38px' }"
|
||||
>
|
||||
<li
|
||||
:class="`ant-transfer-list-content-item ${
|
||||
:class="
|
||||
`ant-transfer-list-content-item ${
|
||||
selectedKeys.includes(item.key) ? 'ant-transfer-list-content-item-selected' : ''
|
||||
}`"
|
||||
}`
|
||||
"
|
||||
@click="setSelectedKeys(item)"
|
||||
>
|
||||
<div class="ant-transfer-list-content-item-text" style="display: inline">
|
||||
@@ -83,7 +86,7 @@
|
||||
</template>
|
||||
</a-transfer>
|
||||
<div v-if="hasFooter" :style="{ marginTop: '5px', height: '20px' }">
|
||||
<a-button :style="{ float: 'right' }" size="small" @click="handleSubmit" type="primary">确定</a-button>
|
||||
<a-button :style="{ float: 'right' }" size="small" @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -110,12 +113,12 @@ export default {
|
||||
default: true,
|
||||
},
|
||||
isSortable: {
|
||||
// 右侧是否可排序
|
||||
// Is the right side sortable?
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
isFixable: {
|
||||
// 右侧是否可固定
|
||||
// Can the right side be fixed?
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
@@ -1,21 +1,30 @@
|
||||
<template>
|
||||
<a-modal :visible="visible" title="导出数据" @cancel="handleCancel" okText="导出" @ok="handleOk">
|
||||
<a-modal
|
||||
:visible="visible"
|
||||
:title="$t('cmdb.components.downloadCI')"
|
||||
@cancel="handleCancel"
|
||||
@ok="handleOk"
|
||||
width="700px"
|
||||
>
|
||||
<a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }">
|
||||
<a-form-item label="文件名">
|
||||
<a-form-item :label="$t('cmdb.components.filename')">
|
||||
<a-input
|
||||
placeholder="请输入文件名"
|
||||
v-decorator="['filename', { rules: [{ required: true, message: '请输入文件名' }] }]"
|
||||
:placeholder="$t('cmdb.components.filenameInputTips')"
|
||||
v-decorator="['filename', { rules: [{ required: true, message: $t('cmdb.components.filenameInputTips') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="保存类型">
|
||||
<a-form-item :label="$t('cmdb.components.saveType')">
|
||||
<a-select
|
||||
placeholder="请选择保存类型"
|
||||
v-decorator="['type', { rules: [{ required: true, message: '请选择保存类型' }], initialValue: 'xlsx' }]"
|
||||
:placeholder="$t('cmdb.components.saveTypeTips')"
|
||||
v-decorator="[
|
||||
'type',
|
||||
{ rules: [{ required: true, message: $t('cmdb.components.saveTypeTips') }], initialValue: 'xlsx' },
|
||||
]"
|
||||
>
|
||||
<a-select-option v-for="item in typeList" :key="item.id" :values="item.id">{{ item.label }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="选择字段">
|
||||
<a-form-item :label="$t('cmdb.ciType.selectAttributes')">
|
||||
<div
|
||||
:style="{
|
||||
paddingLeft: '26px',
|
||||
@@ -29,7 +38,7 @@
|
||||
:checked="checkAll"
|
||||
@change="onCheckAllChange"
|
||||
:style="{ marginRight: '10px' }"
|
||||
/>全选
|
||||
/>{{ $t('checkAll') }}
|
||||
</div>
|
||||
<div
|
||||
:style="{
|
||||
@@ -76,30 +85,7 @@ export default {
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const typeList = [
|
||||
{
|
||||
id: 'xlsx',
|
||||
label: 'Excel工作簿(*.xlsx)',
|
||||
},
|
||||
{
|
||||
id: 'csv',
|
||||
label: 'CSV(逗号分隔)(*.csv)',
|
||||
},
|
||||
{
|
||||
id: 'html',
|
||||
label: '网页(*.html)',
|
||||
},
|
||||
{
|
||||
id: 'xml',
|
||||
label: 'XML数据(*.xml)',
|
||||
},
|
||||
{
|
||||
id: 'txt',
|
||||
label: '文本文件(制表符分隔)(*.txt)',
|
||||
},
|
||||
]
|
||||
return {
|
||||
typeList,
|
||||
visible: false,
|
||||
form: this.$form.createForm(this),
|
||||
preferenceAttrList: [],
|
||||
@@ -109,6 +95,32 @@ export default {
|
||||
defaultChecked: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
typeList() {
|
||||
return [
|
||||
{
|
||||
id: 'xlsx',
|
||||
label: this.$t('cmdb.components.xlsx'),
|
||||
},
|
||||
{
|
||||
id: 'csv',
|
||||
label: this.$t('cmdb.components.csv'),
|
||||
},
|
||||
{
|
||||
id: 'html',
|
||||
label: this.$t('cmdb.components.html'),
|
||||
},
|
||||
{
|
||||
id: 'xml',
|
||||
label: this.$t('cmdb.components.xml'),
|
||||
},
|
||||
{
|
||||
id: 'txt',
|
||||
label: this.$t('cmdb.components.txt'),
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('cmdbStore', ['SET_IS_TABLE_LOADING']),
|
||||
open({ preferenceAttrList, ciTypeName = undefined }) {
|
||||
|
@@ -25,17 +25,17 @@
|
||||
</vxe-column>
|
||||
<template #empty>
|
||||
<div v-if="loading()" style="height: 200px; line-height: 200px;color:#2F54EB">
|
||||
<a-icon type="loading" /> 加载中...
|
||||
<a-icon type="loading" /> {{ $t('loading') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<img :style="{ width: '100px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>暂无数据</div>
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">授权用户/部门</span>
|
||||
<span class="grant-button" @click="grantRole">授权角色</span>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
@@ -95,10 +95,8 @@ export default {
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permMap,
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -131,8 +129,8 @@ export default {
|
||||
} else {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: '警告',
|
||||
content: `确认删除 【${row.name}】 的 【授权】 权限?`,
|
||||
title: that.$t('warning'),
|
||||
content: that.$t('cmdb.components.confirmRevoke', { name: `${row.name}` }),
|
||||
onOk() {
|
||||
that.handleChange({ target: { checked: false } }, col, row)
|
||||
const _idx = that.tableData.findIndex((item) => item.rid === row.rid)
|
||||
|
@@ -1,11 +1,15 @@
|
||||
export const permMap = {
|
||||
read: '查看',
|
||||
add: '新增',
|
||||
create: '新增',
|
||||
update: '修改',
|
||||
delete: '删除',
|
||||
config: '配置',
|
||||
grant: '授权',
|
||||
'read_attr': '查看字段',
|
||||
'read_ci': '查看实例'
|
||||
import i18n from '@/lang'
|
||||
|
||||
export const permMap = () => {
|
||||
return {
|
||||
read: i18n.t('view'),
|
||||
add: i18n.t('new'),
|
||||
create: i18n.t('new'),
|
||||
update: i18n.t('update'),
|
||||
delete: i18n.t('delete'),
|
||||
config: i18n.t('cmdb.components.config'),
|
||||
grant: i18n.t('grant'),
|
||||
'read_attr': i18n.t('cmdb.components.readAttribute'),
|
||||
'read_ci': i18n.t('cmdb.components.readCI')
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="cmdb-grant" :style="{ maxHeight: `${windowHeight - 104}px` }">
|
||||
<template v-if="cmdbGrantType.includes('ci_type')">
|
||||
<div class="cmdb-grant-title">模型权限</div>
|
||||
<div class="cmdb-grant-title">{{ $t('cmdb.components.ciTypeGrant') }}</div>
|
||||
<CiTypeGrant
|
||||
:CITypeId="CITypeId"
|
||||
:tableData="tableData"
|
||||
@@ -18,7 +18,7 @@
|
||||
cmdbGrantType.includes('ci_type,ci') || (cmdbGrantType.includes('ci') && !cmdbGrantType.includes('ci_type'))
|
||||
"
|
||||
>
|
||||
<div class="cmdb-grant-title">实例权限</div>
|
||||
<div class="cmdb-grant-title">{{ $t('cmdb.components.ciGrant') }}</div>
|
||||
<CiTypeGrant
|
||||
:CITypeId="CITypeId"
|
||||
:tableData="tableData"
|
||||
@@ -32,7 +32,7 @@
|
||||
/>
|
||||
</template>
|
||||
<template v-if="cmdbGrantType.includes('type_relation')">
|
||||
<div class="cmdb-grant-title">关系权限</div>
|
||||
<div class="cmdb-grant-title">{{ $t('cmdb.components.relationGrant') }}</div>
|
||||
<TypeRelationGrant
|
||||
:typeRelationIds="typeRelationIds"
|
||||
:tableData="tableData"
|
||||
@@ -45,7 +45,7 @@
|
||||
/>
|
||||
</template>
|
||||
<template v-if="cmdbGrantType.includes('relation_view')">
|
||||
<div class="cmdb-grant-title">{{ resourceTypeName }}权限</div>
|
||||
<div class="cmdb-grant-title">{{ resourceTypeName }}{{ $t('cmdb.components.perm') }}</div>
|
||||
<RelationViewGrant
|
||||
:resourceTypeName="resourceTypeName"
|
||||
:tableData="tableData"
|
||||
@@ -116,7 +116,7 @@ export default {
|
||||
attrGroup: [],
|
||||
filerPerimissions: {},
|
||||
loading: false,
|
||||
addedRids: [], // 本次新增的rid
|
||||
addedRids: [], // added rid this time
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -203,12 +203,12 @@ export default {
|
||||
this.tableData = perms
|
||||
this.loading = false
|
||||
},
|
||||
// 授权common-setting中的部门 从中拿到roleid
|
||||
// Grant the department in common-setting and get the roleid from it
|
||||
grantDepart(grantType) {
|
||||
this.$refs.grantModal.open('depart')
|
||||
this.grantType = grantType
|
||||
},
|
||||
// 授权最古老的角色权限
|
||||
// Grant the oldest role permissions
|
||||
grantRole(grantType) {
|
||||
this.$refs.grantModal.open('role')
|
||||
this.grantType = grantType
|
||||
|
@@ -26,9 +26,9 @@ export default {
|
||||
computed: {
|
||||
title() {
|
||||
if (this.type === 'depart') {
|
||||
return '授权用户/部门'
|
||||
return this.$t('cmdb.components.grantUser')
|
||||
}
|
||||
return '授权角色'
|
||||
return this.$t('cmdb.components.grantRole')
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@@ -2,9 +2,9 @@
|
||||
<a-modal :width="680" :title="title" :visible="visible" @ok="handleOk" @cancel="handleCancel">
|
||||
<CustomRadio
|
||||
:radioList="[
|
||||
{ value: 1, label: '全部' },
|
||||
{ value: 2, label: '自定义', layout: 'vertical' },
|
||||
{ value: 3, label: '无' },
|
||||
{ value: 1, label: $t('cmdb.components.all') },
|
||||
{ value: 2, label: $t('cmdb.components.customize'), layout: 'vertical' },
|
||||
{ value: 3, label: $t('cmdb.components.none') },
|
||||
]"
|
||||
v-model="radioValue"
|
||||
>
|
||||
@@ -16,7 +16,7 @@
|
||||
:clearable="true"
|
||||
searchable
|
||||
:options="attrGroup"
|
||||
placeholder="请选择属性字段"
|
||||
:placeholder="$t('cmdb.ciType.selectAttributes')"
|
||||
value-consists-of="LEAF_PRIORITY"
|
||||
:limit="10"
|
||||
:limitText="(count) => `+ ${count}`"
|
||||
@@ -24,8 +24,8 @@
|
||||
(node) => {
|
||||
return {
|
||||
id: node.name || -1,
|
||||
label: node.alias || node.name || '其他',
|
||||
title: node.alias || node.name || '其他',
|
||||
label: node.alias || node.name || $t('other'),
|
||||
title: node.alias || node.name || $t('other'),
|
||||
children: node.attributes,
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
:wrapperCol="{ span: 10 }"
|
||||
ref="form"
|
||||
>
|
||||
<a-form-model-item label="名称" prop="name">
|
||||
<a-form-model-item :label="$t('name')" prop="name">
|
||||
<a-input v-model="form.name" />
|
||||
</a-form-model-item>
|
||||
<FilterComp
|
||||
@@ -99,16 +99,16 @@ export default {
|
||||
name: '',
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: '请输入自定义筛选条件名' }],
|
||||
name: [{ required: true, message: this.$t('cmdb.components.customizeFilterName') }],
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
if (this.colType === 'read_attr') {
|
||||
return '字段权限'
|
||||
return this.$t('cmdb.components.attributeGrant')
|
||||
}
|
||||
return '实例权限'
|
||||
return this.$t('cmdb.components.ciGrant')
|
||||
},
|
||||
attrGroup() {
|
||||
return this.provide_attrGroup()
|
||||
|
@@ -17,8 +17,8 @@
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">授权用户/部门</span>
|
||||
<span class="grant-button" @click="grantRole">授权角色</span>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
@@ -51,7 +51,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permMap,
|
||||
columns: ['read', 'grant'],
|
||||
}
|
||||
},
|
||||
@@ -65,6 +64,9 @@ export default {
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowStyle,
|
||||
|
@@ -17,8 +17,8 @@
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">授权用户/部门</span>
|
||||
<span class="grant-button" @click="grantRole">授权角色</span>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
@@ -51,7 +51,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permMap,
|
||||
columns: ['create', 'grant', 'delete'],
|
||||
}
|
||||
},
|
||||
@@ -65,6 +64,9 @@ export default {
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowStyle,
|
||||
|
@@ -132,7 +132,7 @@ export default {
|
||||
} else if (color.indexOf('rgb') !== -1) {
|
||||
hsvObj = this.rgbToHSV(color)
|
||||
} else {
|
||||
throw new Error('初始化颜色格式错误,使用#fff或rgb格式')
|
||||
throw new Error(this.$t('cmdb.components.colorPickerError'))
|
||||
// this.$message.error('颜色格式错误,使用16进制格式')
|
||||
}
|
||||
if (hsvObj) {
|
||||
|
@@ -15,19 +15,19 @@
|
||||
:edit-config="isEdit ? { trigger: 'click', mode: 'cell' } : {}"
|
||||
>
|
||||
<template v-if="isEdit">
|
||||
<vxe-colgroup title="自动发现">
|
||||
<vxe-column field="name" title="名称" width="100"> </vxe-column>
|
||||
<vxe-column field="type" title="类型" width="80"> </vxe-column>
|
||||
<vxe-column field="example" title="示例值">
|
||||
<vxe-colgroup :title="$t('cmdb.ciType.autoDiscovery')">
|
||||
<vxe-column field="name" :title="$t('name')" width="100"> </vxe-column>
|
||||
<vxe-column field="type" :title="$t('type')" width="80"> </vxe-column>
|
||||
<vxe-column field="example" :title="$t('cmdb.components.example')">
|
||||
<template #default="{row}">
|
||||
<span v-if="row.type === 'json'">{{ JSON.stringify(row.example) }}</span>
|
||||
<span v-else>{{ row.example }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="desc" title="描述"> </vxe-column>
|
||||
<vxe-column field="desc" :title="$t('desc')"> </vxe-column>
|
||||
</vxe-colgroup>
|
||||
<vxe-colgroup title="模型属性">
|
||||
<vxe-column field="attr" title="名称" :edit-render="{}">
|
||||
<vxe-colgroup :title="$t('cmdb.ciType.attributes')">
|
||||
<vxe-column field="attr" :title="$t('name')" :edit-render="{}">
|
||||
<template #default="{row}">
|
||||
{{ row.attr }}
|
||||
</template>
|
||||
@@ -45,15 +45,15 @@
|
||||
</vxe-colgroup>
|
||||
</template>
|
||||
<template v-else>
|
||||
<vxe-column field="name" title="名称" width="100"> </vxe-column>
|
||||
<vxe-column field="type" title="类型" width="80"> </vxe-column>
|
||||
<vxe-column field="example" title="示例值">
|
||||
<vxe-column field="name" :title="$t('name')" width="100"> </vxe-column>
|
||||
<vxe-column field="type" :title="$t('type')" width="80"> </vxe-column>
|
||||
<vxe-column field="example" :title="$t('cmdb.components.example')">
|
||||
<template #default="{row}">
|
||||
<span v-if="row.type === 'object'">{{ JSON.stringify(row.example) }}</span>
|
||||
<span v-else>{{ row.example }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="desc" title="描述"> </vxe-column>
|
||||
<vxe-column field="desc" :title="$t('desc')"> </vxe-column>
|
||||
</template>
|
||||
</vxe-table>
|
||||
</div>
|
||||
@@ -61,12 +61,6 @@
|
||||
|
||||
<script>
|
||||
import { getHttpCategories, getHttpAttributes, getSnmpAttributes } from '../../api/discovery'
|
||||
const httpMap = {
|
||||
阿里云: { name: 'aliyun' },
|
||||
腾讯云: { name: 'tencentcloud' },
|
||||
华为云: { name: 'huaweicloud' },
|
||||
AWS: { name: 'aws' },
|
||||
}
|
||||
export default {
|
||||
name: 'HttpSnmpAD',
|
||||
props: {
|
||||
@@ -107,13 +101,21 @@ export default {
|
||||
const { ruleType, ruleName } = this
|
||||
return { ruleType, ruleName }
|
||||
},
|
||||
httpMap() {
|
||||
return {
|
||||
阿里云: { name: 'aliyun' },
|
||||
腾讯云: { name: 'tencentcloud' },
|
||||
华为云: { name: 'huaweicloud' },
|
||||
AWS: { name: 'aws' },
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
currentCate: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
getHttpAttributes(httpMap[`${this.ruleName}`].name, { category: newVal }).then((res) => {
|
||||
getHttpAttributes(this.httpMap[`${this.ruleName}`].name, { category: newVal }).then((res) => {
|
||||
if (this.isEdit) {
|
||||
this.formatTableData(res)
|
||||
} else {
|
||||
@@ -139,7 +141,7 @@ export default {
|
||||
})
|
||||
}
|
||||
if (ruleType === 'http' && ruleName) {
|
||||
getHttpCategories(httpMap[`${this.ruleName}`].name).then((res) => {
|
||||
getHttpCategories(this.httpMap[`${this.ruleName}`].name).then((res) => {
|
||||
this.categories = res
|
||||
if (res && res.length) {
|
||||
this.currentCate = res[0]
|
||||
|
@@ -19,7 +19,7 @@
|
||||
<Editor class="notice-content-editor" :defaultConfig="editorConfig" mode="simple" @onCreated="onCreated" />
|
||||
<div class="notice-content-sidebar">
|
||||
<template v-if="needOld">
|
||||
<div class="notice-content-sidebar-divider">变更前</div>
|
||||
<div class="notice-content-sidebar-divider">{{ $t('cmdb.components.beforeChange') }}</div>
|
||||
<div
|
||||
@dblclick="dblclickSidebar(`old_${attr.name}`, attr.alias || attr.name)"
|
||||
class="notice-content-sidebar-item"
|
||||
@@ -29,7 +29,7 @@
|
||||
>
|
||||
{{ attr.alias || attr.name }}
|
||||
</div>
|
||||
<div class="notice-content-sidebar-divider">变更后</div>
|
||||
<div class="notice-content-sidebar-divider">{{ $t('cmdb.components.afterChange') }}</div>
|
||||
</template>
|
||||
<div
|
||||
@dblclick="dblclickSidebar(attr.name, attr.alias || attr.name)"
|
||||
@@ -65,7 +65,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
editorConfig: { placeholder: '请输入通知内容', readOnly: this.readOnly },
|
||||
editorConfig: { placeholder: this.$t('cmdb.components.noticeContentTips'), readOnly: this.readOnly },
|
||||
content: '',
|
||||
defaultParams: [],
|
||||
value2LabelMap: {},
|
||||
@@ -74,11 +74,11 @@ export default {
|
||||
beforeDestroy() {
|
||||
const editor = this.editor
|
||||
if (editor == null) return
|
||||
editor.destroy() // 组件销毁时,及时销毁编辑器
|
||||
editor.destroy() // When the component is destroyed, destroy the editor in time
|
||||
},
|
||||
methods: {
|
||||
onCreated(editor) {
|
||||
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
|
||||
this.editor = Object.seal(editor) // Be sure to use Object.seal(), otherwise an error will be reported
|
||||
},
|
||||
getContent() {
|
||||
const html = _.cloneDeep(this.editor.getHtml())
|
||||
|
@@ -11,7 +11,7 @@
|
||||
@blur="handleInputConfirm"
|
||||
@keyup.enter="handleInputConfirm"
|
||||
/>
|
||||
<a-button v-else type="primary" size="small" ghost @click="showInput">保存筛选条件</a-button>
|
||||
<a-button v-else type="primary" size="small" ghost @click="showInput">{{ $t('cmdb.components.saveQuery') }}</a-button>
|
||||
</span>
|
||||
<template v-for="(item, index) in preferenceSearchList.slice(0, 3)">
|
||||
<span
|
||||
@@ -26,7 +26,7 @@
|
||||
<a-tooltip :title="item.name">
|
||||
<span @click="clickPreferenceSearch(item)">{{ `${item.name.slice(0, 6)}...` }}</span>
|
||||
</a-tooltip>
|
||||
<a-popconfirm title="确认删除?" @confirm="deletePreferenceSearch(item)">
|
||||
<a-popconfirm :title="$t('cmdb.ciType.confirmDelete2')" @confirm="deletePreferenceSearch(item)">
|
||||
<a-icon type="close" />
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
@@ -40,7 +40,7 @@
|
||||
}"
|
||||
>
|
||||
<span @click="clickPreferenceSearch(item)">{{ item.name }}</span>
|
||||
<a-popconfirm title="确认删除?" @confirm="deletePreferenceSearch(item)">
|
||||
<a-popconfirm :title="$t('cmdb.ciType.confirmDelete2')" @confirm="deletePreferenceSearch(item)">
|
||||
<a-icon type="close" />
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
@@ -73,7 +73,7 @@
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<a-popconfirm
|
||||
title="确认删除?"
|
||||
:title="$t('cmdb.ciType.confirmDelete2')"
|
||||
:getPopupContainer="(trigger) => trigger.parentElement"
|
||||
placement="left"
|
||||
@confirm="
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user