一、数据库介绍:

1、account:帐务信息表
2、admin_info:管理员信息表
3、admin_role:管理员角色信息表
4、cost:资费信息表
5、privilege_info:权限信息表
6、role_info:角色信息表
7、role_privilege:角色权限表
8、service:业务信息表

二、项目结构及功能介绍:
2-1 项目结构:




2-2 功能介绍:
1、登录模块(login.jsp):
通过输入账号、密码、以及验证码可进行系统登录功能。
2、主页(pages/index.jsp):
项目主页,含有所有功能模块菜单。
3、角色管理(role/role_list.jsp):
角色管理页,可对表中各角色进行操作。
4、管理员(admin/admin_list.jsp):
管理员页,可对管理员角色进行功能操作。
5、资费管理(fee/fee_list):
资费管理页。可对用户资费信息进行操作。
6、账务账号(account/account_list.jsp):
账务账号页。可对用户账务信息进行操作。
7、业务账号(service/service_list.jsp):
业务账号页。可对用户业务信息进行操作。
8、账单管理(bill/bill_list.jsp):
账单管理页。可对用户账单信息进行操作。
9、报表(report/report_list.jsp)
报表管理页。可对账号的报表信息进行操作。
10、个人信息(user/user_info.jsp)
个人信息管理页。可对当前登录用户信息进行查看及操作。
11、个人信息---修改密码(user/user_modi_pwd.jsp)

个人信息的密码管理页。可对当前登录用户的密码进行操作。
三、SSM项目配置文件(必须):
1、pom.xml需要引入的项目坐标依赖:
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ssm.netctoss</groupId>
<artifactId>netctoss</artifactId>
<version>1.0-SNAPSHOT</version>
<name>netctoss</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--junit的依赖jar包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!-- servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- jackson依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
<!-- springmvc依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--mybatis的依赖jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--mysql的依赖jar包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!-- druid连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!-- spring事务依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- 参考版本对应 http://www.mybatis.org/spring/ -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
<!-- commons 文件上传jar -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</project>
2、JDBC连接池配置文件:jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm_db?serverTimezone=Asia/Shanghai&useTimezone=true&useSSL=false jdbc.username=root jdbc.password=root
3、Mybatis的配置文件:mybatis-config.xml
因为关于Mybatis的其它配置代码,因为在后文的spring-ioc.xml配置文件中配置完成,所以不需要再次配置,两者任选其一,配置一次即可。否则重复配置会严重报错。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<plugins>
<!-- 配置 PageHelper 分页插件 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
<property name="reasonable" value="true"/>
<property name="supportMethodsArguments" value="true"/>
<property name="params" value="pageNum=pageHelperStart;pageSize=pageHelperRows;"/>
</plugin>
</plugins>
</configuration>
4、spring的配置文件:spring-ioc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描,比如扫描Dao,Service-->
<context:component-scan base-package="com.ssm.netctoss"/>
<!--配置加载jdbc.properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置druid的连接池: 使用了spring容器来代替了mybatis的核心配置文件的数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置SqlSessionFactory的bean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--绑定数据源-->
<property name="dataSource" ref="dataSource"></property>
<!--加载mybatis的核心配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--配置加载各个pojo对应的XXXXMapper.xml 代替的是mybatis核心配置文件里的mapper设置-->
<property name="mapperLocations" value="classpath:com/ssm/netctoss/mapper/*.xml"/>
<property name="typeAliasesPackage" value="com.ssm.netctoss.pojo"/>
</bean>
<!--配置可以扫描mapper/dao接口的类型-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<property name="basePackage" value="com.ssm.netctoss.mapper"></property>
</bean>
</beans>
5、springMVC的配置文件:spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启SpringMVC的注解: 简化处理器映射器和处理器适配器的bean注册,以及JSON数据的传递-->
<mvc:annotation-driven/>
<!--静态资源的访问通过配置-->
<mvc:default-servlet-handler/>
<!--视图解析器的配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp" />
</bean>
</beans>
6、整合 spring + springMVC的配置文件:mainConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--整合ioc 和 mvc的两个配置文件-->
<import resource="classpath:spring-ioc.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
四、项目模块开发步骤:
(用service模块举例,其它模块的步骤相同)
1、数据库对应的实体类:XXX.java
(Service.java)
package com.ssm.netctoss.pojo;
import java.sql.Timestamp;
import java.util.Objects;
public class Service {
private Integer serviceId; // 业务ID
private Integer accountId; // 账户ID
private String unixHost; // UNIX主机地址
private String osUsername; // 操作系统用户名
private String loginPasswd; // 登录密码
private String status; // 服务状态。0:是暂停,1是开通,2是删除
private Timestamp createDate; // 创建日期
private Timestamp pauseDate; // 暂停日期
private Timestamp closeDate; // 关闭日期
private Integer costId; // 资费ID
private String idcardNo; // 身份证号
private String name;
// 构造函数
public Service() {}
public Service(Integer serviceId, Integer accountId, String unixHost, String osUsername, String loginPasswd, String status, Timestamp createDate, Timestamp pauseDate, Timestamp closeDate, Integer costId, String idcardNo, String name) {
this.serviceId = serviceId;
this.accountId = accountId;
this.unixHost = unixHost;
this.osUsername = osUsername;
this.loginPasswd = loginPasswd;
this.status = status;
this.createDate = createDate;
this.pauseDate = pauseDate;
this.closeDate = closeDate;
this.costId = costId;
this.idcardNo = idcardNo;
this.name = name;
}
// Getter和Setter方法
public Integer getServiceId() {
return serviceId;
}
public void setServiceId(Integer serviceId) {
this.serviceId = serviceId;
}
public Integer getAccountId() {
return accountId;
}
public void setAccountId(Integer accountId) {
this.accountId = accountId;
}
public String getUnixHost() {
return unixHost;
}
public void setUnixHost(String unixHost) {
this.unixHost = unixHost;
}
public String getOsUsername() {
return osUsername;
}
public void setOsUsername(String osUsername) {
this.osUsername = osUsername;
}
public String getLoginPasswd() {
return loginPasswd;
}
public void setLoginPasswd(String loginPasswd) {
this.loginPasswd = loginPasswd;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Timestamp getCreateDate() {
return createDate;
}
public void setCreateDate(Timestamp createDate) {
this.createDate = createDate;
}
public Timestamp getPauseDate() {
return pauseDate;
}
public void setPauseDate(Timestamp pauseDate) {
this.pauseDate = pauseDate;
}
public Timestamp getCloseDate() {
return closeDate;
}
public void setCloseDate(Timestamp closeDate) {
this.closeDate = closeDate;
}
public Integer getCostId() {
return costId;
}
public void setCostId(Integer costId) {
this.costId = costId;
}
public String getIdcardNo() {
return idcardNo;
}
public void setIdcardNo(String idcardNo) {
this.idcardNo = idcardNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 重写equals和hashCode
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Service)) return false;
Service service = (Service) o;
return Objects.equals(serviceId, service.serviceId) &&
Objects.equals(accountId, service.accountId) &&
Objects.equals(unixHost, service.unixHost) &&
Objects.equals(osUsername, service.osUsername) &&
Objects.equals(loginPasswd, service.loginPasswd) &&
Objects.equals(status, service.status) &&
Objects.equals(createDate, service.createDate) &&
Objects.equals(pauseDate, service.pauseDate) &&
Objects.equals(closeDate, service.closeDate) &&
Objects.equals(costId, service.costId) &&
Objects.equals(idcardNo, service.idcardNo) &&
Objects.equals(name, service.name);
}
@Override
public int hashCode() {
return Objects.hash(serviceId, accountId, unixHost, osUsername, loginPasswd, status, createDate, pauseDate, closeDate, costId, idcardNo, name);
}
// 重写toString
@Override
public String toString() {
return "Service{" +
"serviceId=" + serviceId +
", accountId=" + accountId +
", unixHost='" + unixHost + '\'' +
", osUsername='" + osUsername + '\'' +
", loginPasswd='" + loginPasswd + '\'' +
", status='" + status + '\'' +
", createDate=" + createDate +
", pauseDate=" + pauseDate +
", closeDate=" + closeDate +
", costId=" + costId +
", idcardNo='" + idcardNo + '\'' +
", name='" + name + '\'' +
'}';
}
}
2、实体类对应的Service接口:XXXService.java
(ServiceService.java)
package com.ssm.netctoss.service;
import com.github.pagehelper.PageInfo;
import com.ssm.netctoss.pojo.SearchCondition;
import com.ssm.netctoss.pojo.Service;
public interface ServiceService {
/**
* 分页并按条件查询服务列表
* @param condition 搜索条件
* @param pageNum 页码
* @return PageInfo<Service>
*/
PageInfo<Service> findByPageAndCondition(SearchCondition condition, Integer pageNum);
/**
* 添加新的服务
* @param service 服务对象
*/
void addService(Service service);
/**
* 根据服务ID查找服务
* @param serviceId 服务ID
* @return Service
*/
Service findByServiceId(Integer serviceId);
/**
* 更新服务信息
* @param service 服务对象
*/
void updateService(Service service);
/**
* 删除服务(逻辑删除)
* @param serviceId 服务ID
*/
void deleteService(Integer serviceId);
/**
* 改变服务状态
* @param serviceId 服务ID
* @param status 新状态
* @return 是否成功
*/
boolean changeStatus(Integer serviceId, String status);
}
3、每个Service接口对应的实现类Impl:XXXServiceImpl.java
(ServiceServiceImpl.java)
package com.ssm.netctoss.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssm.netctoss.mapper.ServiceMapper;
import com.ssm.netctoss.pojo.SearchCondition;
import com.ssm.netctoss.pojo.Service;
import com.ssm.netctoss.service.ServiceService;
import javax.annotation.Resource;
import java.util.List;
@org.springframework.stereotype.Service
public class ServiceServiceImpl implements ServiceService {
private int pageSize = 5; // 每页显示的数量
private int navigatePages = 5; // 导航栏显示页码数量
@Resource
private ServiceMapper serviceMapper;
@Override
public PageInfo<Service> findByPageAndCondition(SearchCondition condition, Integer pageNum) {
PageHelper.startPage(pageNum, pageSize); // 启用分页
List<Service> services = serviceMapper.findByPageAndCondition(condition); // 查询符合条件的服务列表
PageInfo<Service> pageInfo = new PageInfo<>(services, navigatePages); // 创建分页信息对象
return pageInfo;
}
@Override
public void addService(Service service) {
serviceMapper.addService(service); // 调用Mapper层插入新的服务
}
@Override
public Service findByServiceId(Integer serviceId) {
return serviceMapper.findByServiceId(serviceId); // 调用Mapper层根据ID查找服务
}
@Override
public void updateService(Service service) {
serviceMapper.updateService(service); // 调用Mapper层更新服务信息
}
@Override
public void deleteService(Integer serviceId) {
serviceMapper.deleteService(serviceId); // 调用Mapper层逻辑删除服务
}
@Override
public boolean changeStatus(Integer serviceId, String status) {
int result = serviceMapper.changeStatus(serviceId, status); // 调用Mapper层更新服务状态
return result > 0;
}
}
4、每个实体类对应的Mapper接口:XXXMapper.java
(ServiceMapper.java)
package com.ssm.netctoss.mapper;
import com.ssm.netctoss.pojo.SearchCondition;
import com.ssm.netctoss.pojo.Service;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ServiceMapper {
/**
* 分页并按条件查询服务列表
* @param condition 搜索条件
* @return List<Service> 服务列表
*/
List<Service> findByPageAndCondition(SearchCondition condition);
/**
* 添加新的服务
* @param service 服务对象
*/
void addService(Service service);
/**
* 根据服务ID查找服务
* @param serviceId 服务ID
* @return Service
*/
Service findByServiceId(Integer serviceId);
/**
* 更新服务信息
* @param service 服务对象
*/
void updateService(Service service);
/**
* 逻辑删除服务
* @param serviceId 服务ID
*/
void deleteService(Integer serviceId);
/**
* 改变服务状态
* @param serviceId 服务ID
* @param status 新状态
* @return 受影响的行数
*/
int changeStatus(@Param("serviceId") Integer serviceId, @Param("status") String status);
}
5、每个实体类对应的Mapper.xml配置文件:XXXMapper.xml
(ServiceMapper.xml)
<?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="com.ssm.netctoss.mapper.ServiceMapper">
<!-- 结果映射 -->
<resultMap id="serviceMap" type="Service">
<id column="service_id" property="serviceId" />
<result column="account_id" property="accountId" />
<result column="unix_host" property="unixHost" />
<result column="os_username" property="osUsername" />
<result column="login_passwd" property="loginPasswd" />
<result column="status" property="status" />
<result column="create_date" property="createDate" />
<result column="pause_date" property="pauseDate" />
<result column="close_date" property="closeDate" />
<result column="cost_id" property="costId" />
<result column="idcard_no" property="idcardNo" />
<result column="name" property="name" />
</resultMap>
<!-- 根据条件和分页查询服务 -->
<select id="findByPageAndCondition" parameterType="SearchCondition" resultMap="serviceMap">
SELECT s.*, a.idcard_no, c.name
FROM service s
JOIN account a ON s.account_id = a.account_id
JOIN cost c ON s.cost_id = c.cost_id
<where>
<if test="osUsername != null and osUsername != '' ">
AND s.os_username = #{osUsername}
</if>
<if test="unixHost != null and unixHost != '' ">
AND s.unix_host = #{unixHost}
</if>
<if test="idcardNo != null and idcardNo != '' ">
AND a.idcard_no = #{idcardNo}
</if>
<if test="status != null and status != '-1' ">
AND s.status = #{status}
</if>
</where>
ORDER BY s.service_id
</select>
<!-- 添加新服务 -->
<insert id="addService" parameterType="Service">
INSERT INTO service (account_id, unix_host, os_username, login_passwd, status, create_date, cost_id)
VALUES (#{accountId}, #{unixHost}, #{osUsername}, #{loginPasswd}, #{status}, #{createDate}, #{costId})
</insert>
<!-- 根据serviceId查询服务 -->
<select id="findByServiceId" parameterType="int" resultMap="serviceMap">
SELECT s.*, a.idcard_no, c.name
FROM service s
JOIN account a ON s.account_id = a.account_id
JOIN cost c ON s.cost_id = c.cost_id
WHERE s.service_id = #{serviceId}
</select>
<!-- 更新服务信息 -->
<update id="updateService" parameterType="Service">
UPDATE service
SET account_id = #{accountId},
unix_host = #{unixHost},
os_username = #{osUsername},
login_passwd = #{loginPasswd},
status = #{status},
create_date = #{createDate},
pause_date = #{pauseDate},
close_date = #{closeDate},
cost_id = #{costId}
WHERE service_id = #{serviceId}
</update>
<!-- 逻辑删除服务(设置状态为关闭) -->
<update id="deleteService" parameterType="int">
UPDATE service
SET status = '2'
WHERE service_id = #{serviceId}
</update>
<!-- 改变服务状态 -->
<update id="changeStatus" parameterType="map">
UPDATE service
SET status = #{status}
WHERE service_id = #{serviceId}
</update>
</mapper>
6、XXX模块对应的前端 jsp 主界面:
(service_list.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电信资费管理系统</title>
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global.css" />
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global_color.css" />
<script src="${pageContext.request.contextPath}/statics/js/services.js"></script>
<script language="javascript" type="text/javascript">
//显示角色详细信息
function showDetail(flag, a) {
var detailDiv = a.parentNode.getElementsByTagName("div")[0];
if (flag) {
detailDiv.style.display = "block";
}
else
detailDiv.style.display = "none";
}
//删除
function deleteAccount(serviceId) {
var r = window.confirm("确定要删除此业务账号吗?删除后将不能恢复。");
if (r) {
// 发送请求到 delete 端点,设置 serviceId
window.location.href = 'delete?serviceId=' + serviceId;
}
}
//开通或暂停
function setState(serviceId, newStatus) {
var action = newStatus === '1' ? "开通" : "暂停";
var confirmMsg = "确定要" + action + "此业务账号吗?";
var r = window.confirm(confirmMsg);
if (r) {
// 发送请求到 changeStatus 端点,设置状态
window.location.href = 'changeStatus?serviceId=' + serviceId + '&status=' + newStatus;
}
}
//分页搜索
function searchService(page) {
document.getElementById("pageNum").value = page;
document.getElementById("myForm").submit();
}
</script>
</head>
<body>
<!--Logo区域开始-->
<div id="header">
<img src="../statics/images/logo.png" alt="logo" class="left"/>
<a href="#">[退出]</a>
</div>
<!--Logo区域结束-->
<!-- 导航区域开始 -->
<jsp:include page="../nav.jsp" />
<!-- 导航区域结束 -->
<!--主要区域开始-->
<div id="main">
<form action="searchService" method="post" id="myForm">
<!--查询-->
<div class="search_add">
<input type="hidden" id="pageNum" name="pageNum" value="${pageInfo.pageNum}" />
<div>OS 账号:<input type="text" name="osUsername" value="${condition.osUsername}" class="width100 text_search" /></div>
<div>服务器 IP:<input type="text" name="unixHost" value="${condition.unixHost}" class="width100 text_search" /></div>
<div>身份证:<input type="text" name="idcardNo" value="${condition.idcardNo}" class="text_search" /></div>
<div>状态:
<select class="select_search" name="status">
<option value="-1" <c:if test="${condition.status == '-1'}">selected</c:if> >全部</option>
<option value="1" <c:if test="${condition.status == '1'}">selected</c:if> >开通</option>
<option value="0" <c:if test="${condition.status == '0'}">selected</c:if> >暂停</option>
<option value="2" <c:if test="${condition.status == '2'}">selected</c:if> >删除</option>
</select>
</div>
<div><input type="button" value="搜索" class="btn_search" id="searchBtn" οnclick="searchService(1)" /></div>
<input type="button" value="增加" class="btn_add" οnclick="location.href='toAdd';" />
</div>
<!--删除的操作提示-->
<div id="operate_result_info" class="operate_success" style="display: none;">
<img src="../statics/images/close.png" οnclick="this.parentNode.style.display='none';" />
操作成功!
</div>
<!--数据区域:用表格展示数据-->
<div id="data">
<table id="datalist">
<tr>
<th class="width50">业务ID</th>
<th class="width70">账务账号ID</th>
<th class="width150">身份证</th>
<th class="width70">姓名</th>
<th>OS 账号</th>
<th class="width50">状态</th>
<th class="width100">服务器 IP</th>
<th class="width100">资费</th>
<th class="width200">操作</th>
</tr>
<c:forEach items="${pageInfo.list}" var="service">
<tr>
<td><a href="service_detail.jsp" title="查看明细">${service.serviceId}</a></td>
<td>${service.accountId}</td>
<td>${service.idcardNo}</td>
<td>高哈哈</td>
<td>${service.osUsername}</td>
<td>
<c:choose>
<c:when test="${service.status == '0'}">暂停</c:when>
<c:when test="${service.status == '1'}">开通</c:when>
<c:when test="${service.status == '2'}">删除</c:when>
<c:otherwise>未知状态</c:otherwise>
</c:choose>
</td>
<td>${service.unixHost}</td>
<td>
<a class="summary" οnmοuseοver="showDetail(true,this);" οnmοuseοut="showDetail(false,this);">包 20 小时</a>
<!--浮动的详细信息-->
<div class="detail_info" style="display: none;">
20小时,24.5 元,超出部分 0.03元/分钟
</div>
</td>
<td class="td_modi">
<c:choose>
<c:when test="${service.status == '1'}">
<input type="button" value="暂停" class="btn_pause" οnclick="setState(${service.serviceId}, '0');" />
</c:when>
<c:otherwise>
<input type="button" value="开通" class="btn_start" οnclick="setState(${service.serviceId}, '1');" />
</c:otherwise>
</c:choose>
<input type="button" value="修改" class="btn_modify" οnclick="location.href='modify?serviceId=${service.serviceId}';" />
<input type="button" value="删除" class="btn_delete" οnclick="deleteAccount(${service.serviceId});" />
</td>
</tr>
</c:forEach>
</table>
<p>业务说明:<br />
1、创建即开通,记载创建时间;<br />
2、暂停后,记载暂停时间;<br />
3、重新开通后,删除暂停时间;<br />
4、删除后,记载删除时间,标示为删除,不能再开通、修改、删除;<br />
5、业务账号不设计修改密码功能,由用户自服务功能实现;<br />
6、暂停和删除状态的账务账号下属的业务账号不能被开通。
</p>
</div>
<!--分页-->
<div id="pages">
<a href="javascript:searchService(1)">首页</a>
<!-- 上一页 -->
<c:choose>
<c:when test="${pageInfo.pageNum > 1}">
<a href="javascript:searchService(${pageInfo.pageNum - 1})">上一页</a>
</c:when>
<c:otherwise>
<a href="#" class="disabled">上一页</a>
</c:otherwise>
</c:choose>
<!-- 中间页码动态生成 -->
<c:forEach begin="${pageInfo.navigateFirstPage}" end="${pageInfo.navigateLastPage}" var="nav">
<c:choose>
<c:when test="${pageInfo.pageNum == nav}">
<a href="#" class="current_page">${nav}</a> <!-- 当前页 -->
</c:when>
<c:otherwise>
<a href="javascript:searchService(${nav})" class="page_link">${nav}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<!-- 下一页 -->
<c:choose>
<c:when test="${pageInfo.pageNum < pageInfo.pages}">
<a href="javascript:searchService(${pageInfo.pageNum + 1})">下一页</a>
</c:when>
<c:otherwise>
<a href="#" class="disabled">下一页</a>
</c:otherwise>
</c:choose>
<!-- 末页 -->
<a href="javascript:searchService(${pageInfo.pages})">末页</a>
</div>
</form>
</div>
<!--主要区域结束-->
<div id="footer">
<span>[Copyright © 1996-2024 NET Corporation, All Rights Reserved]</span>
<br />
<span>版权所有(C) Company NET</span>
</div>
<!-- 显示操作结果提示 -->
<c:if test="${param.operation == 'changeStatus' && param.result == 'success'}">
<script type="text/javascript">
document.getElementById("operate_result_info").style.display = "block";
document.getElementById("operate_result_info").innerHTML = '<img src="../statics/images/close.png" οnclick="this.parentNode.style.display=\'none\';" />状态更新成功!';
</script>
</c:if>
<c:if test="${param.operation == 'changeStatus' && param.result == 'error'}">
<script type="text/javascript">
document.getElementById("operate_result_info").style.display = "block";
document.getElementById("operate_result_info").innerHTML = '<img src="../statics/images/close.png" οnclick="this.parentNode.style.display=\'none\';" />状态更新失败,请重试!';
</script>
</c:if>
</body>
</html>
7、XXX前端 jsp 主界面中对应的添加(add)功能:
(service_add.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电信资费管理系统</title>
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global.css" />
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global_color.css" />
<script language="javascript" type="text/javascript">
//保存成功的提示信息
function showResult() {
showResultDiv(true);
window.setTimeout("showResultDiv(false);", 3000);
}
function showResultDiv(flag) {
var divResult = document.getElementById("save_result_info");
if (flag)
divResult.style.display = "block";
else
divResult.style.display = "none";
}
//自动查询账务账号
function searchAccounts(txtObj) {
//document.getElementById("a1").innerHTML = txtObj.value;
}
</script>
</head>
<body>
<!--Logo区域开始-->
<div id="header">
<img src="../statics/images/logo.png" alt="logo" class="left"/>
<a href="#">[退出]</a>
</div>
<!--Logo区域结束-->
<!-- 导航区域开始 -->
<jsp:include page="../nav.jsp" />
<!-- 导航区域结束 -->
<!--主要区域开始-->
<div id="main">
<!--保存操作的提示信息-->
<div id="save_result_info" class="save_fail">保存失败!192.168.0.23服务器上已经开通过 OS 账号 “mary”。</div>
<form action="add" method="post" class="main_form">
<!--内容项-->
<div class="text_info clearfix"><span>身份证:</span></div>
<div class="input_info">
<input type="text" name="idcardNo" class="width180" required />
<input type="button" value="查询账务账号" class="btn_search_large" />
<span class="required">*</span>
<div class="validate_msg_short">没有此身份证号,请重新录入。</div>
</div>
<div class="text_info clearfix"><span>账务账号:</span></div>
<div class="input_info">
<input type="text" name="accountId" οnkeyup="searchAccounts(this);" required />
<span class="required">*</span>
<div class="validate_msg_long">没有此账务账号,请重新录入。</div>
</div>
<div class="text_info clearfix"><span>资费类型:</span></div>
<div class="input_info">
<select name="costId" required>
<option value="1">包 20 小时</option>
<option value="2">包 40 小时</option>
<option value="3">包 60 小时</option>
<option value="4">包月</option>
</select>
</div>
<div class="text_info clearfix"><span>服务器 IP:</span></div>
<div class="input_info">
<input type="text" name="unixHost" required />
<span class="required">*</span>
<div class="validate_msg_long">15 长度,符合IP的地址规范</div>
</div>
<div class="text_info clearfix"><span>登录 OS 账号:</span></div>
<div class="input_info">
<input type="text" name="osUsername" required />
<span class="required">*</span>
<div class="validate_msg_long">8长度以内的字母、数字和下划线的组合</div>
</div>
<div class="text_info clearfix"><span>密码:</span></div>
<div class="input_info">
<input type="password" name="loginPasswd" required />
<span class="required">*</span>
<div class="validate_msg_long">30长度以内的字母、数字和下划线的组合</div>
</div>
<div class="text_info clearfix"><span>重复密码:</span></div>
<div class="input_info">
<input type="password" name="confirmPasswd" required />
<span class="required">*</span>
<div class="validate_msg_long">两次密码必须相同</div>
</div>
<!--操作按钮-->
<div class="button_info clearfix">
<input type="submit" value="保存" class="btn_save" />
<input type="button" value="取消" class="btn_save" />
</div>
</form>
</div>
<!--主要区域结束-->
<div id="footer">
<span>[Copyright © 1996-2024 NET Corporation, All Rights Reserved]</span>
<br />
<span>版权所有(C) Company NET</span>
</div>
</body>
</html>
8、XXX前端 jsp 主界面中对应的修改(modi)功能:
(service_modi.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电信资费管理系统 - 修改服务</title>
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global.css" />
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global_color.css" />
<script src="${pageContext.request.contextPath}/statics/js/services.js"></script>
<script language="javascript" type="text/javascript">
// 其他 JavaScript 代码
</script>
</head>
<body>
<!--Logo区域开始-->
<div id="header">
<img src="../statics/images/logo.png" alt="logo" class="left"/>
<a href="#">[退出]</a>
</div>
<!--Logo区域结束-->
<!-- 导航区域开始 -->
<jsp:include page="../nav.jsp" />
<!-- 导航区域结束 -->
<!--主要区域开始-->
<div id="main">
<form action="saveModify" method="post" id="myForm">
<!--修改表单内容-->
<div class="form_section">
<!--业务账号ID-->
<div class="text_info clearfix"><span>业务账号ID:</span></div>
<div class="input_info">
<input type="hidden" name="serviceId" value="${service.serviceId}" />
<input type="hidden" name="accountId" value="${service.accountId}" />
<!-- 如果不需要修改 accountId,使用只读文本框 -->
<input type="text" value="${service.accountId}" readonly class="readonly" />
</div>
<!-- UNIX 主机地址 -->
<div class="text_info clearfix"><span>UNIX 主机地址:</span></div>
<div class="input_info">
<input type="hidden" name="unixHost" value="${service.unixHost}" />
<input type="text" value="${service.unixHost}" readonly class="readonly" />
</div>
<!--OS 账号-->
<div class="text_info clearfix"><span>OS 账号:</span></div>
<div class="input_info">
<input type="text" name="osUsername" value="${service.osUsername}" class="text_input" />
</div>
<!--登录密码-->
<div class="text_info clearfix"><span>登录密码:</span></div>
<div class="input_info">
<input type="password" name="loginPasswd" value="${service.loginPasswd}" class="text_input" />
</div>
<!--状态-->
<div class="text_info clearfix"><span>状态:</span></div>
<div class="input_info">
<select name="status" class="text_input">
<option value="1" <c:if test="${service.status == '1'}">selected</c:if>>开通</option>
<option value="0" <c:if test="${service.status == '0'}">selected</c:if>>暂停</option>
<option value="2" <c:if test="${service.status == '2'}">selected</c:if>>删除</option>
</select>
</div>
<!--创建时间-->
<div class="text_info clearfix">
<span>创建时间:</span>
</div>
<div class="input_info">
<input type="text" name="createDate" value="<fmt:formatDate value='${service.createDate}' pattern='yyyy-MM-dd HH:mm:ss' />" readonly class="readonly" />
</div>
<!--暂停时间-->
<div class="text_info clearfix"><span>暂停时间:</span></div>
<div class="input_info">
<input type="text" name="pauseDate" value="<fmt:formatDate value='${service.pauseDate}' pattern='yyyy-MM-dd HH:mm:ss' />" class="text_input" />
</div>
<!--关闭时间-->
<div class="text_info clearfix"><span>关闭时间:</span></div>
<div class="input_info">
<input type="text" name="closeDate" value="<fmt:formatDate value='${service.closeDate}' pattern='yyyy-MM-dd HH:mm:ss' />" class="text_input" />
</div>
<!--资费ID-->
<div class="text_info clearfix"><span>资费ID:</span></div>
<div class="input_info">
<input type="text" name="costId" value="${service.costId}" class="text_input" />
</div>
<!--提交按钮-->
<div class="form_actions">
<input type="submit" value="保存" class="btn_save" />
<input type="button" value="取消" class="btn_save btn_cancel" οnclick="location.href='searchService';" />
</div>
</div>
</form>
</div>
<!--主要区域结束-->
<div id="footer">
<span>[Copyright © 1996-2024 NET Corporation, All Rights Reserved]</span>
<br />
<span>版权所有(C) Company NET</span>
</div>
</body>
</html>
9、XXX前端 jsp 主界面中对应的查找(detail)功能:
(service_detail.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电信资费管理系统</title>
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global.css" />
<link type="text/css" rel="stylesheet" media="all" href="../statics/styles/global_color.css" />
</head>
<body>
<!--Logo区域开始-->
<div id="header">
<img src="../statics/images/logo.png" alt="logo" class="left"/>
<a href="#">[退出]</a>
</div>
<!--Logo区域结束-->
<!-- 导航区域开始 -->
<jsp:include page="../nav.jsp" />
<!-- 导航区域结束 -->
<!--主要区域开始-->
<div id="main">
<form action="" method="" class="main_form">
<!--必填项-->
<div class="text_info clearfix"><span>业务账号ID:</span></div>
<div class="input_info">
<input type="text" value="${service.id}" readonly class="readonly" />
</div>
<div class="text_info clearfix"><span>账务账号ID:</span></div>
<div class="input_info">
<input type="text" value="${service.accountId}" readonly class="readonly" />
</div>
<div class="text_info clearfix"><span>客户姓名:</span></div>
<div class="input_info">
<input type="text" readonly class="readonly" value="${service.customerName}" />
</div>
<div class="text_info clearfix"><span>身份证号码:</span></div>
<div class="input_info">
<input type="text" readonly class="readonly" value="${service.idCard}" />
</div>
<div class="text_info clearfix"><span>服务器 IP:</span></div>
<div class="input_info">
<input type="text" value="${service.unixHost}" readonly class="readonly" />
</div>
<div class="text_info clearfix"><span>OS 账号:</span></div>
<div class="input_info">
<input type="text" value="${service.osUsername}" readonly class="readonly" />
</div>
<div class="text_info clearfix"><span>状态:</span></div>
<div class="input_info">
<select disabled>
<option value="active" ${service.status == 'active' ? 'selected' : ''}>开通</option>
<option value="paused" ${service.status == 'paused' ? 'selected' : ''}>暂停</option>
<option value="deleted" ${service.status == 'deleted' ? 'selected' : ''}>删除</option>
</select>
</div>
<div class="text_info clearfix"><span>开通时间:</span></div>
<div class="input_info">
<input type="text" value="${service.startTime}" readonly class="readonly" />
</div>
<div class="text_info clearfix"><span>资费 ID:</span></div>
<div class="input_info">
<input type="text" value="${service.costId}" class="readonly" readonly />
</div>
<div class="text_info clearfix"><span>资费名称:</span></div>
<div class="input_info">
<input type="text" value="${service.costName}" readonly class="width200 readonly" />
</div>
<div class="text_info clearfix"><span>资费说明:</span></div>
<div class="input_info_high">
<textarea class="width300 height70 readonly" readonly>${service.costDescription}</textarea>
</div>
<!--操作按钮-->
<div class="button_info clearfix">
<input type="button" value="返回" class="btn_save" οnclick="location.href='service_list.jsp';" />
</div>
</form>
</div>
<!--主要区域结束-->
<div id="footer">
<span>[Copyright © 1996-2024 NET Corporation, All Rights Reserved]</span>
<br />
<span>版权所有(C) Company NET</span>
</div>
</body>
</html>
10、每个模块对应的Controller文件:XXXController.java
(ServiceConrtoller.java)
package com.ssm.netctoss.controller;
import com.github.pagehelper.PageInfo;
import com.ssm.netctoss.pojo.SearchCondition;
import com.ssm.netctoss.pojo.Service;
import com.ssm.netctoss.service.ServiceService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import java.sql.Timestamp;
@Controller
@RequestMapping("/service")
public class ServiceController {
@Resource
private ServiceService serviceService;
/**
* 查询所有或按条件搜索服务
*/
@RequestMapping("searchService")
public String findByPageAndCondition(SearchCondition condition, Integer pageNum, Model model) {
if (pageNum == null) {
pageNum = 1;
}
PageInfo<Service> pageInfo = serviceService.findByPageAndCondition(condition, pageNum);
System.out.println(pageInfo);
model.addAttribute("pageInfo", pageInfo);
// 将查询条件字段再次绑定到model, 进行回显设置。
model.addAttribute("condition", condition);
return "service/service_list";
}
/**
* 显示添加服务页面
* URL示例: /service/toAdd
*/
@RequestMapping("toAdd")
public String toAddPage() {
return "service/service_add"; // 返回添加页面视图
}
/**
* 处理添加服务的请求
* URL示例: /service/add
*/
@RequestMapping(value = "add", method = RequestMethod.POST)
public ModelAndView addService(Service service, ModelAndView mav) {
// 设置默认状态和创建时间等信息
service.setStatus("1"); // 假设1表示启用
service.setCreateDate(new Timestamp(System.currentTimeMillis()));
// 调用服务层添加服务
serviceService.addService(service);
// 设置返回视图,重定向到列表页面
mav.setViewName("redirect:/service/searchService");
return mav;
}
/**
* 显示修改服务页面
* URL示例: /service/modify?serviceId=1
*/
@RequestMapping("modify")
public ModelAndView modifyService(@RequestParam("serviceId") Integer serviceId, ModelAndView mav) {
System.out.println("Received serviceId: " + serviceId); // 日志输出
Service service = serviceService.findByServiceId(serviceId);
if (service == null) {
mav.setViewName("error");
mav.addObject("message", "未找到对应的服务。");
return mav;
}
mav.setViewName("service/service_modi");
mav.addObject("service", service);
return mav;
}
/**
* 处理修改服务的请求
* URL示例: /service/saveModify
*/
@RequestMapping(value = "saveModify", method = RequestMethod.POST)
public ModelAndView saveModifiedService(Service service, ModelAndView mav) {
// 调用服务层更新服务
serviceService.updateService(service);
// 设置返回视图,重定向到列表页面
mav.setViewName("redirect:/service/searchService");
return mav;
}
/**
* 删除服务(逻辑删除)
* URL示例: /service/delete?serviceId=1
*/
@RequestMapping("delete")
public String deleteService(@RequestParam("serviceId") Integer serviceId) {
serviceService.deleteService(serviceId);
return "redirect:searchService"; // 重定向到服务列表页面
}
/**
* 改变服务状态
* URL示例: /service/changeStatus?serviceId=1&status=0
*/
@RequestMapping("changeStatus")
public String changeStatus(
@RequestParam("serviceId") Integer serviceId,
@RequestParam("status") String status,
Model model) {
boolean success = serviceService.changeStatus(serviceId, status);
if (success) {
return "redirect:/service/searchService?operation=changeStatus&result=success";
} else {
return "redirect:/service/searchService?operation=changeStatus&result=error";
}
}
/**
* 显示服务详细信息页面
* URL示例: /service/detail?serviceId=1
*/
@RequestMapping("detail")
public ModelAndView serviceDetail(@RequestParam("serviceId") Integer serviceId, ModelAndView mav) {
Service service = serviceService.findByServiceId(serviceId);
if (service == null) {
mav.setViewName("error");
mav.addObject("message", "未找到对应的服务。");
return mav;
}
mav.setViewName("service/service_detail");
mav.addObject("service", service);
return mav;
}
}



















![[Linux] 进程创建、退出和等待](https://i-blog.csdnimg.cn/direct/87f11c4ab92b46ee81f35acff372329e.png)














