完善核心业务用户管理页面
This commit is contained in:
parent
6e4b025bb6
commit
af541d0507
33
service-core/pom.xml
Normal file
33
service-core/pom.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>wg-basic</artifactId>
|
||||
<groupId>ink.wgink</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>service-core</artifactId>
|
||||
<description>用户、组织机构、角色、菜单、职位、组、权限全部</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ink.wgink</groupId>
|
||||
<artifactId>service-group</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ink.wgink</groupId>
|
||||
<artifactId>service-position</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ink.wgink</groupId>
|
||||
<artifactId>service-role</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,66 @@
|
||||
package ink.wgink.service.core.controller.api.manage;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.dtos.department.DepartmentDTO;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import ink.wgink.service.core.service.manage.ICoreManageService;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: CoreManageController
|
||||
* @Description: 核心管理
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/10 16:27
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "核心业务")
|
||||
@RestController
|
||||
@RequestMapping(ISystemConstant.API_PREFIX + "/core/manage")
|
||||
public class CoreManageController extends DefaultBaseController {
|
||||
|
||||
@Autowired
|
||||
private ICoreManageService coreManageService;
|
||||
|
||||
@ApiOperation(value = "组织部门导航列表", notes = "通过组织部门ID获取与查询有关的所有组织部门列表接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "departmentId", value = "组织部门上级ID", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("list-department-nav-path/department-id/{departmentId}")
|
||||
public List<DepartmentDTO> listDepartmentNavPathByDepartmentId(@PathVariable("departmentId") String departmentId) {
|
||||
return coreManageService.listDepartmentNavPathByDepartmentId(departmentId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "组织部门用户列表", notes = "组织部门用户列表接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "departmentId", value = "部门ID", paramType = "path"),
|
||||
@ApiImplicitParam(name = "roleId", value = "部门ID", paramType = "query"),
|
||||
@ApiImplicitParam(name = "positionId", value = "部门ID", paramType = "query"),
|
||||
@ApiImplicitParam(name = "groupId", value = "部门ID", paramType = "query"),
|
||||
@ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query"),
|
||||
@ApiImplicitParam(name = "userType", value = "用户类型", paramType = "query"),
|
||||
@ApiImplicitParam(name = "userStatus", value = "用户状态", paramType = "query"),
|
||||
@ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"),
|
||||
@ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"),
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("listpage-user/department-id/{departmentId}")
|
||||
public SuccessResultList<List<UserDTO>> listPageUserByDepartmentId(@PathVariable("departmentId") String departmentId, ListPage page) {
|
||||
Map<String, Object> requestParams = requestParams();
|
||||
page.setParams(requestParams);
|
||||
return coreManageService.listPageUserByDepartmentId(departmentId, page);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package ink.wgink.service.core.controller.route.manage;
|
||||
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.interfaces.user.IUserExpandBaseService;
|
||||
import ink.wgink.interfaces.user.IUserExpandOptionButton;
|
||||
import ink.wgink.service.user.util.UserUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* @ClassName: CoreManageRouteController
|
||||
* @Description: 核心管理
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/10 16:29
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.ROUTE_TAGS_PREFIX + "核心管理路由")
|
||||
@Controller
|
||||
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/core/manage")
|
||||
public class CoreManageRouteController {
|
||||
|
||||
@Autowired(required = false)
|
||||
private IUserExpandBaseService userExpandBaseService;
|
||||
@Autowired(required = false)
|
||||
private IUserExpandOptionButton userExpandOptionButton;
|
||||
|
||||
@GetMapping("list-department-tree")
|
||||
public ModelAndView listDepartmentTree() {
|
||||
ModelAndView modelAndView = new ModelAndView("core/manage/list-department-tree");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("list-department-user")
|
||||
public ModelAndView listDepartmentUser() {
|
||||
ModelAndView modelAndView = new ModelAndView("core/manage/list-department-user");
|
||||
UserUtil.setUserListPageExpand(userExpandBaseService, userExpandOptionButton, modelAndView);
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("save-department-user")
|
||||
public ModelAndView saveDepartmentUser() {
|
||||
ModelAndView modelAndView = new ModelAndView("core/manage/save-department-user");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("update-department-user")
|
||||
public ModelAndView updateDepartmentUser() {
|
||||
ModelAndView modelAndView = new ModelAndView("core/manage/update-department-user");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package ink.wgink.service.core.dao.manage;
|
||||
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: ICoreManageDao
|
||||
* @Description: 核心管理
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/11 14:51
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Repository
|
||||
public interface ICoreManageDao {
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
List<UserDTO> listUser(Map<String, Object> params);
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package ink.wgink.service.core.service.manage;
|
||||
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.dtos.department.DepartmentDTO;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: ICoreManageService
|
||||
* @Description: 核心管理
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/10 16:28
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public interface ICoreManageService {
|
||||
|
||||
/**
|
||||
* 组织部门导航列表
|
||||
*
|
||||
* @param departmentId
|
||||
* @return
|
||||
*/
|
||||
List<DepartmentDTO> listDepartmentNavPathByDepartmentId(String departmentId);
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<UserDTO> listUser(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 组织部门用户列表
|
||||
*
|
||||
* @param departmentId
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
SuccessResultList<List<UserDTO>> listPageUserByDepartmentId(String departmentId, ListPage page);
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package ink.wgink.service.core.service.manage.impl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.dtos.department.DepartmentDTO;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.pojo.pos.DepartmentPO;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import ink.wgink.service.core.dao.manage.ICoreManageDao;
|
||||
import ink.wgink.service.core.service.manage.ICoreManageService;
|
||||
import ink.wgink.service.department.service.IDepartmentService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: CoreManageServiceImpl
|
||||
* @Description: 核心管理业务
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/10 16:28
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class CoreManageServiceImpl extends DefaultBaseService implements ICoreManageService {
|
||||
|
||||
@Autowired
|
||||
private IDepartmentService departmentService;
|
||||
@Autowired
|
||||
private ICoreManageDao coreManageDao;
|
||||
|
||||
@Override
|
||||
public List<DepartmentDTO> listDepartmentNavPathByDepartmentId(String departmentId) {
|
||||
DepartmentPO departmentPO = departmentService.getPO(departmentId);
|
||||
if (departmentPO == null) {
|
||||
throw new SearchException("部门不存在");
|
||||
}
|
||||
List<DepartmentDTO> navList = new ArrayList<>();
|
||||
setDepartmentNav(navList, departmentPO);
|
||||
return navList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserDTO> listUser(Map<String, Object> params) {
|
||||
params = params == null ? getHashMap(0) : params;
|
||||
return coreManageDao.listUser(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuccessResultList<List<UserDTO>> listPageUserByDepartmentId(String departmentId, ListPage page) {
|
||||
page.getParams().put("departmentId", departmentId);
|
||||
PageHelper.startPage(page.getPage(), page.getRows());
|
||||
List<UserDTO> userDTOs = listUser(page.getParams());
|
||||
PageInfo<UserDTO> pageInfo = new PageInfo<>(userDTOs);
|
||||
return new SuccessResultList<>(userDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置部门导航
|
||||
*
|
||||
* @param navList
|
||||
* @param departmentPO
|
||||
*/
|
||||
private void setDepartmentNav(List<DepartmentDTO> navList, DepartmentPO departmentPO) {
|
||||
DepartmentDTO departmentDTO = new DepartmentDTO();
|
||||
BeanUtils.copyProperties(departmentPO, departmentDTO);
|
||||
navList.add(0, departmentDTO);
|
||||
if (StringUtils.equals(ISystemConstant.TREE_ROOT_ID, departmentPO.getDepartmentParentId())) {
|
||||
return;
|
||||
}
|
||||
DepartmentPO departmentParentPO = departmentService.getPO(departmentPO.getDepartmentParentId());
|
||||
setDepartmentNav(navList, departmentParentPO);
|
||||
}
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
<?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="ink.wgink.service.core.dao.manage.ICoreManageDao">
|
||||
|
||||
<!-- 用户列表 -->
|
||||
<select id="listUser" parameterType="map" resultMap="ink.wgink.service.user.dao.IUserDao.userDTO">
|
||||
SELECT
|
||||
user_id,
|
||||
user_password,
|
||||
user_username,
|
||||
user_name,
|
||||
user_phone,
|
||||
user_email,
|
||||
user_ukey,
|
||||
user_ukey_electronic_secret_key,
|
||||
user_type,
|
||||
user_state,
|
||||
user_expired_date,
|
||||
user_avatar,
|
||||
user_longitude,
|
||||
user_latitude,
|
||||
last_login_address,
|
||||
LEFT(last_login_time, 19) last_login_time,
|
||||
login_type,
|
||||
gmt_password_modified,
|
||||
remarks,
|
||||
LEFT(gmt_create, 19) gmt_create
|
||||
FROM
|
||||
sys_user t1
|
||||
WHERE
|
||||
t1.is_delete = 0
|
||||
AND
|
||||
t1.user_username != 'admin'
|
||||
<if test="keywords != null and keywords != ''">
|
||||
AND (
|
||||
t1.user_username LIKE CONCAT('%', #{keywords}, '%')
|
||||
OR
|
||||
t1.user_name LIKE CONCAT('%', #{keywords}, '%')
|
||||
OR
|
||||
t1.user_phone LIKE CONCAT('%', #{keywords}, '%')
|
||||
OR
|
||||
t1.user_email LIKE CONCAT('%', #{keywords}, '%')
|
||||
)
|
||||
</if>
|
||||
<if test="userType != null">
|
||||
AND
|
||||
t1.user_type = #{userType}
|
||||
</if>
|
||||
<if test="userState != null">
|
||||
AND
|
||||
t1.user_state = #{userState}
|
||||
</if>
|
||||
<if test="excludeUserType != null and excludeUserType != ''">
|
||||
AND
|
||||
t1.user_type != #{excludeUserType}
|
||||
</if>
|
||||
<!-- 组织部门用户 -->
|
||||
<if test="departmentId != null and departmentId != ''">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_department_user st1
|
||||
WHERE
|
||||
st1.department_id = #{departmentId}
|
||||
)
|
||||
</if>
|
||||
<if test="departmentIds != null and departmentIds.size > 0">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_department_user st1
|
||||
WHERE
|
||||
st1.department_id IN
|
||||
<foreach collection="departmentIds" index="index" open="(" separator="," close=")">
|
||||
#{departmentIds[${index}]}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
<if test="excludeDepartmentId != null and excludeDepartmentId != ''">
|
||||
AND
|
||||
t1.user_id NOT IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_department_user st1
|
||||
WHERE
|
||||
st1.department_id = #{excludeDepartmentId}
|
||||
)
|
||||
</if>
|
||||
<if test="excludeDepartmentIds != null and excludeDepartmentIds.size > 0">
|
||||
AND
|
||||
t1.user_id NOT IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_department_user st1
|
||||
WHERE
|
||||
st1.department_id IN
|
||||
<foreach collection="excludeDepartmentIds" index="index" open="(" separator="," close=")">
|
||||
#{excludeDepartmentIds[${index}]}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
<!-- 角色 -->
|
||||
<if test="roleId != null and roleId != ''">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_role_user st2
|
||||
WHERE
|
||||
st2.role_id = #{roleId}
|
||||
)
|
||||
</if>
|
||||
<if test="roleIds != null and roleIds.size > 0">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_role_user st2
|
||||
WHERE
|
||||
st2.role_id IN
|
||||
<foreach collection="roleIds" index="index" open="(" separator="," close=")">
|
||||
#{roleIds[${index}]}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
<!-- 用户职位 -->
|
||||
<if test="positionId != null and positionId != ''">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_position_user st3
|
||||
WHERE
|
||||
st3.position_id = #{positionId}
|
||||
)
|
||||
</if>
|
||||
<if test="positionIds != null and positionIds.size > 0">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_position_user st3
|
||||
WHERE
|
||||
st3.position_id IN
|
||||
<foreach collection="positionIds" index="index" open="(" separator="," close=")">
|
||||
#{positionIds[${index}]}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
<!-- 用户组 -->
|
||||
<if test="groupId != null and groupId != ''">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_group_user st4
|
||||
WHERE
|
||||
st4.group_id = #{groupId}
|
||||
)
|
||||
</if>
|
||||
<if test="groupIds != null and groupIds.size > 0">
|
||||
AND
|
||||
t1.user_id IN (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
sys_group_user st4
|
||||
WHERE
|
||||
st4.group_id IN
|
||||
<foreach collection="groupIds" index="index" open="(" separator="," close=")">
|
||||
#{groupIds[${index}]}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
<link rel="stylesheet" href="assets/js/vendor/zTree3/css/metroStyle/metroStyle.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/common.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md2 layui-col-sm2 layui-col-xs2" style="padding-right: 0px;">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body left-tree-wrap">
|
||||
<div id="leftTreeWrap">
|
||||
<ul id="leftTree" class="ztree"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md10 layui-col-sm10 layui-col-xs10" style="padding-left: 0px;">
|
||||
<div class="layui-card">
|
||||
<div id="listContentWrap" class="layui-card-body">
|
||||
<iframe id="listContent" frameborder="0" class="layadmin-iframe"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
var common;
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index', 'ztree', 'common'], function() {
|
||||
common = layui.common;
|
||||
var $ = layui.$;
|
||||
var $win = $(window);
|
||||
var resizeTimeout = null;
|
||||
var selectedDepartmentId = 0;
|
||||
var zTree;
|
||||
|
||||
// 初始化IFrame
|
||||
function initIFrame() {
|
||||
$('#listContent').attr('src', top.restAjax.path('route/core/manage/list-department-user?departmentId={departmentId}', [selectedDepartmentId]));
|
||||
}
|
||||
// 初始化大小
|
||||
function initSize() {
|
||||
$('#leftTreeWrap').css({
|
||||
height: $win.height() - 30,
|
||||
overflow: 'auto'
|
||||
});
|
||||
$('#listContentWrap').css({
|
||||
height: $win.height() - 50,
|
||||
});
|
||||
}
|
||||
// 初始化树
|
||||
function initThree() {
|
||||
var setting = {
|
||||
async: {
|
||||
enable: true,
|
||||
autoLoad: true,
|
||||
type: 'get',
|
||||
url: top.restAjax.path('api/department/listztree', []),
|
||||
autoParam: ['id'],
|
||||
otherParam: {},
|
||||
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;
|
||||
}
|
||||
},
|
||||
callback: {
|
||||
onAsyncSuccess: function(event, treeId, treeNode, msg) {
|
||||
if(selectedDepartmentId != 0) {
|
||||
return;
|
||||
}
|
||||
var rootDepartmentNodes = zTree.getNodesByParam('pId', 0);
|
||||
if(rootDepartmentNodes.length == 0) {
|
||||
initIFrame();
|
||||
return;
|
||||
}
|
||||
// 默认选中第一个
|
||||
selectedDepartmentId = rootDepartmentNodes[0].id;
|
||||
initIFrame();
|
||||
},
|
||||
onClick: function (event, treeId, treeNode) {
|
||||
selectedDepartmentId = treeNode.id;
|
||||
initIFrame();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
zTree = $.fn.zTree.init($("#leftTree"), setting);
|
||||
}
|
||||
initSize();
|
||||
initThree();
|
||||
|
||||
// 事件 - 页面变化
|
||||
$win.on('resize', function() {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(function() {
|
||||
initSize();
|
||||
}, 500);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,495 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/js/vendor/viewer/viewer.min.css">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-anim layui-anim-fadein">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<blockquote id="selectedDepartmentName" class="layui-elem-quote"></blockquote>
|
||||
<div class="test-table-reload-btn" style="margin-bottom: 10px;">
|
||||
<input type="hidden" id="userExpand" th:value="${userExpand}" th:if="${userExpand}">
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="keywords" class="layui-input search-item" placeholder="输入用户名、昵称">
|
||||
</div>
|
||||
<div class="layui-inline layui-form search-item">
|
||||
<select id="userType" name="userType">
|
||||
<option value="">选择类型</option>
|
||||
<option value="1">系统用户</option>
|
||||
<option value="2">普通用户</option>
|
||||
<option value="3">公共用户</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline layui-form search-item">
|
||||
<select id="userState" name="userState">
|
||||
<option value="">选择状态</option>
|
||||
<option value="0">正常</option>
|
||||
<option value="1">锁定</option>
|
||||
<option value="-1">未审核</option>
|
||||
<option value="-2">审核不通过</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<input type="hidden" id="roleId">
|
||||
<input type="text" id="roleName" class="layui-input search-item search-item-width-100" placeholder="选择角色">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<input type="hidden" id="positionId">
|
||||
<input type="text" id="positionName" class="layui-input search-item search-item-width-100" placeholder="选择职位">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<input type="hidden" id="groupId">
|
||||
<input type="text" id="groupName" class="layui-input search-item search-item-width-100" placeholder="选择用户组">
|
||||
</div>
|
||||
<div class="layui-btn-group">
|
||||
<button type="button" id="search" class="layui-btn layui-btn-sm">
|
||||
<i class="fa fa-lg fa-search"></i> 本级搜索
|
||||
</button>
|
||||
<!--
|
||||
<button type="button" id="globalSearch" class="layui-btn layui-btn-sm layui-btn-normal">
|
||||
<i class="fa fa-lg fa-search"></i> 全局搜索
|
||||
</button>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
|
||||
<!-- 表头按钮组 -->
|
||||
<script type="text/html" id="headerToolBar">
|
||||
<div class="layui-btn-group">
|
||||
<button type="button" class="layui-btn layui-btn-sm" lay-event="saveEvent">
|
||||
<i class="fa fa-lg fa-plus"></i> 新增
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-event="updateEvent">
|
||||
<i class="fa fa-lg fa-edit"></i> 编辑
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-danger layui-btn-sm" lay-event="removeEvent">
|
||||
<i class="fa fa-lg fa-trash"></i> 删除
|
||||
</button>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/js/common/layui-input-tree.js"></script>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script th:inline="javascript">
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index', 'table', 'laydate', 'upload', 'ztree'], function() {
|
||||
var $ = layui.$;
|
||||
var $win = $(window);
|
||||
var table = layui.table;
|
||||
var admin = layui.admin;
|
||||
var layer = layui.layer;
|
||||
var laydate = layui.laydate;
|
||||
var resizeTimeout = null;
|
||||
var expandOption = [[${expandOption}]];
|
||||
var layuiInputTree = new LayuiInputTree(layui);
|
||||
var queryParams = top.restAjax.params(window.location.href);
|
||||
var departmentId = queryParams.departmentId;
|
||||
var tableUrl = 'api/core/manage/listpage-user/department-id/{departmentId}';
|
||||
|
||||
// 初始化表格
|
||||
function initTable() {
|
||||
var colsArray = [
|
||||
{type:'checkbox', fixed: 'left'},
|
||||
{field:'rowNum', width:80, title: '序号', fixed: 'left', align:'center', templet: '<span>{{d.LAY_INDEX}}</span>'},
|
||||
{field:'userUsername', width:140, title: '用户名', sort: true, align:'center',
|
||||
templet: function(rowData) {
|
||||
return '<a href="javascript:void(0);" lay-event="userUsernameEvent">'+ rowData.userUsername +'</a>';
|
||||
}
|
||||
},
|
||||
{field:'userName', width:140, title: '昵称', sort: true, align:'center'},
|
||||
{field:'userType', width:90, title: '类型', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
if(item.userType == 1) {
|
||||
return '<span class="layui-badge layui-bg-green">系统用户</span>';
|
||||
} else if(item.userType == 2) {
|
||||
return '<span class="layui-badge layui-bg-orange">普通用户</span>';
|
||||
} else if(item.userType == 3) {
|
||||
return '<span class="layui-badge layui-bg-gray">公共用户</span>';
|
||||
}
|
||||
return '<span class="layui-badge">类型错误</span>';
|
||||
}
|
||||
},
|
||||
{field:'userState', width:80, title: '状态', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
var value;
|
||||
switch (item.userState) {
|
||||
case 1:
|
||||
value = '<span class="layui-badge layui-bg-blue">锁定</span>';
|
||||
break;
|
||||
case -1:
|
||||
value = '<span class="layui-badge layui-bg-gray">未审核</span>';
|
||||
break;
|
||||
case -2:
|
||||
value = '<span class="layui-badge">审核不通过</span>';
|
||||
break;
|
||||
default:
|
||||
value = '<span class="layui-badge layui-bg-green">正常</span>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
{field:'userPhone', width:140, title: '手机', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.userPhone) {
|
||||
return '-';
|
||||
}
|
||||
return item.userPhone;
|
||||
}
|
||||
},
|
||||
{field:'userEmail', width: 160, title: '邮箱', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.userEmail) {
|
||||
return '-';
|
||||
}
|
||||
return item.userEmail;
|
||||
}
|
||||
},
|
||||
{field:'userExpiredDate', width:180, title: '账号过期时间', align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.userExpiredDate) {
|
||||
return '<button type="button" class="layui-btn layui-btn-xs layui-btn-normal" lay-event="userExpiredDateEvent">' +
|
||||
'<i class="fa fa-clock-o"></i> 设置时间' +
|
||||
'</button>';
|
||||
}
|
||||
return item.userExpiredDate;
|
||||
}
|
||||
},
|
||||
{field:'lastLoginAddress', width:140, title: '登录地址', align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.lastLoginAddress) {
|
||||
return '-';
|
||||
}
|
||||
return item.lastLoginAddress;
|
||||
}
|
||||
},
|
||||
{field:'lastLoginTime', width:180, title: '最后登录系统时间', align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.lastLoginTime) {
|
||||
return '-';
|
||||
}
|
||||
return item.lastLoginTime;
|
||||
}
|
||||
},
|
||||
{field:'gmtCreate', width:180, title: '创建时间', align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.gmtCreate) {
|
||||
return '-';
|
||||
}
|
||||
return item.gmtCreate;
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
if($('#userExpand') && $('#userExpand').val()) {
|
||||
colsArray.push({
|
||||
field:'opition', width:190, title: '操作', fixed:'right', align:'center', templet: function(item) {
|
||||
return '<div class="layui-btn-group">' +
|
||||
'<button type="button" class="layui-btn layui-btn-xs" lay-event="resetPasswordEvent"><i class="fa fa-key"></i> 重置密码</button>'+
|
||||
'<button type="button" class="layui-btn layui-btn-xs layui-btn-primary" lay-event="userExpandEvent"><i class="fa fa-vcard"></i> 拓展属性</button>'+
|
||||
'</div>';
|
||||
}
|
||||
});
|
||||
} else {
|
||||
colsArray.push({
|
||||
field:'opition', width:110, title: '操作', fixed:'right', align:'center', templet: function(item) {
|
||||
return '<button type="button" class="layui-btn layui-btn-xs" lay-event="resetPasswordEvent">' +
|
||||
'<i class="fa fa-key"></i> 重置密码' +
|
||||
'</button>';
|
||||
}
|
||||
});
|
||||
}
|
||||
if(expandOption) {
|
||||
colsArray.push({
|
||||
field:'expandOpition', width: expandOption.width, title: expandOption.title, fixed: expandOption.fixed, align: expandOption.align, templet: function(item) {
|
||||
var btns = '<div class="layui-btn-group">';
|
||||
for(var i = 0, item; item = expandOption.btns[i++];) {
|
||||
btns += '<button type="button" class="layui-btn layui-btn-xs" lay-event="expandOpitionEvent" data-route="'+ item.route +'" data-title="'+ item.title +'">'+ item.title +'</button>';
|
||||
}
|
||||
btns += '</div>';
|
||||
return btns;
|
||||
}
|
||||
});
|
||||
}
|
||||
table.render({
|
||||
elem: '#dataTable',
|
||||
id: 'dataTable',
|
||||
url: top.restAjax.path(tableUrl, [departmentId]),
|
||||
width: admin.screen() > 1 ? '100%' : '',
|
||||
height: $win.height() - 122,
|
||||
limit: 20,
|
||||
limits: [20, 40, 60, 80, 100, 200],
|
||||
toolbar: '#headerToolBar',
|
||||
request: {
|
||||
pageName: 'page',
|
||||
limitName: 'rows'
|
||||
},
|
||||
cols: [
|
||||
colsArray
|
||||
],
|
||||
page: true,
|
||||
parseData: function(data) {
|
||||
return {
|
||||
'code': 0,
|
||||
'msg': '',
|
||||
'count': data.total,
|
||||
'data': data.rows
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
// 重载表格
|
||||
function reloadTable(currentPage) {
|
||||
table.reload('dataTable', {
|
||||
where: {
|
||||
keywords: $('#keywords').val(),
|
||||
startTime: $('#startTime').val(),
|
||||
endTime: $('#endTime').val(),
|
||||
userType: $('#userType').val(),
|
||||
userState: $('#userState').val(),
|
||||
roleId: $('#roleId').val(),
|
||||
positionId: $('#positionId').val(),
|
||||
groupId: $('#groupId').val()
|
||||
},
|
||||
page: {
|
||||
curr: currentPage
|
||||
},
|
||||
});
|
||||
}
|
||||
// 初始化日期
|
||||
function initDate() {
|
||||
// 日期选择
|
||||
laydate.render({
|
||||
elem: '#startTime',
|
||||
format: 'yyyy-MM-dd'
|
||||
});
|
||||
laydate.render({
|
||||
elem: '#endTime',
|
||||
format: 'yyyy-MM-dd'
|
||||
});
|
||||
}
|
||||
// 初始化部门导航
|
||||
function initDepartmentNav() {
|
||||
top.restAjax.get(top.restAjax.path('api/core/manage/list-department-nav-path/department-id/{departmentId}', [departmentId]), {}, null, function(code, data) {
|
||||
var navs = '';
|
||||
$.each(data, function(index, item) {
|
||||
if(navs.length != '') {
|
||||
navs += '<i class="fa fa-angle-right" aria-hidden="true" style="margin: 0 6px;"></i>'
|
||||
}
|
||||
navs += `<a href="route/core/manage/list-department-user?departmentId=${item.departmentId}">${item.departmentName}</a>`;
|
||||
})
|
||||
$('#selectedDepartmentName').append(navs);
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
})
|
||||
}
|
||||
// 初始化下拉树
|
||||
function initSelectInputTree() {
|
||||
// 角色下拉树选择
|
||||
layuiInputTree.initSelect({
|
||||
id: 'roleName',
|
||||
zTreeUrl: 'api/role/listztree',
|
||||
onConfirm: function(zTree, selectedNode) {
|
||||
if(!selectedNode) {
|
||||
$('#roleId').val('');
|
||||
return;
|
||||
}
|
||||
$('#roleId').val(selectedNode.id);
|
||||
}
|
||||
})
|
||||
// 职位下拉树选择
|
||||
layuiInputTree.initSelect({
|
||||
id: 'positionName',
|
||||
zTreeUrl: 'api/position/listztree',
|
||||
onConfirm: function(zTree, selectedNode) {
|
||||
if(!selectedNode) {
|
||||
$('#positionId').val('');
|
||||
return;
|
||||
}
|
||||
$('#positionId').val(selectedNode.id);
|
||||
}
|
||||
})
|
||||
// 用户组下拉树选择
|
||||
layuiInputTree.initSelect({
|
||||
id: 'groupName',
|
||||
zTreeUrl: 'api/group/listztree',
|
||||
onConfirm: function(zTree, selectedNode) {
|
||||
if(!selectedNode) {
|
||||
$('#groupId').val('');
|
||||
return;
|
||||
}
|
||||
$('#groupId').val(selectedNode.id);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 删除
|
||||
function removeData(ids) {
|
||||
top.dialog.msg(top.dataMessage.delete, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function (index) {
|
||||
top.dialog.close(index);
|
||||
var layIndex;
|
||||
top.restAjax.delete(top.restAjax.path('api/user/remove/{ids}', [ids]), {}, null, function (code, data) {
|
||||
top.dialog.msg(top.dataMessage.deleteSuccess, {time: 1000});
|
||||
reloadTable();
|
||||
}, function (code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function () {
|
||||
layIndex = top.dialog.msg(top.dataMessage.deleting, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function () {
|
||||
top.dialog.close(layIndex);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
initTable();
|
||||
initDate();
|
||||
initDepartmentNav();
|
||||
initSelectInputTree();
|
||||
// 事件 - 页面变化
|
||||
$win.on('resize', function() {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(function() {
|
||||
reloadTable();
|
||||
}, 500);
|
||||
});
|
||||
// 事件 - 搜索
|
||||
$(document).on('click', '#search', function() {
|
||||
reloadTable(1);
|
||||
});
|
||||
// 事件 - 增删改
|
||||
table.on('toolbar(dataTable)', function(obj) {
|
||||
var layEvent = obj.event;
|
||||
var checkStatus = table.checkStatus('dataTable');
|
||||
var checkDatas = checkStatus.data;
|
||||
if(layEvent === 'saveEvent') {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
area: ['100%', '100%'],
|
||||
shadeClose: true,
|
||||
anim: 2,
|
||||
content: top.restAjax.path('route/core/manage/save-department-user', []),
|
||||
end: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
} else if(layEvent === 'updateEvent') {
|
||||
if(checkDatas.length === 0) {
|
||||
top.dialog.msg(top.dataMessage.table.selectEdit);
|
||||
} else if(checkDatas.length > 1) {
|
||||
top.dialog.msg(top.dataMessage.table.selectOneEdit);
|
||||
} else {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
area: ['100%', '100%'],
|
||||
shadeClose: true,
|
||||
anim: 2,
|
||||
content: top.restAjax.path('route/user/update?userId={id}', [checkDatas[0].userId]),
|
||||
end: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if(layEvent === 'removeEvent') {
|
||||
if(checkDatas.length === 0) {
|
||||
top.dialog.msg(top.dataMessage.table.selectDelete);
|
||||
} else {
|
||||
var ids = '';
|
||||
for(var i = 0, item; item = checkDatas[i++];) {
|
||||
if(i > 1) {
|
||||
ids += '_';
|
||||
}
|
||||
ids += item.userId;
|
||||
}
|
||||
removeData(ids);
|
||||
}
|
||||
}
|
||||
});
|
||||
table.on('tool(dataTable)', function(obj) {
|
||||
var layEvent = obj.event;
|
||||
var data = obj.data;
|
||||
if(layEvent === 'userUsernameEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/user/update-username?userId={userId}', [data.userId]),
|
||||
title: '【'+ data.userName +'】修改用户名',
|
||||
width: '320px',
|
||||
height: '430px',
|
||||
onClose: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
} else if(layEvent === 'resetPasswordEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/user/rest-password?userId={userId}', [data.userId]),
|
||||
title: '【'+ data.userName +'】重置密码',
|
||||
width: '320px',
|
||||
height: '280px',
|
||||
onClose: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
} else if(layEvent === 'userExpiredDateEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/user/update-expired-date?userId={userId}', [data.userId]),
|
||||
title: '【'+ data.userName +'】设置账号过期时间',
|
||||
width: '274px',
|
||||
height: '395px',
|
||||
onClose: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
} else if(layEvent === 'userExpandEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('{userExpand}?userId={userId}', [$('#userExpand').val(), data.userId]),
|
||||
title: '【'+ data.userName +'】拓展属性',
|
||||
width: '60%',
|
||||
height: '80%',
|
||||
onClose: function() {}
|
||||
});
|
||||
} else if(layEvent === 'expandOpitionEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('{userExpandOptionRoute}?userId={userId}', [this.dataset.route, data.userId]),
|
||||
title: '【'+ data.userName +'】'+ this.dataset.title,
|
||||
width: '60%',
|
||||
height: '80%',
|
||||
onClose: function() {}
|
||||
});
|
||||
}
|
||||
});
|
||||
// 事件-排序
|
||||
table.on('sort(dataTable)', function(obj) {
|
||||
table.reload('dataTable', {
|
||||
initSort: obj,
|
||||
where: {
|
||||
sort: obj.field,
|
||||
order: obj.type
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,347 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-anim layui-anim-fadein">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-breadcrumb" lay-filter="breadcrumb" style="visibility: visible;">
|
||||
<a class="close" href="javascript:void(0);">上级列表</a><span lay-separator="">/</span>
|
||||
<a href="javascript:void(0);"><cite>新增内容</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md6 layui-col-sm8 layui-col-xs12">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户名 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userUsername" lay-verify="userUsername"
|
||||
placeholder="请输入用户名" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="userPassword" lay-verify="required"
|
||||
placeholder="请输入密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">昵称 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userName" lay-verify="required" placeholder="请输入昵称"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">类型 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="userType" value="1" title="系统用户">
|
||||
<input type="radio" name="userType" value="2" title="普通用户" checked>
|
||||
<input type="radio" name="userType" value="3" title="公共用户">
|
||||
</div>
|
||||
</div>
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
<div><b>类型说明</b></div>
|
||||
<div>系统用户:具有后台登录权限且参与后台、APP业务的用户</div>
|
||||
<div>普通用户:具有APP登录权限且参与APP业务的用户</div>
|
||||
<div>公共用户:来自小程序、公众号等公共平台自动创建且参与此类业务的的用户</div>
|
||||
</blockquote>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">状态 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="userState" value="0" title="正常" checked>
|
||||
<input type="radio" name="userState" value="1" title="锁定">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">手机</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="userPhone" placeholder="请输入手机" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userEmail" placeholder="请输入邮箱" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">过期时间</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userExpiredDate" id="userExpiredDate"
|
||||
placeholder="请选择过期日期,空表示永不过期" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">备注</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="remarks" placeholder="请输入备注" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md6 layui-col-sm8 layui-col-xs12">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">组织部门 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="hidden" id="departmentIds">
|
||||
<input type="text" id="departmentNames" class="layui-input" placeholder="勾选组织部门">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">角色</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="hidden" id="roleIds">
|
||||
<input type="text" id="roleNames" class="layui-input" placeholder="勾选角色">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">职位</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="hidden" id="positionIds">
|
||||
<input type="text" id="positionNames" class="layui-input" placeholder="勾选职位">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">组</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="hidden" id="groupIds">
|
||||
<input type="text" id="groupNames" class="layui-input" placeholder="勾选组">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs12">
|
||||
<div class="layui-form-item" style="text-align: center;">
|
||||
<img id="avatarImage" src="assets/images/profile-photo.jpg" title="点击修改头像">
|
||||
<input type="hidden" id="userAvatar" name="userAvatar">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交新增</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/js/common/layui-input-tree.js"></script>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'laydate', 'ztree'], function () {
|
||||
var $ = layui.$;
|
||||
var laydate = layui.laydate;
|
||||
var form = layui.form;
|
||||
var layuiInputTree = new LayuiInputTree(layui);
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化下拉树
|
||||
*/
|
||||
function initMultiSelectInputTree() {
|
||||
// 组织部门选择
|
||||
function initDepartmentSelect() {
|
||||
var selectedDepartments = [];
|
||||
layuiInputTree.initMultiSelect({
|
||||
id: 'departmentNames',
|
||||
zTreeUrl: 'api/department/listztree',
|
||||
checkboxType: {Y: '', N: ''},
|
||||
selectedDatas: selectedDepartments,
|
||||
onConfirm: function (zTree, selectedNodes) {
|
||||
selectedDepartments = selectedNodes;
|
||||
if (selectedNodes.length == 0) {
|
||||
$('#departmentIds').val('');
|
||||
return;
|
||||
}
|
||||
var departmentIds = '';
|
||||
$.each(selectedDepartments, function (index, item) {
|
||||
if (departmentIds != '') {
|
||||
departmentIds += ',';
|
||||
}
|
||||
departmentIds += item.id;
|
||||
})
|
||||
$('#departmentIds').val(departmentIds);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 角色选择
|
||||
function initRoleSelect() {
|
||||
var selectedRoles = [];
|
||||
layuiInputTree.initMultiSelect({
|
||||
id: 'roleNames',
|
||||
zTreeUrl: 'api/role/listztree',
|
||||
checkboxType: {Y: '', N: ''},
|
||||
selectedDatas: selectedRoles,
|
||||
onConfirm: function (zTree, selectedNodes) {
|
||||
selectedRoles = selectedNodes;
|
||||
if (selectedNodes.length == 0) {
|
||||
$('#roleIds').val('');
|
||||
return;
|
||||
}
|
||||
var roleIds = '';
|
||||
$.each(selectedRoles, function (index, item) {
|
||||
if (roleIds != '') {
|
||||
roleIds += ',';
|
||||
}
|
||||
roleIds += item.id;
|
||||
})
|
||||
$('#roleIds').val(roleIds);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 职位选择
|
||||
function initPositionSelect() {
|
||||
var selectedPositions = [];
|
||||
layuiInputTree.initMultiSelect({
|
||||
id: 'positionNames',
|
||||
zTreeUrl: 'api/position/listztree',
|
||||
checkboxType: {Y: '', N: ''},
|
||||
selectedDatas: selectedPositions,
|
||||
onConfirm: function (zTree, selectedNodes) {
|
||||
selectedPositions = selectedNodes;
|
||||
if (selectedNodes.length == 0) {
|
||||
$('#positionIds').val('');
|
||||
return;
|
||||
}
|
||||
var positionIds = '';
|
||||
$.each(selectedPositions, function (index, item) {
|
||||
if (positionIds != '') {
|
||||
positionIds += ',';
|
||||
}
|
||||
positionIds += item.id;
|
||||
})
|
||||
$('#positionIds').val(positionIds);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 组选择
|
||||
function initGroupSelect() {
|
||||
var selectedGroups = [];
|
||||
layuiInputTree.initMultiSelect({
|
||||
id: 'groupNames',
|
||||
zTreeUrl: 'api/group/listztree',
|
||||
checkboxType: {Y: '', N: ''},
|
||||
selectedDatas: selectedGroups,
|
||||
onConfirm: function (zTree, selectedNodes) {
|
||||
selectedGroups = selectedNodes;
|
||||
if (selectedNodes.length == 0) {
|
||||
$('#groupIds').val('');
|
||||
return;
|
||||
}
|
||||
var groupIds = '';
|
||||
$.each(selectedGroups, function (index, item) {
|
||||
if (groupIds != '') {
|
||||
groupIds += ',';
|
||||
}
|
||||
groupIds += item.id;
|
||||
})
|
||||
$('#groupIds').val(groupIds);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
initDepartmentSelect();
|
||||
initRoleSelect();
|
||||
initPositionSelect();
|
||||
initGroupSelect();
|
||||
}
|
||||
|
||||
initMultiSelectInputTree();
|
||||
|
||||
function initDate() {
|
||||
laydate.render({
|
||||
elem: '#userExpiredDate',
|
||||
trigger: 'click',
|
||||
format: 'yyyy-MM-dd HH:mm:ss'
|
||||
});
|
||||
}
|
||||
|
||||
initDate();
|
||||
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function (formData) {
|
||||
var authorizedGrantTypes = top.restAjax.checkBoxToString(formData.field, 'authorizedGrantTypes');
|
||||
formData.field.authorizedGrantTypes = authorizedGrantTypes;
|
||||
top.dialog.confirm(top.dataMessage.commit, function (index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.post(top.restAjax.path('api/user/save', []), formData.field, null, function (code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function (index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function () {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function (code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function () {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function () {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
form.verify({
|
||||
userUsername: function (value, item) {
|
||||
if (!new RegExp('^[a-zA-Z0-9_\\s·]+$').test(value)) {
|
||||
return '用户名不能有特殊字符';
|
||||
}
|
||||
if (/(^\_)|(\__)|(\_+$)/.test(value)) {
|
||||
return '用户名首尾不能出现下划线\'_\'';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#avatarImage').on('click', function () {
|
||||
top.dialog.open({
|
||||
url: 'route/file/uploadimage?fileId=' + $('#userAvatar').val(),
|
||||
title: '上传头像',
|
||||
width: '800px',
|
||||
height: '470px',
|
||||
onClose: function () {
|
||||
var uploadImage = top.dialog.dialogData.uploadImage;
|
||||
if (typeof (uploadImage) != 'undefined' && null != uploadImage && '' != uploadImage) {
|
||||
$('#avatarImage').attr('src', 'route/file/download/false/' + uploadImage);
|
||||
$('#userAvatar').val(uploadImage);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$('.close').on('click', function () {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,226 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-breadcrumb" lay-filter="breadcrumb" style="visibility: visible;">
|
||||
<a class="close" href="javascript:void(0);">上级列表</a><span lay-separator="">/</span>
|
||||
<a href="javascript:void(0);"><cite>编辑内容</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md6 layui-col-sm8 layui-col-xs12">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户名 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userUsername" lay-verify="userUsername" placeholder="请输入用户名" class="layui-input" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">新密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="userPassword" placeholder="修改密码,请输入新密码,不修改为空" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">昵称 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userName" lay-verify="required" placeholder="请输入昵称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">类型 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="userType" value="1" title="系统用户">
|
||||
<input type="radio" name="userType" value="2" title="普通用户">
|
||||
<input type="radio" name="userType" value="3" title="公共用户">
|
||||
</div>
|
||||
</div>
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
<div><b>类型说明</b></div>
|
||||
<div>系统用户:具有后台登录权限且参与后台、APP业务的用户</div>
|
||||
<div>普通用户:具有APP登录权限且参与APP业务的用户</div>
|
||||
<div>公共用户:来自小程序、公众号等公共平台自动创建且参与此类业务的的用户</div>
|
||||
</blockquote>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">状态 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="userState" value="0" title="正常">
|
||||
<input type="radio" name="userState" value="1" title="锁定">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">手机</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="userPhone" placeholder="请输入手机" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userEmail" placeholder="请输入邮箱" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">过期时间</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userExpiredDate" id="userExpiredDate" placeholder="请选择过期日期,空表示永不过期" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">备注</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="remarks" placeholder="请输入备注" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs12">
|
||||
<div class="layui-form-item" style="text-align: center;">
|
||||
<img id="avatarImage" src="assets/images/profile-photo.jpg" title="点击修改头像">
|
||||
<input type="hidden" id="userAvatar" name="userAvatar">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'laydate'], function(){
|
||||
var $ = layui.$;
|
||||
var laydate = layui.laydate;
|
||||
var form = layui.form;
|
||||
var userId = top.restAjax.params(window.location.href).userId;
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
function initDate() {
|
||||
laydate.render({
|
||||
elem: '#userExpiredDate',
|
||||
trigger: 'click',
|
||||
format: 'yyyy-MM-dd HH:mm:ss'
|
||||
});
|
||||
}
|
||||
initDate();
|
||||
|
||||
// 初始化
|
||||
function initData() {
|
||||
var self = this;
|
||||
var loadLayerIndex;
|
||||
top.restAjax.get(top.restAjax.path('api/user/get/{userId}', [userId]), {}, null, function(code, data) {
|
||||
form.val('dataForm', {
|
||||
userAvatar: data.userAvatar,
|
||||
userUsername: data.userUsername,
|
||||
userName: data.userName,
|
||||
userType: data.userType +'',
|
||||
userState: data.userState +'',
|
||||
userPhone: data.userPhone,
|
||||
userEmail: data.userEmail.toString(),
|
||||
userExpiredDate: data.userExpiredDate
|
||||
});
|
||||
form.render(null, 'dataForm');
|
||||
if($('#userAvatar').val() != '') {
|
||||
$('#avatarImage').attr('src', 'route/file/download/true/' + $('#userAvatar').val());
|
||||
} else {
|
||||
$('#userAvatar').val($('#userAvatar').val());
|
||||
}
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
}
|
||||
initData();
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
var authorizedGrantTypes = top.restAjax.checkBoxToString(formData.field, 'authorizedGrantTypes');
|
||||
formData.field.authorizedGrantTypes = authorizedGrantTypes;
|
||||
top.dialog.confirm(top.dataMessage.commit, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.put(top.restAjax.path('api/user/update/{userId}', [userId]), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
form.verify({
|
||||
userUsername: function(value, item) {
|
||||
if(!new RegExp('^[a-zA-Z0-9_\\s]+$').test(value)) {
|
||||
return '用户名不能有特殊字符';
|
||||
}
|
||||
if(/(^\_)|(\__)|(\_+$)/.test(value)){
|
||||
return '用户名首尾不能出现下划线\'_\'';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#avatarImage').on('click', function() {
|
||||
top.dialog.open({
|
||||
url: 'route/file/uploadimage?fileId='+ $('#userAvatar').val(),
|
||||
title: '上传头像',
|
||||
width: '800px',
|
||||
height: '470px',
|
||||
onClose: function() {
|
||||
var uploadImage = top.dialog.dialogData.uploadImage;
|
||||
if(typeof(uploadImage) != 'undefined' && null != uploadImage && '' != uploadImage) {
|
||||
$('#avatarImage').attr('src', 'route/file/download/true/' + uploadImage);
|
||||
$('#userAvatar').val(uploadImage);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user