提交 4be78af5 编写于 作者: MaxKey单点登录官方's avatar MaxKey单点登录官方

Accounts Strategy

上级 b7817531
......@@ -4,7 +4,7 @@
# Overview
<b>Maxkey </b> Single Sign On system, which means the Maximum key, <b>Leading-Edge Enterprise-Class IAM Identity and Access management product </b>, Support OAuth 2.0/OPENID CONNECT, SAML 2.0, JWT, CAS, SCIM and other standard protocols, and provide <b> Simple, Standard, Secure and Open </b> Identity management (IDM), Access management (AM), Single Sign On (SSO), RBAC permission management and Resource management.
<b>Maxkey </b> Single Sign On system, which means the Maximum key, <b>Leading-Edge Enterprise-Class IAM Identity and Access management product </b>, Support OAuth 2.x/OPENID CONNECT, SAML 2.0, JWT, CAS, SCIM and other standard protocols, and provide <b> Simple, Standard, Secure and Open </b> Identity management (IDM), Access management (AM), Single Sign On (SSO), RBAC permission management and Resource management.
Official Website <a href="https://www.maxkey.top" target="_blank"><b>Official</b></a> | <a href="https://maxkeytop.gitee.io" target="_blank"><b>Line2</b></a>
......@@ -89,7 +89,7 @@ App Management UI
# Download
Download the current version of Baidu Pan,<a href="https://maxkey.top/zh/about/download.html" target="_blank"> history version</a>
Download the current version from Baidu Pan,<a href="https://maxkey.top/zh/about/download.html" target="_blank"> history version</a>
| Version | Date | Docker | Pan URL | Pan Code |
| -------- | :----- | :---- | :---- | :---- |
......
......@@ -4,7 +4,7 @@
# Overview
<b>Maxkey </b> Single Sign On system, which means the Maximum key, <b>Leading-Edge Enterprise-Class IAM Identity and Access management product </b>, Support OAuth 2.0/OPENID CONNECT, SAML 2.0, JWT, CAS, SCIM and other standard protocols, and provide <b> Simple, Standard, Secure and Open </b> Identity management (IDM), Access management (AM), Single Sign On (SSO), RBAC permission management and Resource management.
<b>Maxkey </b> Single Sign On system, which means the Maximum key, <b>Leading-Edge Enterprise-Class IAM Identity and Access management product </b>, Support OAuth 2.x/OPENID CONNECT, SAML 2.0, JWT, CAS, SCIM and other standard protocols, and provide <b> Simple, Standard, Secure and Open </b> Identity management (IDM), Access management (AM), Single Sign On (SSO), RBAC permission management and Resource management.
Official Website <a href="https://www.maxkey.top" target="_blank"><b>Official</b></a> | <a href="https://maxkeytop.gitee.io" target="_blank"><b>Line2</b></a>
......@@ -89,7 +89,7 @@ App Management UI
# Download
Download the current version of Baidu Pan,<a href="https://maxkey.top/zh/about/download.html" target="_blank"> history version</a>
Download the current version from Baidu Pan,<a href="https://maxkey.top/zh/about/download.html" target="_blank"> history version</a>
| Version | Date | Docker | Pan URL | Pan Code |
| -------- | :----- | :---- | :---- | :---- |
......
......@@ -5,7 +5,7 @@
# 概述
<b>MaxKey</b>单点登录认证系统(Single Sign On System),谐音马克思的钥匙寓意是最大钥匙,是<b>业界领先的企业级IAM身份管理和认证产品</b>,支持OAuth 2.0/OpenID Connect、SAML 2.0、JWT、CAS、SCIM等标准协议,提供<b>简单、标准、安全和开放</b>的用户身份管理(IDM)、身份认证(AM)、单点登录(SSO)、RBAC权限管理和资源管理等。
<b>MaxKey</b>单点登录认证系统(Single Sign On System),谐音马克思的钥匙寓意是最大钥匙,是<b>业界领先的企业级IAM身份管理和认证产品</b>,支持OAuth 2.x/OpenID Connect、SAML 2.0、JWT、CAS、SCIM等标准协议,提供<b>简单、标准、安全和开放</b>的用户身份管理(IDM)、身份认证(AM)、单点登录(SSO)、RBAC权限管理和资源管理等。
官方网站 <a href="https://www.maxkey.top" target="_blank"><b>官网</b></a> | <a href="https://maxkeytop.gitee.io" target="_blank"><b>官网二线</b></a>
......
......@@ -11,7 +11,10 @@
*(MAXKEY-210810) 日志优化
*(MAXKEY-210811) 密码修改问题修复
*(MAXKEY-210812) 环境变量参数优化
*(MAXKEY-210813) 依赖jar引用、更新和升级
*(MAXKEY-210813) 管理端图标显示修复
*(MAXKEY-210814) 管理端‘应用管理’移动到‘配置管理’的菜单项
*(MAXKEY-210815) OAuth的数据库加载增加本地缓存
*(MAXKEY-210816) 依赖jar引用、更新和升级
mybatis-jpa-extra 2.6
druid 1.2.8
caffeine 2.9.2
......
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
@Entity
@Table(name = "MXK_ACCOUNTS_STRATEGY")
public class AccountsStrategy extends JpaBaseEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8743329570694948718L;
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO,generator = "snowflakeid")
private String id;
@Column
private String name;
@Column
private String appId;
@Column
private String appName;
@Column
private String mapping;
@Column
String filters ;
@Column
String orgIdsList;
@Column
String status;
@Column
String description;
@Column
String createdBy;
@Column
String createdDate;
@Column
String modifiedBy;
@Column
String modifiedDate;
public AccountsStrategy() {
super();
// TODO Auto-generated constructor stub
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
public String getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
public String getOrgIdsList() {
return orgIdsList;
}
public void setOrgIdsList(String orgIdsList) {
this.orgIdsList = orgIdsList;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getMapping() {
return mapping;
}
public void setMapping(String mapping) {
this.mapping = mapping;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("AccountsStrategy [id=");
builder.append(id);
builder.append(", name=");
builder.append(name);
builder.append(", appId=");
builder.append(appId);
builder.append(", appName=");
builder.append(appName);
builder.append(", mapping=");
builder.append(mapping);
builder.append(", filters=");
builder.append(filters);
builder.append(", orgIdsList=");
builder.append(orgIdsList);
builder.append(", status=");
builder.append(status);
builder.append(", description=");
builder.append(description);
builder.append(", createdBy=");
builder.append(createdBy);
builder.append(", createdDate=");
builder.append(createdDate);
builder.append(", modifiedBy=");
builder.append(modifiedBy);
builder.append(", modifiedDate=");
builder.append(modifiedDate);
builder.append("]");
return builder.toString();
}
}
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
*/
package org.maxkey.persistence.mapper;
import java.util.List;
import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
import org.maxkey.entity.AccountsStrategy;
import org.maxkey.entity.Groups;
/**
* @author Crystal.sea
*
*/
public interface AccountsStrategyMapper extends IJpaBaseMapper<AccountsStrategy> {
public List<Groups> queryDynamicGroups(Groups groups);
}
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.persistence.service;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import org.apache.mybatis.jpa.persistence.JpaBaseService;
import org.maxkey.entity.AccountsStrategy;
import org.maxkey.entity.Groups;
import org.maxkey.persistence.mapper.AccountsStrategyMapper;
import org.maxkey.persistence.mapper.GroupsMapper;
import org.maxkey.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Repository
public class AccountsStrategyService extends JpaBaseService<AccountsStrategy> implements Serializable {
/**
*
*/
private static final long serialVersionUID = -921086134545225302L;
final static Logger _logger = LoggerFactory.getLogger(AccountsStrategyService.class);
/*
@JsonIgnore
@Autowired
@Qualifier("groupMemberService")
GroupMemberService accountsStrategyService;
*/
public AccountsStrategyService() {
super(AccountsStrategyMapper.class);
}
/* (non-Javadoc)
* @see com.connsec.db.service.BaseService#getMapper()
*/
@Override
public AccountsStrategyMapper getMapper() {
// TODO Auto-generated method stub
return (AccountsStrategyMapper)super.getMapper();
}
public List<Groups> queryDynamicGroups(Groups groups){
return this.getMapper().queryDynamicGroups(groups);
}
public boolean deleteById(String groupId) {
this.remove(groupId);
//groupMemberService.deleteByGroupId(groupId);
return true;
}
/*
public void refreshDynamicGroups(Groups dynamicGroup){
if(dynamicGroup.getDynamic().equals("1")) {
boolean isDynamicTimeSupport = false;
boolean isBetweenEffectiveTime = false;
if(dynamicGroup.getResumeTime()!=null&&dynamicGroup.getResumeTime().equals("")
&&dynamicGroup.getSuspendTime()!=null&&dynamicGroup.getSuspendTime().equals("")) {
LocalTime currentTime = LocalDateTime.now().toLocalTime();
LocalTime resumeTime = LocalTime.parse(dynamicGroup.getResumeTime());
LocalTime suspendTime = LocalTime.parse(dynamicGroup.getSuspendTime());
_logger.info("currentTime: " + currentTime
+ " , resumeTime : " + resumeTime
+ " , suspendTime: " + suspendTime);
isDynamicTimeSupport = true;
if(resumeTime.isBefore(currentTime) && currentTime.isBefore(suspendTime)) {
isBetweenEffectiveTime = true;
}
}
if(dynamicGroup.getOrgIdsList()!=null && !dynamicGroup.getOrgIdsList().equals("")) {
dynamicGroup.setOrgIdsList("'"+dynamicGroup.getOrgIdsList().replace(",", "','")+"'");
}
String filters = dynamicGroup.getFilters();
if(StringUtils.filtersSQLInjection(filters.toLowerCase())) {
_logger.info("filters include SQL Injection Attack Risk.");
return;
}
filters = filters.replace("&", " AND ");
filters = filters.replace("|", " OR ");
dynamicGroup.setFilters(filters);
if(isDynamicTimeSupport) {
if(isBetweenEffectiveTime) {
groupMemberService.deleteDynamicGroupMember(dynamicGroup);
groupMemberService.addDynamicGroupMember(dynamicGroup);
}else {
groupMemberService.deleteDynamicGroupMember(dynamicGroup);
}
}else{
groupMemberService.deleteDynamicGroupMember(dynamicGroup);
groupMemberService.addDynamicGroupMember(dynamicGroup);
}
}
}*/
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.maxkey.persistence.mapper.AccountsStrategyMapper">
<sql id="where_statement">
<if test="id != null and id != ''">
and id = #{id}
</if>
<if test="appId != null and appId != ''">
and appid = #{appId}
</if>
<if test="name != null and name != ''">
and name = #{name}
</if>
</sql>
<select id="queryPageResults" parameterType="AccountsStrategy" resultType="AccountsStrategy">
select
*
from
mxk_accounts_strategy
where
(1=1)
<include refid="where_statement"/>
</select>
</mapper>
\ No newline at end of file
......@@ -40,7 +40,7 @@ import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value={"/app/accounts"})
@RequestMapping(value={"/accounts"})
public class AccountsController {
final static Logger _logger = LoggerFactory.getLogger(AccountsController.class);
......@@ -58,7 +58,7 @@ public class AccountsController {
@RequestMapping(value={"/list"})
public ModelAndView appAccountsList(){
ModelAndView modelAndView=new ModelAndView("/accounts/appAccountsList");
ModelAndView modelAndView=new ModelAndView("/accounts/accountsList");
return modelAndView;
}
......@@ -71,14 +71,14 @@ public class AccountsController {
@RequestMapping(value = { "/forwardSelect/{appId}" })
public ModelAndView forwardSelect(@PathVariable("appId") String appId) {
ModelAndView modelAndView=new ModelAndView("/accounts/appAccountsAddSelect");
ModelAndView modelAndView=new ModelAndView("/accounts/accountsAddSelect");
modelAndView.addObject("appId",appId);
return modelAndView;
}
@RequestMapping(value = { "/forwardAdd" })
public ModelAndView forwardAdd(@ModelAttribute("appAccounts") Accounts appAccounts) {
ModelAndView modelAndView=new ModelAndView("/accounts/appAccountsAdd");
ModelAndView modelAndView=new ModelAndView("/accounts/accountsAdd");
//Applications app= appsService.get(appAccounts.getAppId());
//appAccounts.setAppName(app.getName());
modelAndView.addObject("model",appAccounts);
......@@ -103,7 +103,7 @@ public class AccountsController {
@RequestMapping(value = { "/forwardUpdate/{id}" })
public ModelAndView forwardUpdate(@PathVariable("id") String id) {
ModelAndView modelAndView=new ModelAndView("/accounts/appAccountsUpdate");
ModelAndView modelAndView=new ModelAndView("/accounts/accountsUpdate");
Accounts appAccounts =accountsService.get(id);
appAccounts.setRelatedPassword(ReciprocalUtils.decoder(appAccounts.getRelatedPassword()));
......
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.contorller;
import org.apache.mybatis.jpa.persistence.JpaPageResults;
import org.maxkey.constants.ConstantsOperateMessage;
import org.maxkey.entity.AccountsStrategy;
import org.maxkey.entity.Roles;
import org.maxkey.persistence.service.AccountsStrategyService;
import org.maxkey.persistence.service.RolesService;
import org.maxkey.web.WebContext;
import org.maxkey.web.message.Message;
import org.maxkey.web.message.MessageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value={"/accountsstrategy"})
public class AccountsStrategyController {
final static Logger _logger = LoggerFactory.getLogger(AccountsStrategyController.class);
@Autowired
@Qualifier("accountsStrategyService")
AccountsStrategyService accountsStrategyService;
@RequestMapping(value={"/list"})
public ModelAndView rolesList(){
return new ModelAndView("accountsstrategy/accountsstrategyList");
}
@RequestMapping(value = { "/grid" })
@ResponseBody
public JpaPageResults<AccountsStrategy> queryDataGrid(@ModelAttribute("accountsStrategy") AccountsStrategy accountsStrategy) {
_logger.debug(""+accountsStrategy);
return accountsStrategyService.queryPageResults(accountsStrategy);
}
@RequestMapping(value = { "/forwardAdd" })
public ModelAndView forwardAdd() {
return new ModelAndView("accountsstrategy/accountsstrategyAdd");
}
@RequestMapping(value = { "/forwardUpdate/{id}" })
public ModelAndView forwardUpdate(@PathVariable("id") String id) {
ModelAndView modelAndView=new ModelAndView("accountsstrategy/accountsstrategyUpdate");
AccountsStrategy accountsStrategy=accountsStrategyService.get(id);
modelAndView.addObject("model",accountsStrategy);
return modelAndView;
}
@ResponseBody
@RequestMapping(value={"/add"})
public Message insert(@ModelAttribute("accountsStrategy") AccountsStrategy accountsStrategy) {
_logger.debug("-Add :" + accountsStrategy);
if (accountsStrategyService.insert(accountsStrategy)) {
//rolesService.refreshDynamicRoles(role);
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.INSERT_SUCCESS),MessageType.success);
} else {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.INSERT_SUCCESS),MessageType.error);
}
}
/**
* 查询
* @param role
* @return
*/
@ResponseBody
@RequestMapping(value={"/query"})
public Message query(@ModelAttribute("accountsStrategy") AccountsStrategy accountsStrategy) {
_logger.debug("-query :" + accountsStrategy);
if (accountsStrategyService.load(accountsStrategy)!=null) {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.INSERT_SUCCESS),MessageType.success);
} else {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.INSERT_ERROR),MessageType.error);
}
}
/**
* 修改
* @param role
* @return
*/
@ResponseBody
@RequestMapping(value={"/update"})
public Message update(@ModelAttribute("accountsStrategy") AccountsStrategy accountsStrategy) {
_logger.debug("-update AccountsStrategy :" + accountsStrategy);
if (accountsStrategyService.update(accountsStrategy)) {
// rolesService.refreshDynamicRoles(role);
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_SUCCESS),MessageType.success);
} else {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_ERROR),MessageType.error);
}
}
@ResponseBody
@RequestMapping(value={"/delete"})
public Message delete(@ModelAttribute("role") Roles role) {
_logger.debug("-delete role :" + role);
if (accountsStrategyService.deleteById(role.getId())) {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.DELETE_SUCCESS),MessageType.success);
} else {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.DELETE_SUCCESS),MessageType.error);
}
}
}
......@@ -447,6 +447,12 @@ account.appId=\u5e94\u7528\u7f16\u53f7
account.appName=\u5e94\u7528\u540d\u79f0
account.relatedUsername=\u7528\u6237\u8d26\u53f7
account.relatedPassword=\u8d26\u53f7\u5bc6\u7801
#accounts.strategy
accounts.strategy.id=\u7B56\u7565\u7f16\u7801
accounts.strategy.name=\u7B56\u7565\u540D\u79F0
accounts.strategy.mapping=\u8D26\u53F7\u6620\u5C04
accounts.strategy.filters=\u7528\u6237\u6761\u4EF6
accounts.strategy.orgidslist=\u673A\u6784\u5217\u8868
#synchronizers
synchronizers.id=\u7F16\u53F7
synchronizers.name=\u540C\u6B65\u5668\u540D\u79F0
......@@ -566,6 +572,7 @@ navs.orgs=\u673a\u6784\u7ba1\u7406
navs.users=\u7528\u6237\u7ba1\u7406
navs.apps=\u5e94\u7528\u7ba1\u7406
navs.accounts=\u8d26\u53f7\u7ba1\u7406
navs.accounts.strategy=\u8D26\u53F7\u7B56\u7565
navs.privileges=\u8BBF\u95EE\u63A7\u5236\u7BA1\u7406
navs.groups=\u7ec4\u7ba1\u7406
navs.groups.member=\u6210\u5458\u7ba1\u7406
......
......@@ -456,6 +456,11 @@ account.appName=appName
account.relatedUsername=relatedUsername
account.relatedPassword=relatedPassword
accounts.strategy.id=Id
accounts.strategy.name=name
accounts.strategy.mapping=mapping
accounts.strategy.filters=filters
accounts.strategy.orgidslist=orgIdsList
#synchronizers
synchronizers.id=id
......@@ -577,6 +582,7 @@ navs.orgs=Orgs
navs.users=Users
navs.apps=Apps
navs.accounts=Accounts
navs.accounts.strategy=AccountsStrategy
navs.privileges=Access Control
navs.groups=Groups
navs.groups.member=Groups Member
......
......@@ -453,6 +453,12 @@ account.appId=\u5e94\u7528\u7f16\u53f7
account.appName=\u5e94\u7528\u540d\u79f0
account.relatedUsername=\u7528\u6237\u8d26\u53f7
account.relatedPassword=\u8d26\u53f7\u5bc6\u7801
#accounts.strategy
accounts.strategy.id=\u7B56\u7565\u7f16\u7801
accounts.strategy.name=\u7B56\u7565\u540D\u79F0
accounts.strategy.mapping=\u8D26\u53F7\u6620\u5C04
accounts.strategy.filters=\u7528\u6237\u6761\u4EF6
accounts.strategy.orgidslist=\u673A\u6784\u5217\u8868
#synchronizers
synchronizers.id=\u7F16\u53F7
synchronizers.name=\u540C\u6B65\u5668\u540D\u79F0
......@@ -571,6 +577,7 @@ navs.orgs=\u673a\u6784\u7ba1\u7406
navs.users=\u7528\u6237\u7ba1\u7406
navs.apps=\u5e94\u7528\u7ba1\u7406
navs.accounts=\u8d26\u53f7\u7ba1\u7406
navs.accounts.strategy=\u8D26\u53F7\u7B56\u7565
navs.privileges=\u8BBF\u95EE\u63A7\u5236\u7BA1\u7406
navs.groups=\u7ec4\u7ba1\u7406
navs.groups.member=\u6210\u5458\u7ba1\u7406
......
......@@ -11,6 +11,19 @@
$("#relatedUsername").val($("#username").val());
}
});
$("#generateSecret").on("click",function(){
$.post("<@base/>/userinfo/randomPassword/", {_method:"post",currTime:(new Date()).getTime()}, function(data) {
$("#relatedPassword").val(data+"");
});
});
$("#view").on("click",function(){
if($("#relatedPassword").attr("type")=="text"){
$("#relatedPassword").attr("type","password");
}else{
$("#relatedPassword").attr("type","text");
}
});
});
</script>
</head>
......@@ -25,54 +38,69 @@
<input required="" type="text" id="id" name="id" readonly class="form-control" title="" value="${model.id!}"/>
</td>
<td>
</td>
</tr>
<tr>
<th><@locale code="userinfo.username" /></th>
<td nowrap>
<input required="" readonly type="text" id="username" name="username" class="form-control username" title="" value="${model.username!}" style="float:left;width:70%;" required="" />
<input class="button btn btn-primary mr-3 window" type="button" id="selectUserinfoBtn" value="<@locale code="button.text.select" />"
wurl="<@base/>/userinfo/select"
wwidth="800"
wheight="500"
target="window"/>
<td nowrap style="width:60%">
<input required="" readonly type="text" id="username" name="username" class="form-control username" title="" value="${model.username!}" required="" />
</td>
<td style="width: 20%;">
<input class="button btn btn-primary mr-3 window" type="button" id="selectUserinfoBtn" value="<@locale code="button.text.select" />"
wurl="<@base/>/userinfo/select"
wwidth="800"
wheight="500"
target="window"/>
</td>
</tr>
<tr>
<th><@locale code="userinfo.displayName" /></th>
<td nowrap>
<input required="" readonly type="text" id="displayName" name="displayName" class="form-control displayName" title="" value="${model.displayName!}" style="width:70%;" required="" />
<input required="" readonly type="text" id="displayName" name="displayName" class="form-control displayName" title="" value="${model.displayName!}" required="" />
</td>
<td>
</td>
</tr>
<tr>
<th><@locale code="apps.name" /></th>
<td nowrap>
<input required="" readonly type="text" id="appName" name="appName" class="form-control appName" title="" value="${model.appName!}" style="float:left;width:70%;" required="" />
<input class="button btn btn-primary mr-3 window" type="button" id="selectAppsubmitBtn" value="<@locale code="button.text.select" />"
wurl="<@base/>/apps/select"
wwidth="800"
wheight="500"
target="window"/>
<input required="" readonly type="text" id="appName" name="appName" class="form-control appName" title="" value="${model.appName!}" required="" />
</td>
<td>
<input class="button btn btn-primary mr-3 window" type="button" id="selectAppsubmitBtn" value="<@locale code="button.text.select" />"
wurl="<@base/>/apps/select"
wwidth="800"
wheight="500"
target="window"/>
</td>
</tr>
<tr>
<th><@locale code="account.relatedUsername" /></th>
<td nowrap>
<input type="text" id="relatedUsername" name="relatedUsername" class="form-control" title="" value="${model.relatedUsername!}" style="width:70%;" required="" />
<input type="text" id="relatedUsername" name="relatedUsername" class="form-control" title="" value="${model.relatedUsername!}" required="" />
</td>
<td>
</td>
</tr>
<tr>
<th><@locale code="account.relatedPassword" /></th>
<td nowrap>
<input type="password" id="relatedPassword" name="relatedPassword" class="form-control" title="" value="${model.relatedPassword!}" style="width:70%;" required="" />
</td>
<input type="password" id="relatedPassword" name="relatedPassword" class="form-control" title="" value="${model.relatedPassword!}" required="" />
</td>
<td>
<input id="generateSecret" type="button" class="button btn btn-warning mr-3" style="width:75px" value="<@locale code="button.text.generate"/>"/>
<input id="view" type="button" class="button btn btn-info mr-3" style="width:75px" value="<@locale code="button.text.view"/>"/>
</td>
</tr>
<tr>
<td colspan="2" class="center">
<td colspan="3" class="center">
<input id="_method" type="hidden" name="_method" value="post"/>
<input id="status" type="hidden" name="status" value="1"/>
<input type="hidden" id="userId" name="userId" class="userId" title="" value="${model.userId!}"/>
......
......@@ -54,13 +54,13 @@
<td colspan="2">
<div id="tool_box_right">
<input class="button btn btn-success mr-3" id="addBtn" type="button" value="<@locale code="button.text.add"/>"
wurl="<@base/>/app/accounts/forwardAdd"
wurl="<@base/>/accounts/forwardAdd"
wwidth="960"
wheight="600"
target="window">
<input class="button btn btn-danger mr-3 " id="deleteBtn" type="button" value="<@locale code="button.text.delete"/>"
wurl="<@base/>/app/accounts/delete" />
wurl="<@base/>/accounts/delete" />
</div>
</td>
</tr>
......@@ -73,9 +73,16 @@
<form id="advanced_search_form">
<table class="table table-bordered">
<tr>
<td width="120px"><@locale code="account.displayName"/></td>
<td width="120px"><@locale code="apps.name"/></td>
<td width="360px">
<input class="form-control" name="displayName" type="text" >
<input class="form-control d-none appId" id="appId" name="appId" value="" type="text" >
<input class="form-control d-none" id="parentId" name="parentId" value="" type="text" >
<input class="form-control appName" style="width:200px;float: left;" value="" id="appName" name="appName" type="text" >
<input class="button btn btn-success mr-3 window" style="float: left;" id="selectBtn" type="button" value="<@locale code="button.text.select"/>"
wurl="<@base/>/apps/select"
wwidth="700"
wheight="500"
target="window">
</td>
<td width="120px"><@locale code="account.relatedUsername"/></td>
<td width="360px">
......@@ -86,7 +93,7 @@
</table>
</form>
</div>
<table data-url="<@base/>/app/accounts/grid"
<table data-url="<@base/>/accounts/grid"
id="datagrid"
data-toggle="table"
data-classes="table table-bordered table-hover table-striped"
......
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<#include "../layout/header.ftl"/>
<#include "../layout/common.cssjs.ftl"/>
<style type="text/css">
.table th, .table td {
padding: .2rem;
vertical-align: middle;
}
</style>
<script type="text/javascript">
function onClick (event, treeId, treeNode) {
var zTree = $.fn.zTree.getZTreeObj("orgsTree");
nodes = zTree.getCheckedNodes(true);
var orgsName = "";
var orgsId = "";
for (var i=0, l=nodes.length; i<l; i++) {
orgsName += nodes[i].name + ",";
orgsId += nodes[i].id + ",";
}
$("#orgIdsListName").val(orgsName);
$("#orgIdsList").val(orgsId);
}
$(function () {
var treeSettings={
element : "orgsTree",
rootId : "1",
checkbox : true,
onClick : onClick,
onDblClick : null,
url : "<@base/>/orgs/tree"
};
function singlePath(newNode) {
if (newNode === curExpandNode) return;
if (curExpandNode && curExpandNode.open==true) {
var zTree = $.fn.zTree.getZTreeObj(treeSettings.element);
if (newNode.parentTId === curExpandNode.parentTId) {
zTree.expandNode(curExpandNode, false);
} else {
var newParents = [];
while (newNode) {
newNode = newNode.getParentNode();
if (newNode === curExpandNode) {
newParents = null;
break;
} else if (newNode) {
newParents.push(newNode);
}
}
if (newParents!=null) {
var oldNode = curExpandNode;
var oldParents = [];
while (oldNode) {
oldNode = oldNode.getParentNode();
if (oldNode) {
oldParents.push(oldNode);
}
}
if (newParents.length>0) {
for (var i = Math.min(newParents.length, oldParents.length)-1; i>=0; i--) {
if (newParents[i] !== oldParents[i]) {
zTree.expandNode(oldParents[i], false);
break;
}
}
} else {
zTree.expandNode(oldParents[oldParents.length-1], false);
}
}
}
}
curExpandNode = newNode;
};
function beforeExpand(treeId, treeNode) {
var pNode = curExpandNode ? curExpandNode.getParentNode():null;
var treeNodeP = treeNode.parentTId ? treeNode.getParentNode():null;
var zTree = $.fn.zTree.getZTreeObj(""+treeSettings.element);
for(var i=0, l=!treeNodeP ? 0:treeNodeP.children.length; i<l; i++ ) {
if (treeNode !== treeNodeP.children[i]) {
zTree.expandNode(treeNodeP.children[i], false);
}
}
while (pNode) {
if (pNode === treeNode) {
break;
}
pNode = pNode.getParentNode();
}
if (!pNode) {
singlePath(treeNode);
}
};
$.fn.zTree.init(
$("#"+treeSettings.element), //element
{//json object
check : {
enable : treeSettings.checkbox
},
async : {
enable : true,
url : treeSettings.url,
autoParam : ["id", "name=n", "level=lv"],
otherParam : {"otherParam":"zTreeAsyncTest",id:treeSettings.rootId},
dataFilter : function (treeId, parentNode, childNodes) {
if (!childNodes) return null;
for (var i=0, l=childNodes.length; i<l; i++) {
childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
}
return childNodes;
}
},
data : {
simpleData : {
enable : true
}
},
callback: {
onClick : treeSettings.onClick,
onDblClick : treeSettings.onDblClick,
beforeAsync : function(treeId, treeNode){
$.loading();
},
onAsyncSuccess : function(event, treeId, treeNode, msg){
$.unloading();
},
//beforeExpand : beforeExpand,
onExpand : function onExpand(event, treeId, treeNode) {
curExpandNode = treeNode;
}
}
}
);//end tree
});
function onBodyDown(event) {
if (!(event.target.id == "menuBtn" || event.target.id == "orgIdsListName" || event.target.id == "orgContent" || $(event.target).parents("#orgContent").length>0)) {
$("#orgContent").fadeOut("fast");
$("body").unbind("mousedown", onBodyDown);
}
}
function showOrgsTree() {
var treeObj = $("#orgIdsListName");
var treeOffset = $("#orgIdsListName").offset();
$("#orgContent").css({left:treeOffset.left + "px", top:treeOffset.top + treeObj.outerHeight() + "px"}).slideDown("fast");
$("body").bind("mousedown", onBodyDown);
}
</script>
</head>
<body>
<form id="actionForm" method="post" type="label" autoclose="true" action="<@base/>/roles/add" class="needs-validation" novalidate>
<table border="0" cellpadding="0" cellspacing="0" class="table table-bordered" >
<tbody>
<tr>
<th><@locale code="role.id" /></th>
<td nowrap>
<input type="text" id="id" name="id" class="form-control" title="" value="" />
</td>
</tr>
<tr>
<th><@locale code="role.name" /></th>
<td nowrap>
<input type="text" id="name" name="name" class="form-control" title="" value="" required="" />
</td>
</tr>
<tr>
<th><@locale code="role.dynamic" /></th>
<td nowrap>
<select id="dynamic" name="dynamic" class="form-control form-select">
<option value="0" selected ><@locale code="common.text.no" /></option>
<option value="1" ><@locale code="common.text.yes" /></option>
</select>
</td>
</tr>
<tr>
<th><@locale code="role.orgidslist" /></th>
<td nowrap>
<input type="text" id="orgIdsListName" name="orgIdsListName" readonly class="form-control" title="" value="" onclick="showOrgsTree();"/>
<input type="hidden" id="orgIdsList" name="orgIdsList" readonly class="form-control" title="" value="" />
</td>
</tr>
<tr>
<th><@locale code="role.filters" /></th>
<td nowrap>
<textarea id="filters" name="filters" class="form-control" rows="7" cols="20"></textarea>
</td>
</tr>
<tr>
<th><@locale code="common.text.description" /></th>
<td nowrap>
<textarea id="description" name="description" class="form-control" rows="6" cols="20"></textarea>
</td>
</tr>
<tr>
<td nowrap colspan="2" class="center">
<input id="_method" type="hidden" name="_method" value="post"/>
<input id="status" type="hidden" name="status" value="1"/>
<input class="button btn btn-primary mr-3" id="submitBtn" type="submit" value="<@locale code="button.text.save" />">
<input class="button btn btn-secondary mr-3" id="closeBtn" type="button" value="<@locale code="button.text.cancel" />">
</td>
</tr>
</tbody>
</table>
</form>
<div id="orgContent" class="menuContent" style="display:none; position: absolute;">
<ul id="orgsTree" class="ztree" style="margin-top:0; width:180px; height: 300px;"></ul>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<#include "../layout/header.ftl"/>
<#include "../layout/common.cssjs.ftl"/>
<script type="text/javascript">
function dynamicFormatter(value, row, index){
return value=='0'? '<@locale code="common.text.no" />':'<@locale code="common.text.yes" />';
};
</script>
</head>
<body>
<div class="app header-default side-nav-dark">
<div class="layout">
<div class="header navbar">
<#include "../layout/top.ftl"/>
</div>
<div class="col-md-3 sidebar-nav side-nav" >
<#include "../layout/sidenav.ftl"/>
</div>
<div class="page-container">
<div class="main-content">
<div class="container-fluid">
<div class="breadcrumb-wrapper row">
<div class="col-12 col-lg-3 col-md-6">
<h4 class="page-title"><@locale code="navs.roles"/></h4>
</div>
<div class="col-12 col-lg-9 col-md-6">
<ol class="breadcrumb float-right">
<li><a href="<@base/>/main"><@locale code="navs.home"/></a></li>
<li class="active">/ <@locale code="navs.roles"/></li>
</ol>
</div>
</div>
</div>
<div class="container-fluid">
<div class="content-wrapper row">
<div class="col-12 grid-margin">
<div class="card">
<div class="card-body">
<table class="table table-bordered">
<tr>
<td width="120px"><@locale code="role.name"/>:</td>
<td width="375px">
<form id="basic_search_form">
<input class="form-control" type="text" name="name" style ="width:150px;float:left;">
<input class="button btn btn-primary mr-3" id="searchBtn" type="button" size="50" value="<@locale code="button.text.search"/>">
<!--<input class="button btn btn-secondary" id="advancedSearchExpandBtn" type="button" size="50" value="<@locale code="button.text.expandsearch"/>" expandValue="<@locale code="button.text.expandsearch"/>" collapseValue="<@locale code="button.text.collapsesearch"/>">
-->
</form>
</td>
<td colspan="2">
<div id="tool_box_right">
<input class="button btn btn-success mr-3" id="addBtn" type="button" value="<@locale code="button.text.add"/>"
wurl="<@base/>/accountsstrategy/forwardAdd"
wwidth="500"
wheight="600"
target="window">
<input class="button btn btn-info mr-3 " id="modifyBtn" type="button" value="<@locale code="button.text.edit"/>"
wurl="<@base/>/accountsstrategy/forwardUpdate"
wwidth="500"
wheight="600"
target="window">
<input class="button btn btn-danger mr-3 " id="deleteBtn" type="button" value="<@locale code="button.text.delete"/>"
wurl="<@base/>/roles/delete" />
</div>
</td>
</tr>
</table>
<div id="advanced_search">
<form id="advanced_search_form">
</form>
</div>
<table data-url="<@base/>/accountsstrategy/grid"
id="datagrid"
data-toggle="table"
data-classes="table table-bordered table-hover table-striped"
data-click-to-select="true"
data-pagination="true"
data-total-field="records"
data-page-list="[10, 25, 50, 100]"
data-search="false"
data-locale="zh-CN"
data-query-params="dataGridQueryParams"
data-query-params-type="pageSize"
data-side-pagination="server">
<thead>
<tr>
<th data-checkbox="true"></th>
<th data-sortable="true" data-field="id" data-visible="false">Id</th>
<th data-field="name"><@locale code="role.name"/></th>
<th data-field="dynamic" data-formatter="dynamicFormatter"><@locale code="group.dynamic"/></th>
<th data-field="description"><@locale code="common.text.description"/></th>
<th data-field="createdBy" data-visible="false"><@locale code="common.text.createdby"/></th>
<th data-field="createdDate" data-visible="false"><@locale code="common.text.createddate"/></th>
<th data-field="modifiedBy" data-visible="false"><@locale code="common.text.modifiedby"/></th>
<th data-field="modifiedDate" data-visible="false"><@locale code="common.text.modifieddate"/></th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
<footer class="content-footer">
<#include "../layout/footer.ftl"/>
</footer>
</div>
</div>
</div>
<div id="preloader">
<div class="loader" id="loader-1"></div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<#include "../layout/header.ftl"/>
<#include "../layout/common.cssjs.ftl"/>
<style type="text/css">
.table th, .table td {
padding: .2rem;
vertical-align: middle;
}
</style>
<script type="text/javascript">
function onClick (event, treeId, treeNode) {
var zTree = $.fn.zTree.getZTreeObj("orgsTree");
nodes = zTree.getCheckedNodes(true);
var orgsName = "";
var orgsId = "";
for (var i=0; i<nodes.length; i++) {
orgsName += nodes[i].name + ",";
orgsId += nodes[i].id + ",";
}
$("#orgIdsListName").val(orgsName);
$("#orgIdsList").val(orgsId);
}
$(function () {
var treeSettings={
element : "orgsTree",
rootId : "1",
checkbox : true,
onClick : onClick,
onDblClick : null,
url : "<@base/>/orgs/tree"
};
function singlePath(newNode) {
if (newNode === curExpandNode) return;
if (curExpandNode && curExpandNode.open==true) {
var zTree = $.fn.zTree.getZTreeObj(treeSettings.element);
if (newNode.parentTId === curExpandNode.parentTId) {
zTree.expandNode(curExpandNode, false);
} else {
var newParents = [];
while (newNode) {
newNode = newNode.getParentNode();
if (newNode === curExpandNode) {
newParents = null;
break;
} else if (newNode) {
newParents.push(newNode);
}
}
if (newParents!=null) {
var oldNode = curExpandNode;
var oldParents = [];
while (oldNode) {
oldNode = oldNode.getParentNode();
if (oldNode) {
oldParents.push(oldNode);
}
}
if (newParents.length>0) {
for (var i = Math.min(newParents.length, oldParents.length)-1; i>=0; i--) {
if (newParents[i] !== oldParents[i]) {
zTree.expandNode(oldParents[i], false);
break;
}
}
} else {
zTree.expandNode(oldParents[oldParents.length-1], false);
}
}
}
}
curExpandNode = newNode;
};
function beforeExpand(treeId, treeNode) {
var pNode = curExpandNode ? curExpandNode.getParentNode():null;
var treeNodeP = treeNode.parentTId ? treeNode.getParentNode():null;
var zTree = $.fn.zTree.getZTreeObj(""+treeSettings.element);
for(var i=0, l=!treeNodeP ? 0:treeNodeP.children.length; i<l; i++ ) {
if (treeNode !== treeNodeP.children[i]) {
zTree.expandNode(treeNodeP.children[i], false);
}
}
while (pNode) {
if (pNode === treeNode) {
break;
}
pNode = pNode.getParentNode();
}
if (!pNode) {
singlePath(treeNode);
}
};
function onLoadSuccessed(){
var zTree = $.fn.zTree.getZTreeObj("orgsTree");
var orgsIdValues = $("#orgIdsList").val().split(",") ;
var orgsName="";
for (var i=0; i<orgsIdValues.length; i++) {
var node = zTree.getNodeByParam("id",orgsIdValues[i] );
if(node != null){
zTree.checkNode(node, true, false);//将指定ID的节点选中
orgsName += node.name;
}
}
$("#orgIdsListName").val(orgsName);
}
$.fn.zTree.init(
$("#"+treeSettings.element), //element
{//json object
check : {
enable : treeSettings.checkbox
},
async : {
enable : true,
url : treeSettings.url,
autoParam : ["id", "name=n", "level=lv"],
otherParam : {"otherParam":"zTreeAsyncTest",id:treeSettings.rootId},
dataFilter : function (treeId, parentNode, childNodes) {
if (!childNodes) return null;
for (var i=0, l=childNodes.length; i<l; i++) {
childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
}
return childNodes;
}
},
data : {
simpleData : {
enable : true
}
},
callback: {
onClick : treeSettings.onClick,
onDblClick : treeSettings.onDblClick,
beforeAsync : function(treeId, treeNode){
$.loading();
},
onAsyncSuccess : function(event, treeId, treeNode, msg){
$.unloading();
onLoadSuccessed();
},
//beforeExpand : beforeExpand,
onExpand : function onExpand(event, treeId, treeNode) {
curExpandNode = treeNode;
}
}
}
);//end tree
});
function onBodyDown(event) {
if (!(event.target.id == "menuBtn" || event.target.id == "orgIdsListName" || event.target.id == "orgContent" || $(event.target).parents("#orgContent").length>0)) {
$("#orgContent").fadeOut("fast");
$("body").unbind("mousedown", onBodyDown);
}
}
function showOrgsTree() {
var treeObj = $("#orgIdsListName");
var treeOffset = $("#orgIdsListName").offset();
$("#orgContent").css({left:treeOffset.left + "px", top:treeOffset.top + treeObj.outerHeight() + "px"}).slideDown("fast");
$("body").bind("mousedown", onBodyDown);
}
</script>
</head>
<body>
<form id="actionForm" method="post" type="label" autoclose="true" action="<@base/>/roles/update" class="needs-validation" novalidate>
<table border="0" cellpadding="0" cellspacing="0" class="table table-bordered">
<tbody>
<tr>
<th><@locale code="role.id" /></th>
<td nowrap>
<input id="id" type="text" readonly name="id" class="form-control" value="${model.id}"/>
</td>
</tr>
<tr>
<th><@locale code="role.name" /></th>
<td nowrap>
<input type="text" id="name" name="name" class="form-control" title="" value="${model.name!}" required="" />
</td>
</tr>
<tr>
<th><@locale code="role.dynamic" /></th>
<td nowrap>
<select id="dynamic" name="dynamic" class="form-control form-select">
<option value="0" <#if '0'==model.dynamic>selected</#if> ><@locale code="common.text.no" /></option>
<option value="1" <#if '1'==model.dynamic>selected</#if> ><@locale code="common.text.yes" /></option>
</select>
</td>
</tr>
<tr>
<th><@locale code="role.orgidslist" /></th>
<td nowrap>
<input type="text" id="orgIdsListName" name="orgIdsListName" readonly class="form-control" title="" value="" onclick="showOrgsTree();"/>
<input type="hidden" id="orgIdsList" name="orgIdsList" readonly class="form-control" title="" value="${model.orgIdsList!}" />
</td>
</tr>
<tr>
<th><@locale code="role.filters" /></th>
<td nowrap>
<textarea id="filters" name="filters" class="form-control" rows="7" cols="20">${model.filters!}</textarea>
</td>
</tr>
<tr>
<th><@locale code="common.text.description" /></th>
<td nowrap>
<textarea id="description" name="description" class="form-control" rows="6" cols="20">${model.description!}</textarea>
</td>
</tr>
<tr>
<td nowrap colspan="2" class="center">
<input id="_method" type="hidden" name="_method" value="post"/>
<input id="status" type="hidden" name="status" value="1"/>
<input class="button btn btn-primary mr-3" id="submitBtn" type="submit" value="<@locale code="button.text.save" />">
<input class="button btn btn-secondary mr-3" id="closeBtn" type="button" value="<@locale code="button.text.cancel" />">
</td>
</tr>
</tbody>
</table>
</form>
<div id="orgContent" class="menuContent" style="display:none; position: absolute;">
<ul id="orgsTree" class="ztree" style="margin-top:0; width:180px; height: 300px;"></ul>
</div>
</body>
</html>
\ No newline at end of file
......@@ -5,7 +5,9 @@
<#include "../layout/common.cssjs.ftl"/>
<link type="text/css" rel="stylesheet" href="<@base />/static/css/minitable.css"/>
<script type="text/javascript">
function dynamicFormatter(value, row, index){
return value=='0'? '<@locale code="common.text.no" />':'<@locale code="common.text.yes" />';
};
$(function () {
$("#selectBtn").on("click",function(){
var seldata=$.dataGridSelRowsData("#datagrid");
......@@ -58,11 +60,12 @@
<th data-checkbox="true"></th>
<th data-sortable="true" data-field="id" data-visible="false">Id</th>
<th data-field="name"><@locale code="group.name"/></th>
<th data-field="dynamic" data-formatter="dynamicFormatter"><@locale code="group.dynamic"/></th>
<th data-field="description"><@locale code="common.text.description"/></th>
<th data-field="createdBy"><@locale code="common.text.createdby"/></th>
<th data-field="createdDate"><@locale code="common.text.createddate"/></th>
<th data-field="modifiedBy"><@locale code="common.text.modifiedby"/></th>
<th data-field="modifiedDate"><@locale code="common.text.modifieddate"/></th>
<th data-field="createdBy" data-visible="false"><@locale code="common.text.createdby"/></th>
<th data-field="createdDate" data-visible="false"><@locale code="common.text.createddate"/></th>
<th data-field="modifiedBy" data-visible="false"><@locale code="common.text.modifiedby"/></th>
<th data-field="modifiedDate" data-visible="false"><@locale code="common.text.modifieddate"/></th>
</tr>
</thead>
......
......@@ -21,7 +21,7 @@
</a>
</li>
<li>
<a class="side-nav-menu" href="<@base />/app/accounts/list/">
<a class="side-nav-menu" href="<@base />/accounts/list/">
<@locale code="navs.accounts"/>
<span class="fa fa-fw fa-vcard fa-lg"></span>
......@@ -99,6 +99,13 @@
<span class="fa fa-fw fa-globe fa-lg"></span>
</a>
</li>
<li>
<a class="side-nav-menu" href="<@base />/accountsstrategy/list/">
<@locale code="navs.accounts.strategy"/>
<span class="fa fa-fw fa-globe fa-lg"></span>
</a>
</li>
<li>
<a class="side-nav-menu" href="<@base />/synchronizers/list/">
<@locale code="navs.synchronizers"/>
......
......@@ -5,7 +5,9 @@
<#include "../layout/common.cssjs.ftl"/>
<link type="text/css" rel="stylesheet" href="<@base />/static/css/minitable.css"/>
<script type="text/javascript">
function dynamicFormatter(value, row, index){
return value=='0'? '<@locale code="common.text.no" />':'<@locale code="common.text.yes" />';
};
$(function () {
$("#selectBtn").on("click",function(){
var seldata=$.dataGridSelRowsData("#datagrid");
......@@ -58,11 +60,12 @@
<th data-checkbox="true"></th>
<th data-sortable="true" data-field="id" data-visible="false">Id</th>
<th data-field="name"><@locale code="role.name"/></th>
<th data-field="dynamic" data-formatter="dynamicFormatter"><@locale code="role.dynamic"/></th>
<th data-field="description"><@locale code="common.text.description"/></th>
<th data-field="createdBy"><@locale code="common.text.createdby"/></th>
<th data-field="createdDate"><@locale code="common.text.createddate"/></th>
<th data-field="modifiedBy"><@locale code="common.text.modifiedby"/></th>
<th data-field="modifiedDate"><@locale code="common.text.modifieddate"/></th>
<th data-field="createdBy" data-visible="false"><@locale code="common.text.createdby"/></th>
<th data-field="createdDate" data-visible="false"><@locale code="common.text.createddate"/></th>
<th data-field="modifiedBy" data-visible="false"><@locale code="common.text.modifiedby"/></th>
<th data-field="modifiedDate" data-visible="false"><@locale code="common.text.modifieddate"/></th>
</tr>
</thead>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册