1.OA协同办公平台一

项目整合 专栏收录该内容
3 篇文章 0 订阅

OA协同办公系统开发

1. 背景

随着现在知识经济时代步伐的到来,我们的社会正在不断的在进步,而且这一个进步的步伐也正在不断的加速之中,这时候组织就非常迫切的需要一个能够实现内外资源。同时还可以进行整合的一个非常高效的办公信息系统,这样才可以提升他们的管理水平。这就是OA办公系统的背景。

OA办公系统他可以把组织管理之中的那些管理活动以及业务活动还有活动产生的信息在个人,组织以及部门之间进行一个非常及时并且非常高效,同时还能够进行有序控制以及全程共享的这么一个处理以及沟通的平台。这就是OA 办公系统的一个作用。

而且在一起组织的信息化的建设之中很多时候都会特别的重视人物财等等的这些有形方面的资产的管理,但是却大大的忽视了对于知识资产的管理,这时候就需要一个能够借助知识管理工具,对组织内外的知识可以非常有效可行的获取以及应用,沉淀,学习,共享还有创新,这样才可以提高元的素质以及他们的执行力和技能技术,这也是OA办公系统产生的一个社会背景

2. 技术

  1. 主体架构: Spring+springMVC+Mybatis(处理业务技术)
  2. Maven:完成jar文件的管理
  3. Redis: 缓存(把我们经常使用的数据放入redis)减轻db压力(商城项目)
  4. Echars: 图表工具,数据统计
  5. Ueditor: 富文本编辑器、图文混排 、论坛
  6. 阿里巴巴的druid数据源: 稳定 高效 世界上最好的数据源技术
  7. 页面主体:bootstarp.js(vue.js)
  8. Quartz: 定时任务,消息的定时发送
  9. JavaMail: 发送邮件
  10. Ztree插件:树插件
  11. POI:解析Excel

3. 表创建

/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.28 : Database - crmpro
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`crmpro` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `crmpro`;

/*Table structure for table `analysis` */

DROP TABLE IF EXISTS `analysis`;

CREATE TABLE `analysis` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `proname` varchar(64) DEFAULT NULL,
  `title` varchar(64) DEFAULT NULL,
  `simpledis` varchar(320) DEFAULT NULL,
  `detaileddis` varchar(320) DEFAULT NULL,
  `addtime` date DEFAULT NULL,
  `updatetime` date DEFAULT NULL,
  `remark` varchar(320) DEFAULT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `analysis_ibfk_1` FOREIGN KEY (`id`) REFERENCES `project` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `analysis` */

insert  into `analysis`(`id`,`proname`,`title`,`simpledis`,`detaileddis`,`addtime`,`updatetime`,`remark`) values (1,NULL,'联通收费系统需求','协同办公,可以提高工作效率。','可以进行无纸化办公。。。。',NULL,NULL,'目前还在需求确认阶段,详细内容参考需求文档'),(2,NULL,'ERP需求分析','ERP想法包含具体功能:考勤 日常管理  流程审批','考勤:和打卡机连接实时数据同步',NULL,NULL,'需要跟进,完善需求');

/*Table structure for table `archives` */

DROP TABLE IF EXISTS `archives`;

CREATE TABLE `archives` (
  `dnum` varchar(64) NOT NULL,
  `landline` varchar(32) DEFAULT NULL COMMENT '固话',
  `school` varchar(32) DEFAULT NULL COMMENT '毕业院校',
  `zhuanye` varchar(32) DEFAULT NULL COMMENT '专业',
  `sosperson` varchar(32) DEFAULT NULL COMMENT '紧急联系人',
  `biyedate` date DEFAULT NULL COMMENT '毕业时间',
  `zzmm` varchar(32) DEFAULT NULL COMMENT '政治面貌',
  `minzu` varchar(32) DEFAULT NULL COMMENT '民族',
  `xueli` varchar(32) DEFAULT NULL COMMENT '学历',
  `email` varchar(32) DEFAULT NULL COMMENT '邮箱',
  `emp_fk` int(11) DEFAULT NULL COMMENT '员工外键',
  `remark` varchar(256) DEFAULT NULL COMMENT '备注',
  `hirdate` date DEFAULT NULL COMMENT '入职日期',
  PRIMARY KEY (`dnum`),
  KEY `emp_fk` (`emp_fk`),
  CONSTRAINT `archives_ibfk_1` FOREIGN KEY (`emp_fk`) REFERENCES `employee` (`eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `archives` */

insert  into `archives`(`dnum`,`landline`,`school`,`zhuanye`,`sosperson`,`biyedate`,`zzmm`,`minzu`,`xueli`,`email`,`emp_fk`,`remark`,`hirdate`) values ('123-abc','010-110','联合大学','生物科学','仲琪','2018-05-15','群众','汉族','大专','12455@123.com',2,'比较年轻不沉稳需要历练','2019-01-01'),('190-www','0531-120','北京大学','电子工程','李程','2018-09-11','党员','回族','本科','567@165.com',5,'学习能力强,重点培养','2019-01-03'),('456-def','0531-110','北京大学','软件工程','张三','2018-09-09','群众','维吾尔族','本科','123@163.com',1,'学习能力强,重点培养','2019-01-01'),('789-jjj','0531-110','北京大学','软件工程','张三','2018-09-09','群众','维吾尔族','本科','123@163.com',3,'学习能力强,重点培养','2019-01-01'),('900-kkk','0531-119','北京大学','航天技术','马亮','2018-09-10','团员','满族','本科','345@164.com',4,'啥也不会,找个机会开走','2019-01-02');

/*Table structure for table `attachment` */

DROP TABLE IF EXISTS `attachment`;

CREATE TABLE `attachment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pro_fk` int(11) DEFAULT NULL,
  `attname` varchar(32) DEFAULT NULL,
  `attdis` varchar(128) DEFAULT NULL,
  `remark` varchar(256) DEFAULT NULL,
  `path` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKhdq50yhhjhdiyfm03xjohqlki` (`pro_fk`),
  CONSTRAINT `attachment_ibfk_1` FOREIGN KEY (`pro_fk`) REFERENCES `project` (`pid`),
  CONSTRAINT `FKhdq50yhhjhdiyfm03xjohqlki` FOREIGN KEY (`pro_fk`) REFERENCES `project` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `attachment` */

insert  into `attachment`(`id`,`pro_fk`,`attname`,`attdis`,`remark`,`path`) values (2,1,'图片','美女图片','好好看,好好学习。','535f9775-3f99-439a-87f7-eade5d250209_2.经营为什么需要哲学(二)-2010年6月北京.docx'),(3,1,'表笑','表笑的报销','反反复复付付','f8f1ca54-c05d-4615-b3e2-bfbfd20252ea_附件1  个税专项附加扣除信息表-模板.xlsx'),(4,2,'一样一样','以以','uuuuu','bd830b44-fe41-40a4-983e-ca682e1d9395_新建文本文档.txt'),(5,2,'流程图','通天塔','柔柔弱弱若若若','e793907a-80ae-4469-85c6-61044370f87a_模板.doc'),(6,1,'兔兔','大白兔','发发发发发发付','cc2637ad-8129-493f-9167-1270bbe784a4_903Java座位图.xlsx');

/*Table structure for table `baoxiao` */

DROP TABLE IF EXISTS `baoxiao`;

CREATE TABLE `baoxiao` (
  `bxid` varchar(64) NOT NULL,
  `paymode` varchar(32) DEFAULT NULL COMMENT '类型',
  `totalmoney` double DEFAULT NULL COMMENT '总金额',
  `bxtime` date DEFAULT NULL COMMENT '报销时间',
  `bxremark` varchar(100) DEFAULT NULL COMMENT '报销备注',
  `bxstatus` int(11) DEFAULT '0' COMMENT '报销状态',
  `emp_fk` int(11) DEFAULT NULL COMMENT '发起报销人',
  `result` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`bxid`),
  KEY `emp_fk` (`emp_fk`),
  CONSTRAINT `baoxiao_ibfk_1` FOREIGN KEY (`emp_fk`) REFERENCES `employee` (`eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `baoxiao` */

insert  into `baoxiao`(`bxid`,`paymode`,`totalmoney`,`bxtime`,`bxremark`,`bxstatus`,`emp_fk`,`result`) values ('5fa64b67-0864-4a45-b3bf-ca617300dd13','办公采购',456634,'2019-08-08','呃呃呃呃呃反反复复',1,2,'44444'),('c13e844c-3a13-480e-b8e9-9839c08d695a','办公采购',3455,'2019-09-10','出差去岘港吃饭喝酒',2,2,'反反复复'),('e71a0c55-044f-4d56-855f-bd931fd43a36','办公采购',123,'2019-01-01','发发发发发发付付深V许昌县后天发货',2,2,'555555');

/*Table structure for table `customer` */

DROP TABLE IF EXISTS `customer`;

CREATE TABLE `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `comname` varchar(128) DEFAULT NULL,
  `companyperson` varchar(32) DEFAULT NULL,
  `comaddress` varchar(128) DEFAULT NULL,
  `comphone` varchar(32) DEFAULT NULL,
  `camera` varchar(128) DEFAULT NULL,
  `present` varchar(128) DEFAULT NULL,
  `remark` varchar(128) DEFAULT NULL,
  `addtime` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

/*Data for the table `customer` */

insert  into `customer`(`id`,`comname`,`companyperson`,`comaddress`,`comphone`,`camera`,`present`,`remark`,`addtime`) values (4,'用友软件','刘老师','北京市','1111111','010-11','物联网企业','最早的办公软件公司','2018-12-26'),(5,'浪潮软件','孙老师','济南市','3333333','010-22','服务器企业','比较成熟的服务器技术和软件开发技术','2018-12-26'),(6,'中科软','王老师','上海市','5555555','010-33','外包公司','没有自主研发,主要是外包','2018-12-26'),(7,'宜通世纪','候老师','北京市','6666666','010-44','软件公司','各种软件的研发和生产','2018-12-26'),(8,'腾讯','马老师','深圳市','7777777','010-55','游戏公司','占据游戏市场的份额比较大','2018-12-26'),(9,'小米','雷军','中关村软件园23号楼','19999999','010-9999','最大的手机组装工场','香港刚刚上市,有钱尽量套取。','2018-12-26');

/*Table structure for table `datacollect` */

DROP TABLE IF EXISTS `datacollect`;

CREATE TABLE `datacollect` (
  `daid` int(11) NOT NULL AUTO_INCREMENT,
  `dacname` varchar(32) DEFAULT NULL COMMENT '目标公司名称',
  `daturnover` double DEFAULT NULL COMMENT '营业额',
  `datime` date DEFAULT NULL COMMENT '年度',
  `dabusiness` varchar(128) DEFAULT NULL COMMENT '主要业务',
  `dasuperiority` varchar(128) DEFAULT NULL COMMENT '优势',
  `dainforiority` varchar(128) DEFAULT NULL COMMENT '劣势',
  `dasort` int(11) DEFAULT NULL COMMENT '行业排名',
  `empcount` int(11) DEFAULT NULL COMMENT '员工数量',
  `buildtime` date DEFAULT NULL COMMENT '企业创建时间',
  `remark` varchar(256) DEFAULT NULL COMMENT '简单描述',
  `daother` varchar(128) DEFAULT NULL COMMENT '其他',
  PRIMARY KEY (`daid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `datacollect` */

insert  into `datacollect`(`daid`,`dacname`,`daturnover`,`datime`,`dabusiness`,`dasuperiority`,`dainforiority`,`dasort`,`empcount`,`buildtime`,`remark`,`daother`) values (1,'浪潮集团',10,'2015-01-01','软件研发','国家扶持','自主能力较差',1,3000,'1980-09-09','创建时间较长,市场比较稳定','2015年-浪潮集团详细调研说明书.doc'),(2,'浪潮集团',20,'2016-01-01','软件研发,服务器研发','国家扶持','自主能力较差',1,3001,'1980-09-10','创建时间较长,市场比较稳定','2016年-浪潮集团详细调研说明书.doc'),(3,'浪潮集团',50,'2017-01-01','软件研发,软件销售','国家扶持','自主能力较差',1,3002,'1980-09-11','创建时间较长,市场比较稳定','2017年-浪潮集团详细调研说明书.doc'),(4,'浪潮集团',70,'2018-01-01','软件研发','国家扶持','自主能力较差',1,3003,'1980-09-12','创建时间较长,市场比较稳定','2018年-浪潮集团详细调研说明书.doc'),(5,'浪潮集团',8,'2014-01-01','软件研发','国家扶持','自主能力较差',1,3004,'1980-09-13','创建时间较长,市场比较稳定','2014年-浪潮集团详细调研说明书.doc'),(6,'中科软',30,'1018-01-01','软件外包服务','技术人员充沛',NULL,NULL,NULL,NULL,NULL,NULL);

/*Table structure for table `dept` */

DROP TABLE IF EXISTS `dept`;

CREATE TABLE `dept` (
  `deptno` int(11) NOT NULL,
  `dname` varchar(32) DEFAULT NULL,
  `dlocation` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`deptno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `dept` */

insert  into `dept`(`deptno`,`dname`,`dlocation`) values (10,'开发部','北京'),(20,'市场部','广州'),(30,'总裁办','上海');

/*Table structure for table `email` */

DROP TABLE IF EXISTS `email`;

CREATE TABLE `email` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(32) DEFAULT NULL,
  `ename` varchar(32) DEFAULT NULL,
  `sendtime` date DEFAULT NULL,
  `content` varchar(128) DEFAULT NULL,
  `emp_fk` int(11) DEFAULT NULL,
  `path` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKbwdib3s3ugq70b5h2ocn0rfvb` (`emp_fk`),
  CONSTRAINT `email_ibfk_1` FOREIGN KEY (`emp_fk`) REFERENCES `employee` (`eid`),
  CONSTRAINT `FKbwdib3s3ugq70b5h2ocn0rfvb` FOREIGN KEY (`emp_fk`) REFERENCES `employee` (`eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `email` */

/*Table structure for table `emp_role` */

DROP TABLE IF EXISTS `emp_role`;

CREATE TABLE `emp_role` (
  `erid` int(11) NOT NULL AUTO_INCREMENT,
  `role_fk` int(11) DEFAULT NULL,
  `emp_fk` int(11) DEFAULT NULL,
  `erdis` varchar(32) DEFAULT NULL COMMENT '员工和角色的描述',
  PRIMARY KEY (`erid`),
  KEY `emp_fk` (`emp_fk`),
  KEY `role_fk` (`role_fk`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `emp_role` */

insert  into `emp_role`(`erid`,`role_fk`,`emp_fk`,`erdis`) values (1,6,6,'小孙子的角色'),(2,5,7,'444的角色'),(3,5,8,'55的角色');

/*Table structure for table `employee` */

DROP TABLE IF EXISTS `employee`;

CREATE TABLE `employee` (
  `eid` int(11) NOT NULL AUTO_INCREMENT,
  `ename` varchar(32) DEFAULT NULL,
  `esex` varchar(32) DEFAULT NULL,
  `eage` int(11) DEFAULT NULL,
  `telephone` varchar(32) DEFAULT NULL,
  `hiredate` date DEFAULT NULL,
  `pnum` varchar(32) DEFAULT NULL,
  `username` varchar(32) DEFAULT NULL,
  `password` varchar(32) DEFAULT NULL,
  `remark` varchar(256) DEFAULT NULL,
  `p_fk` int(11) DEFAULT NULL,
  `d_fk` int(11) DEFAULT NULL,
  `l_fk` int(11) DEFAULT NULL,
  PRIMARY KEY (`eid`),
  KEY `FKt4aodqf7acjpmo7iejdmg3k78` (`p_fk`),
  KEY `d_fk` (`d_fk`),
  KEY `l_fk` (`l_fk`),
  CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`p_fk`) REFERENCES `position` (`id`),
  CONSTRAINT `employee_ibfk_2` FOREIGN KEY (`d_fk`) REFERENCES `dept` (`deptno`),
  CONSTRAINT `employee_ibfk_3` FOREIGN KEY (`l_fk`) REFERENCES `level` (`jid`),
  CONSTRAINT `FKt4aodqf7acjpmo7iejdmg3k78` FOREIGN KEY (`p_fk`) REFERENCES `position` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

/*Data for the table `employee` */

insert  into `employee`(`eid`,`ename`,`esex`,`eage`,`telephone`,`hiredate`,`pnum`,`username`,`password`,`remark`,`p_fk`,`d_fk`,`l_fk`) values (1,'李四','0',45,'2344','2018-12-03','5767','433','433','234324',4,10,4),(2,'张三','1',45,'45','2018-12-25','45','45','45','45645',1,10,1),(3,'赵四','0',34,'123','2019-01-07','98','12','34','werewolf',5,20,2),(4,'刘恩能够','0',45,'345','2019-01-16','89','12','56','werewolf',2,30,3),(5,'王五','1',56,'456',NULL,'909','12','78','温热无若',3,10,4),(6,'小孙子','1',23,'123213',NULL,'123213','zsf123','000000','这个人老牛逼了会做算法题',5,10,4),(7,'444','1',44,'44',NULL,'44','44','44','444444',2,20,2),(8,'55','1',55,'55','2019-01-08','55','55','55','5555555',1,10,1);

/*Table structure for table `evaluate` */

DROP TABLE IF EXISTS `evaluate`;

CREATE TABLE `evaluate` (
  `evaid` int(11) NOT NULL AUTO_INCREMENT COMMENT '评价id',
  `forum_fk` int(11) DEFAULT NULL COMMENT '帖子外键',
  `emp_fk4` int(11) DEFAULT NULL COMMENT '评价人外键',
  `evaid_fk` int(11) DEFAULT NULL COMMENT '回复外键',
  `evacontent` varchar(256) DEFAULT NULL COMMENT '评价内容',
  `updatetime` datetime DEFAULT NULL COMMENT '更新时间',
  `evatime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  `evastatus` int(11) DEFAULT '0' COMMENT '评价状态',
  PRIMARY KEY (`evaid`),
  KEY `emp_fk4` (`emp_fk4`),
  KEY `forum_fk` (`forum_fk`),
  KEY `evaid_fk` (`evaid_fk`),
  CONSTRAINT `evaluate_ibfk_1` FOREIGN KEY (`emp_fk4`) REFERENCES `employee` (`eid`),
  CONSTRAINT `evaluate_ibfk_2` FOREIGN KEY (`forum_fk`) REFERENCES `forumpost` (`forumid`),
  CONSTRAINT `evaluate_ibfk_3` FOREIGN KEY (`evaid_fk`) REFERENCES `evaluate` (`evaid`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

/*Data for the table `evaluate` */

insert  into `evaluate`(`evaid`,`forum_fk`,`emp_fk4`,`evaid_fk`,`evacontent`,`updatetime`,`evatime`,`evastatus`) values (1,2,5,NULL,'<p>发发发发发发付</p>',NULL,'2019-01-07 11:08:33',NULL),(2,2,2,1,'<p>发发发发发发付</p>',NULL,'2019-01-07 11:08:27',NULL),(3,2,3,1,'<p>发发发发发发付</p>',NULL,'2019-01-07 11:08:25',NULL),(6,2,4,NULL,'<p>发发发发发发付</p>',NULL,'2019-01-07 11:08:24',0),(7,2,1,6,'<p>发发发发发发付</p>',NULL,'2019-01-07 11:08:23',0),(8,2,2,NULL,'<p>发发发发发发付</p>',NULL,'2019-01-07 11:05:34',0),(9,2,2,NULL,'<p>反反复复</p><p>反反复复</p>',NULL,'2019-01-07 11:10:07',0),(10,3,2,NULL,'<p>反反复复付付</p>',NULL,'2019-01-07 11:14:50',0);

/*Table structure for table `forumpost` */

DROP TABLE IF EXISTS `forumpost`;

CREATE TABLE `forumpost` (
  `forumid` int(11) NOT NULL AUTO_INCREMENT COMMENT '帖子id',
  `forumtitle` varchar(32) NOT NULL COMMENT '帖子的标题',
  `forumcontent` varchar(256) NOT NULL COMMENT '帖子的内容',
  `emp_fk3` int(11) NOT NULL COMMENT '发帖人',
  `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  `status` int(11) DEFAULT '0' COMMENT '帖子状态',
  PRIMARY KEY (`forumid`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

/*Data for the table `forumpost` */

insert  into `forumpost`(`forumid`,`forumtitle`,`forumcontent`,`emp_fk3`,`createtime`,`status`) values (2,'投入让人','<p>发发发发发发付多岁的爽肤水</p>',2,'2019-01-04 15:54:23',0),(3,'反反复复','<p>反反复复</p>',2,'2019-01-04 16:01:28',0),(4,'附近反复讲','<p>发的顺丰科技的史莱克</p><p>第三方就离开的说法</p><p>是的房间里看电视</p>',2,'2019-01-04 16:16:18',0),(6,'333333','<p>333333333<br/></p>',2,'2019-01-04 16:50:10',0),(7,'444','<p>4444</p>',2,'2019-01-04 17:48:12',0),(8,'444','<p>44444</p>',2,'2019-01-04 17:48:18',0),(9,'444','<p>5555</p>',2,'2019-01-04 17:50:03',0),(10,'666','<p>666666</p>',2,'2019-01-04 17:53:49',0),(11,'555','<p>55555</p>',2,'2019-01-04 18:22:04',0),(12,'333333','<p>ttttttttttt</p>',2,'2019-01-04 18:32:31',0),(13,'杯子出售','<p>杯子在呢么名史莱克的减肥的流口水</p>',2,'2019-01-07 09:01:37',0);

/*Table structure for table `function` */

DROP TABLE IF EXISTS `function`;

CREATE TABLE `function` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `proname` varchar(32) DEFAULT NULL,
  `analysisname` varchar(32) DEFAULT NULL,
  `modele_fk` int(11) DEFAULT NULL,
  `functionname` varchar(32) DEFAULT NULL,
  `level` varchar(32) DEFAULT NULL,
  `simpledis` varchar(256) DEFAULT NULL,
  `detaileddis` varchar(256) DEFAULT NULL,
  `remark` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKjonpxsiii6o3xv16nttvg500w` (`modele_fk`),
  CONSTRAINT `FKjonpxsiii6o3xv16nttvg500w` FOREIGN KEY (`modele_fk`) REFERENCES `module` (`id`),
  CONSTRAINT `function_ibfk_1` FOREIGN KEY (`modele_fk`) REFERENCES `module` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `function` */

insert  into `function`(`id`,`proname`,`analysisname`,`modele_fk`,`functionname`,`level`,`simpledis`,`detaileddis`,`remark`) values (1,'1','1',2,'收费标准制定','高','3333','333','33333'),(2,'2','2',4,'删除员工信息','高','反反复复','凤飞飞','反反复复'),(3,'2','2',5,'权限添加','高','啊啊啊啊','反反复复','灌灌灌灌');

/*Table structure for table `indexvalue` */

DROP TABLE IF EXISTS `indexvalue`;

CREATE TABLE `indexvalue` (
  `in_id` int(11) NOT NULL AUTO_INCREMENT,
  `in_turnover` double DEFAULT NULL COMMENT '目标营业额',
  `in_business` varchar(128) DEFAULT NULL COMMENT '主要业务方向',
  `comname_fk` int(11) DEFAULT NULL COMMENT '对比企业名称',
  `in_remark` varchar(256) DEFAULT NULL COMMENT '简单说明',
  `in_file` varchar(128) DEFAULT NULL COMMENT '附件',
  `emp_fk5` int(11) DEFAULT NULL COMMENT '指标制定人',
  `in_starttime` date DEFAULT NULL COMMENT '开始时间',
  `in_endtime` date DEFAULT NULL COMMENT '截止时间',
  `in_updatetime` date DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`in_id`),
  KEY `comname_fk` (`comname_fk`),
  KEY `emp_fk5` (`emp_fk5`),
  CONSTRAINT `indexvalue_ibfk_1` FOREIGN KEY (`comname_fk`) REFERENCES `datacollect` (`daid`),
  CONSTRAINT `indexvalue_ibfk_2` FOREIGN KEY (`emp_fk5`) REFERENCES `employee` (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `indexvalue` */

insert  into `indexvalue`(`in_id`,`in_turnover`,`in_business`,`comname_fk`,`in_remark`,`in_file`,`emp_fk5`,`in_starttime`,`in_endtime`,`in_updatetime`) values (4,75,'软件开发服务器销售',4,'扩展业务为服务器销售','a1e97cf3-ded9-4f53-860f-5e95b4fafa00_abc.xls',2,'2019-01-01','2019-06-30',NULL);

/*Table structure for table `level` */

DROP TABLE IF EXISTS `level`;

CREATE TABLE `level` (
  `jid` int(11) NOT NULL AUTO_INCREMENT,
  `jname` varchar(32) DEFAULT NULL,
  `jdis` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`jid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `level` */

insert  into `level`(`jid`,`jname`,`jdis`) values (1,'p1','实习生'),(2,'p2','初级程序员'),(3,'m1','项目组长'),(4,'m2','项目负责人');

/*Table structure for table `module` */

DROP TABLE IF EXISTS `module`;

CREATE TABLE `module` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `proname` varchar(32) DEFAULT NULL,
  `analysis_fk` int(11) DEFAULT NULL,
  `modname` varchar(32) DEFAULT NULL,
  `level` varchar(32) DEFAULT NULL,
  `simpledis` varchar(256) DEFAULT NULL,
  `detaileddis` varchar(256) DEFAULT NULL,
  `remark` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK986a0ufpo55087x7uc0ous7nb` (`analysis_fk`),
  CONSTRAINT `FK986a0ufpo55087x7uc0ous7nb` FOREIGN KEY (`analysis_fk`) REFERENCES `analysis` (`id`),
  CONSTRAINT `module_ibfk_1` FOREIGN KEY (`analysis_fk`) REFERENCES `analysis` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

/*Data for the table `module` */

insert  into `module`(`id`,`proname`,`analysis_fk`,`modname`,`level`,`simpledis`,`detaileddis`,`remark`) values (2,'1',1,'系统管理','低','权限分配,资源创建,','怎么分配权限,怎么创建资源的详细描述','当前模块是我们项目中最后模块,不着急'),(3,'1',1,'收费管理','中','通讯计费标准制定,实施,','通讯计费标准制定,实施,','通讯计费标准制定,实施,'),(4,'2',2,'员工管理','高','员工的考勤管理,工资管理,日常办公管理','员工的考勤管理,工资管理,日常办公管理','员工的考勤管理,工资管理,日常办公管理'),(5,'2',2,'权限管理','高','吾问无为谓','反反复复付','反反复复付');

/*Table structure for table `msg` */

DROP TABLE IF EXISTS `msg`;

CREATE TABLE `msg` (
  `msgid` int(11) NOT NULL AUTO_INCREMENT,
  `sendp` int(32) DEFAULT NULL,
  `recvp` int(32) DEFAULT NULL,
  `mark` int(11) DEFAULT '0',
  `msgcontent` varchar(32) DEFAULT NULL,
  `msgtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`msgid`),
  KEY `sendp` (`sendp`),
  KEY `recvp` (`recvp`),
  CONSTRAINT `msg_ibfk_1` FOREIGN KEY (`sendp`) REFERENCES `employee` (`eid`),
  CONSTRAINT `msg_ibfk_2` FOREIGN KEY (`recvp`) REFERENCES `employee` (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

/*Data for the table `msg` */

insert  into `msg`(`msgid`,`sendp`,`recvp`,`mark`,`msgcontent`,`msgtime`) values (1,2,1,0,'反反复复','2019-01-04 00:00:00');

/*Table structure for table `notice` */

DROP TABLE IF EXISTS `notice`;

CREATE TABLE `notice` (
  `nid` int(11) NOT NULL AUTO_INCREMENT,
  `ntitle` varchar(32) DEFAULT NULL,
  `remark` varchar(320) DEFAULT NULL,
  `ndate` date DEFAULT NULL,
  PRIMARY KEY (`nid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `notice` */

insert  into `notice`(`nid`,`ntitle`,`remark`,`ndate`) values (1,'提升张三为副总裁','张三的接口丽枫酒店\r\n的实例会计法独立思考\r\n的借款方\r\n冻死了空间发的是\r\n独立思考解放东路开始','2019-01-03'),(2,'降薪公告','关于集团为了缩减开始,特发出降薪通告\r\n1:10年员工降薪30%\r\n2:新员工降薪45%','2019-01-01'),(3,'税务改革','2019-01-01 新的纳税制度\r\n大家及时申报免税的信息','2019-01-01'),(4,'年终考核','总结大家一年中工作内容,成绩。突出贡献','2018-12-31'),(5,'集团考勤通告','张三今天迟到了5分钟,本次事故纳入年终考核,罚款500元','2019-01-03'),(6,'节约使用办公用品倡议','为了迎接互联网寒冬,我们要扎进裤腰带,共同度过','2019-01-03');

/*Table structure for table `position` */

DROP TABLE IF EXISTS `position`;

CREATE TABLE `position` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `position` */

insert  into `position`(`id`,`name`) values (1,'初级开发工程师'),(2,'中级开发工程师'),(3,'高级开发工程师'),(4,'项目经理'),(5,'项目总监'),(6,' 其他');

/*Table structure for table `project` */

DROP TABLE IF EXISTS `project`;

CREATE TABLE `project` (
  `pid` int(11) NOT NULL AUTO_INCREMENT,
  `pname` varchar(128) DEFAULT NULL,
  `comname` int(11) DEFAULT NULL,
  `comper` varchar(64) DEFAULT NULL,
  `emp_fk1` int(11) DEFAULT NULL,
  `empcount` int(11) DEFAULT NULL,
  `starttime` date DEFAULT NULL,
  `buildtime` date DEFAULT NULL,
  `cost` int(11) DEFAULT NULL,
  `level` varchar(32) DEFAULT NULL,
  `endtime` date DEFAULT NULL,
  `remark` varchar(256) DEFAULT NULL,
  `emp_fk` int(11) NOT NULL,
  PRIMARY KEY (`pid`),
  KEY `emp_fk1` (`emp_fk1`),
  KEY `FKtirudsu3khj865hrqeamn153y` (`comname`),
  KEY `FKj4vtyyp6ew24vggobfcmav1be` (`emp_fk`),
  CONSTRAINT `FKj4vtyyp6ew24vggobfcmav1be` FOREIGN KEY (`emp_fk`) REFERENCES `employee` (`eid`),
  CONSTRAINT `FKtirudsu3khj865hrqeamn153y` FOREIGN KEY (`comname`) REFERENCES `customer` (`id`),
  CONSTRAINT `project_ibfk_2` FOREIGN KEY (`comname`) REFERENCES `customer` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `project` */

insert  into `project`(`pid`,`pname`,`comname`,`comper`,`emp_fk1`,`empcount`,`starttime`,`buildtime`,`cost`,`level`,`endtime`,`remark`,`emp_fk`) values (1,'联通收费系统',5,'孙老师',NULL,4,'2019-09-09','2018-09-09',444,'1','2222-09-09','333333333',1),(2,'ERP',4,'刘老师',NULL,5,'2018-09-09','2018-10-10',34,'2','2020-09-09','进行中',1),(3,'商城',6,'王老师',NULL,5,'1998-09-09','1998-09-09',3456,'3','2022-09-09','不着急',1);

/*Table structure for table `role` */

DROP TABLE IF EXISTS `role`;

CREATE TABLE `role` (
  `roleid` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色id',
  `rolename` varchar(32) DEFAULT NULL COMMENT '角色名称',
  `roledis` varchar(32) DEFAULT NULL COMMENT '角色描述',
  `status` int(11) DEFAULT '0' COMMENT '是否启用',
  PRIMARY KEY (`roleid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `role` */

insert  into `role`(`roleid`,`rolename`,`roledis`,`status`) values (5,'5555','反反复复付付',1),(6,'vip会员','vip权限普通用户多一些',1);

/*Table structure for table `role_sources` */

DROP TABLE IF EXISTS `role_sources`;

CREATE TABLE `role_sources` (
  `rsid` int(11) NOT NULL AUTO_INCREMENT,
  `rsdis` varchar(32) DEFAULT NULL COMMENT '角色和资源的描述',
  `sid` int(11) DEFAULT NULL,
  `roleid` int(11) DEFAULT NULL,
  PRIMARY KEY (`rsid`),
  KEY `roleid` (`roleid`),
  KEY `sid` (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8;

/*Data for the table `role_sources` */

insert  into `role_sources`(`rsid`,`rsdis`,`sid`,`roleid`) values (17,'资源和我们的角色描述',1,5),(18,'资源和我们的角色描述',2,5),(19,'资源和我们的角色描述',9,5),(20,'资源和我们的角色描述',10,5),(21,'资源和我们的角色描述',11,5),(22,'资源和我们的角色描述',12,5),(23,'资源和我们的角色描述',13,5),(24,'资源和我们的角色描述',3,5),(25,'资源和我们的角色描述',14,5),(26,'资源和我们的角色描述',15,5),(27,'资源和我们的角色描述',16,5),(28,'资源和我们的角色描述',17,5),(29,'资源和我们的角色描述',18,5),(30,'资源和我们的角色描述',19,5),(31,'资源和我们的角色描述',20,5),(32,'资源和我们的角色描述',21,5),(33,'资源和我们的角色描述',1,6),(34,'资源和我们的角色描述',2,6),(35,'资源和我们的角色描述',9,6),(36,'资源和我们的角色描述',10,6),(37,'资源和我们的角色描述',11,6),(38,'资源和我们的角色描述',12,6),(39,'资源和我们的角色描述',13,6),(40,'资源和我们的角色描述',3,6),(41,'资源和我们的角色描述',14,6),(42,'资源和我们的角色描述',15,6),(43,'资源和我们的角色描述',16,6),(44,'资源和我们的角色描述',17,6),(45,'资源和我们的角色描述',18,6),(46,'资源和我们的角色描述',19,6),(47,'资源和我们的角色描述',20,6),(48,'资源和我们的角色描述',21,6),(49,'资源和我们的角色描述',4,6),(50,'资源和我们的角色描述',27,6);

/*Table structure for table `sources` */

DROP TABLE IF EXISTS `sources`;

CREATE TABLE `sources` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) DEFAULT NULL COMMENT '菜单名称',
  `url` varchar(128) DEFAULT NULL COMMENT '资源路径',
  `remark` varchar(32) DEFAULT NULL COMMENT '资源备注',
  `pid` int(11) DEFAULT NULL COMMENT '父菜单id',
  `icon` varchar(32) DEFAULT NULL COMMENT '图标',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;

/*Data for the table `sources` */

insert  into `sources`(`id`,`name`,`url`,`remark`,`pid`,`icon`) values (1,'oa办公协同系统',NULL,'系统名称',0,NULL),(2,'项目管理',NULL,'项目管理',1,NULL),(3,'日常办公',NULL,'日常办公',1,NULL),(4,'消息管理',NULL,'信息箱',1,NULL),(5,'客户信息管理',NULL,'客户信息管理',1,NULL),(6,'系统管理',NULL,'系统管理',1,NULL),(7,'对标管理',NULL,'对标管理',1,NULL),(8,'我的信息',NULL,'我的信息',1,NULL),(9,'基本信息管理',NULL,'项目基本信息',2,NULL),(10,'需求信息管理',NULL,'项目需求分析',2,NULL),(11,'模块管理',NULL,'模块管理',2,NULL),(12,'功能管理',NULL,'功能管理',2,NULL),(13,'附件管理',NULL,'附件管理',2,NULL),(14,'创建任务',NULL,'创建任务',3,NULL),(15,'已发布任务',NULL,'已发布任务',3,NULL),(16,'我的任务',NULL,'我的任务',3,NULL),(17,'通知公告',NULL,'通知公告',3,NULL),(18,'档案管理',NULL,'档案管理',3,NULL),(19,'我的档案',NULL,'我的档案',3,NULL),(20,'报销审批',NULL,'报销审批',3,NULL),(21,'我的报销',NULL,'我的报销',3,NULL),(27,'发送邮件','${pageContext.request.contextPath}/email-send.jsp','仅仅使用javamail发送邮件就ok啦',4,NULL);

/*Table structure for table `task` */

DROP TABLE IF EXISTS `task`;

CREATE TABLE `task` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `starttime` date DEFAULT NULL,
  `endtime` date DEFAULT NULL,
  `level` varchar(32) DEFAULT NULL,
  `remark` varchar(256) DEFAULT NULL,
  `fun_fk` int(11) DEFAULT NULL COMMENT '具体的功能外键',
  `emp_fk2` int(11) DEFAULT NULL COMMENT '具体实现功能的人',
  `emp_fk` int(11) NOT NULL COMMENT '分配任务的人',
  `tasktitle` varchar(32) DEFAULT NULL,
  `status` int(11) DEFAULT NULL COMMENT '任务的状态0,1,2',
  PRIMARY KEY (`id`),
  KEY `emp_fk2` (`emp_fk2`),
  KEY `FK8pqhf0pdn5r478vp69g6sip3` (`fun_fk`),
  KEY `FKcpxt4jxiaoqj5nwny5ai74drj` (`emp_fk`),
  CONSTRAINT `FK8pqhf0pdn5r478vp69g6sip3` FOREIGN KEY (`fun_fk`) REFERENCES `function` (`id`),
  CONSTRAINT `FKcpxt4jxiaoqj5nwny5ai74drj` FOREIGN KEY (`emp_fk`) REFERENCES `employee` (`eid`),
  CONSTRAINT `task_ibfk_1` FOREIGN KEY (`fun_fk`) REFERENCES `function` (`id`),
  CONSTRAINT `task_ibfk_3` FOREIGN KEY (`emp_fk2`) REFERENCES `employee` (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `task` */

insert  into `task`(`id`,`starttime`,`endtime`,`level`,`remark`,`fun_fk`,`emp_fk2`,`emp_fk`,`tasktitle`,`status`) values (1,'2019-09-09','2019-10-10','低','慢慢做',1,2,1,'收费标准全部功能',1),(4,'2019-09-10','2019-09-20','中','权限信息中没有使用shiro和ztree,需要使用这些技术完成',3,2,1,'完善人员权限信息',2);

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

1. 表设计分析

Attachment: 附件表(项目中需要文档类型规范:编码规范 注释规范 命名规范。。)

Project: 项目表(公司经营的主体业务)

Customer: 客户表(统计保存客户信息)

Analysis: 需求表(当前的项目的编写过程中需求分析文档)

Module: 模块(项目中的具体模块:人员管理 业务管理 仓储信息)

Function: 功能表(一个模块下有多个功能)

Task: 任务表 (那些功能分配给了具体人)

Notice: 通知公告(任命,会议通知,考勤情况)

Employee: 员工表(员工的基本信息)

Role: 角色表

Emp_role:员工和角色中间表

Role_sources: 角色和资源的中间表

Sources: 资源表(能够去点击那些连接,能够去操作那些功能)

Email: 邮件表(发送邮件 查看发送的邮件)

Comparsion: 对标管理的表(设定明年的目标,对比企业概况)

Dept: 部门表 (it)

Position: 职位表

level 级别表:当前的职位对应的级别

Msg: 消息表(定时发送一些简短消息)

Baoxiao: 员工报销的表格

Dangan: 员工的档案表

4. 工程建立

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.anzhi</groupId>
  <artifactId>project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.0.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.0.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.0.0.RELEASE</version>
    </dependency>
    <!--spring表达式语言-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

    <!--AOP切面编程-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.1.9.RELEASE</version>
      <exclusions>
        <exclusion>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.8.RELEASE</version>
    </dependency>
    <!--springMVC-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.8.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

    <!--Mysql-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.19</version>
    </dependency>
    <!--数据库连接池-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.22</version>
    </dependency>

    <!--测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>

    <!--动态代理-->
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.2.2</version>
    </dependency>

    <!--JDBCTemplate and Transaction-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>

    <!--文件上传下载-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.3</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.0</version>
    </dependency>
    <!--mybatis整合spring的-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.3</version>
    </dependency>

    <!--JSTL-->
    <dependency>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-impl</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-spec</artifactId>
      <version>1.2.5</version>
    </dependency>

    <!--JSON-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.11.2</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.11.2</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.11.2</version>
    </dependency>

    <!--jsp-servlet-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
    </dependency>

    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>

    <!--redis-->
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>2.3.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.1.0</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <path>/</path>
          <port>8080</port>
        </configuration>
      </plugin>
    </plugins>

    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>

</project>

注意:有的包确实无法导入,更改一下版本号,观察是否报错

2. web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--1. 指定spring的配置文件路径和名称-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:beans.xml</param-value>
  </context-param>

  <!--配置post请求乱码的-->
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <!--配置将POST请求转换为PUT或者DELETE请求的过滤器-->
  <!-- 我们常用的请求是post跟get,而REST风格的URL还有put跟delete请求,
  这四种请求对应的是数据库的CURD。put对应Create,post对应Update, get对应Read,delete当然对应delete了。-->
  <filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!--2. 配置Spring的监听器,默认只加载WEB-INF目录下的applicationContext.xml配置文件-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!--配置spring前端控制器-->
  <servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--配置servlet加载顺序,值越小,优先级越高-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

web.xml出现配置了Mapper,但是仍然无法识别,后来将web.xml删除,重新创建,并更换了idea对应的版本**version=“4.0”**后,成功。

问题描述

  1. 导入项目发现web.xml报错,信息为:The content of element type “web-app” must match “(icon?,display-
    name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet-
    mapping*,session-config?,mime-mapping*,welcome-file-list?,error-page*,taglib*,resource-env-
    ref*,resource-ref*,security-constraint*,login-config?,security-role*,env-entry*,ejb-ref*,ejb-local-ref*)”.
  2. 解决方案
    1. 第一种,将上面的注释删掉 “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”
      “http://java.sun.com/dtd/web-app_2_3.dtd” >
      2.严格按照(icon?,display-
      name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet-
      mapping*,session-config?,mime-mapping*,welcome-file-list?,error-page*,taglib*,resource-env-
      ref*,resource-ref*,security-constraint*,login-config?,security-role*,env-entry*,ejb-ref*,ejb-local-ref*)”顺序写web.xml中的标签。

3. springmvc.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
       http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--配置需要扫描的包-->
    <context:component-scan base-package="com.anzhi" use-default-filters="false">
        <!--配置需要扫描的注解Controlle-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        <!--配置全局ControllerAdvice-->
        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>

    <!--配置内部资源视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--处理静态资源的标签-->
    <mvc:annotation-driven/>
    <mvc:default-servlet-handler/>
</beans>

项目开发遇到的错误

在这里插入图片描述

4. beans.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:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--1.配置要扫描的包-->
    <context:component-scan base-package="com.anzhi">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>

    <!--2.Spring整合Mybatis框架-->
    <!--配置连接池-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="url" value="jdbc:mysql://localhost:3306/crmpro?serverTimezone=UTC"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>
    <!--3.配置Spring框架声明式事务管理-->
    <!--配置事务管理器-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"/>
    </bean>
    <!--4.开启基于注解的事物支持-->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>

    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="druidDataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.anzhi.mapper"/>
    </bean>
</beans>

5. 数据库.properties文件配置

jdbc.jdbcUrl=jdbc:mysql://192.168.1.108:3306/crmpro?serverTimezone=UTC
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.userName=root
jdbc.password=root

6. mybatis-config.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>

</configuration>

7. 页面配置

直接使用资料中给的文件

注意:源文件中的WEB-INF,我们已经配置过,可以删除,剩下的问价复制到项目中webapp文件夹下,不要一股脑的直接复制到idea的webapp工程目录下,防止卡死。

1. 记录问题:

在加入前端文件后,发现主页面无法加载部分图片:

在这里插入图片描述

解决:

在这里插入图片描述

然后清理maven工程,重新生成,最后重启tomcat

8. Mybatis逆向生成

  1. 使用mybatis逆向生成与数据库对应的文件

    pom.xml导入依赖包

    <!--mybatis逆向工程-->
    <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.2</version>
        <dependencies>
            <dependency>
                <groupId> mysql</groupId>
                <artifactId> mysql-connector-java</artifactId>
                <version>5.1.37</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <version>1.3.2</version>
            </dependency>
        </dependencies>
        <executions>
            <execution>
                <id>Generate MyBatis Artifacts</id>
                <phase>package</phase>
                <goals>
                    <goal>generate</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <!--允许移动生成的文件 -->
            <verbose>true</verbose>
            <!-- 是否覆盖 -->
            <overwrite>false</overwrite>
            <!-- 自动生成的配置 -->
            <configurationFile>
                src/main/resources/mybatis-generator.xml</configurationFile>
        </configuration>
    </plugin>
    

    3. 创建逆向工程的配置文件

    mybatis-generator.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    <generatorConfiguration>
        <context id="test" targetRuntime="MyBatis3">
    
            <commentGenerator>
                <!-- 是否去除自动生成的注释 true:是 : false:否 -->
                <property name="suppressAllComments" value="true" />
            </commentGenerator>
            <!--数据库链接URL,用户名、密码 -->
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                            connectionURL="jdbc:mysql://192.168.1.108:3306/crmpro"
                            userId="root"
                            password="root">
            </jdbcConnection>
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>
            <!-- 生成模型的包名和位置 -->
            <javaModelGenerator targetPackage="bean" targetProject="target">
                <property name="enableSubPackages" value="true" />
                <property name="trimStrings" value="true" />
            </javaModelGenerator>
            <!-- 生成映射文件的包名和位置 -->
            <sqlMapGenerator targetPackage="mapper"  targetProject="target">
                <property name="enableSubPackages" value="true" />
            </sqlMapGenerator>
            <!-- 生成DAO的包名和位置 -->
            <javaClientGenerator type="XMLMAPPER" targetPackage="mapper" targetProject="target">
                <property name="enableSubPackages" value="true" />
            </javaClientGenerator>
    
    
    
            <!-- 要生成哪些表 -->
            <table tableName="analysis" domainObjectName="Analysis"></table>
            <table tableName="archives" domainObjectName="Archives"></table>
            <table tableName="attachment" domainObjectName="Attachment"></table>
            <table tableName="baoxiao" domainObjectName="BaoXiao"></table>
            <table tableName="customer" domainObjectName="Customer"></table>
            <table tableName="dept" domainObjectName="Dept"></table>
            <table tableName="email" domainObjectName="Email"></table>
            <table tableName="forumpost" domainObjectName="ForumPost"></table>
            <table tableName="function" domainObjectName="Function"></table>
            <table tableName="level" domainObjectName="Level"></table>
            <table tableName="module" domainObjectName="Model"></table>
    
            <table tableName="msg" domainObjectName="Msg"></table>
            <table tableName="notice" domainObjectName="Notice"></table>
            <table tableName="position" domainObjectName="Position"></table>
            <table tableName="role" domainObjectName="Role"></table>
            <table tableName="sources" domainObjectName="Sources"></table>
            <table tableName="task" domainObjectName="Task"></table>
    
        </context>
    </generatorConfiguration>
    

    点击插件mybatis-generator:generate,在target文件夹下可以看到生成对应的文件

    在这里插入图片描述

5. 项目编写:(先看4.客户信息管理)

1. 创建对应的模块

1. 项目管理-》projectmanage;并创建如下四个模块

  1. controller
  2. service
  3. beans
  4. mapper

1. 基本信息管理

1. 添加页面
  1. 需求:在选择公司的时候,将对应的负责人一并显示,项目经理可选

  2. 修改project-base-add.jsp

    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
    	$(function () {
                    $.ajax({
                        type:"GET",
                        url:"${pageContext.request.contextPath}/prj/getLists",
                        success: function (msg) {
                            $(msg).each(function (index,item) {
                        /*
                        $("#comname").append("<option value='"+item.comname+"'>"+item.comname+"</option>")
                        */
                                    // 将遍历到的item值赋值给下拉框选项
                                    var option = "<option value='"+item.id+"'>"+item.comname+"</option>";
                                    $("#comname").append(option);
                              })
                         }
                    });
                    $.ajax({
                        type:"GET",
                        url:"${pageContext.request.contextPath}/prj/mgr",
                        success:function (msg) {
                            $(msg).each(function (index,item) {
                                alert(item.ename);
                                var option = "<option value='"+item.pFk+"'>"+item.ename+"</option>"
                                $("#empFk").append(option);
                            })
                        }
                    });
        });
    	
        //选中下拉框选项,调用该函数,绑定公司的负责人
        function parseLeader(cid) {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/prj/info/"+cid,
                success:function (msg) {
                    $("#companyperson").val(msg.companyperson);
                }
            });
        }
    </script>
    
        <td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
            //parseLeader(this.value) 一定要将select中的值传递,使用this.value,否则无法绑定对应的负责人
            <select id="comname" name="comname" οnchange="parseLeader(this.value)">
                <option>选择公司...</option>  //添加下拉框选项
            </select>
        </td>
    
    
        // 客户负责人绑定不允许修改,设置只读
        <input type="text" id="companyperson" name="principal" readonly/>
    
        <td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
            <select id="empFk" name="empFk" >
                <option>选择项目经理...</option>
            </select>
        </td>
    
    
  3. controller

    package com.anzhi.projectmanage.controller;
    
    import com.anzhi.custormermanage.bean.Customer;
    import com.anzhi.custormermanage.bean.CustomerExample;
    import com.anzhi.projectmanage.service.ProjectService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.List;
    
    @Controller
    @RequestMapping(value = "/prj")
    public class ProjectController {
        @Autowired
        ProjectService projectService;
    
        @RequestMapping(value = "/getLists", method = RequestMethod.GET)
        @ResponseBody
        public List<Customer> getLists(CustomerExample customerExample){
            return projectService.getLists(customerExample);
        }
    
        @RequestMapping(value = "/info/{cid}", method = RequestMethod.GET)
        @ResponseBody
        public Customer customerName(@PathVariable("cid") Integer cid){
            System.out.println(projectService.customerName(cid));
            return projectService.customerName(cid);
        }
        
        @RequestMapping(value = "/mgr", method = RequestMethod.GET)
        @ResponseBody
        public List<Employee> getManagerList(EmployeeExample employeeExample){
            List<Employee> employeeExamples = projectService.getManagerList(employeeExample);
            return employeeExamples;
        }
    }
    
  4. service层

    package com.anzhi.projectmanage.service;
    
    import com.anzhi.custormermanage.bean.Customer;
    import com.anzhi.custormermanage.bean.CustomerExample;
    
    import java.util.List;
    
    public interface ProjectService {
        List<Customer> getLists(CustomerExample customerExample);
    
        Customer customerName(Integer cid);
        
        List<Employee> getManagerList(EmployeeExample employeeExample);
    }
    
    
    package com.anzhi.projectmanage.service.Impl;
    
    import com.anzhi.custormermanage.bean.Customer;
    import com.anzhi.custormermanage.bean.CustomerExample;
    import com.anzhi.custormermanage.mapper.CustomerMapper;
    import com.anzhi.projectmanage.service.ProjectService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class ProjectServiceImpl implements ProjectService {
    
        @Autowired
        CustomerMapper customerMapper;
    
        public List<Customer> getLists(CustomerExample customerExample) {
            return customerMapper.selectByExample(customerExample);
        }
    
        public Customer customerName(Integer cid) {
            return customerMapper.selectByPrimaryKey(cid);
        }
        
            public List<Employee> getManagerList(EmployeeExample employeeExample) {
            EmployeeExample.Criteria criteria = employeeExample.createCriteria();
            //4. 代表项目经理
            criteria.andPFkEqualTo(4);
            List<Employee> managerLists = employeeMapper.selectByExample(employeeExample);
            return managerLists;
        }
    }
    
2. 添加页面实现时间控件
  1. 下载my97datepicker

    链接:http://www.my97.net/demo/index.htm

  2. 修改 project-base.jsp

    //引入包
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/My97DatePicker/WdatePicker.js"></script>
    
    
    <td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
        <input type="text" name="starttime" id="starttime"/>
        <img οnclick="WdatePicker({el:'starttime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
    </td>
    </tr>
    <tr >
        <td align="right" bgcolor="#FAFAF1" height="22">立项时间:</td>
        <td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
            <input type="text" name="buildtime" id="buildtime"/>
            <img οnclick="WdatePicker({el:'buildtime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
        </td>
    
        <td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
            <input type="text" name="endtime" id="endtime"/>
            <img οnclick="WdatePicker({el:'endtime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
        </td>
    
    
    
3. 完成项目添加
  1. 修改project-base-add.jsp

    function commit() {
        $("#forms").submit();
    }
    
    
    <form name="form2" id="forms" action="${pageContext.request.contextPath}/prj/saveMgr" method="POST">
    
    /*属性对应*/
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22" >项目名称:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input type="text" name="pname"/></td>
    	<td align="right" bgcolor="#FAFAF1" height="22">客户公司名称:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<select id="comname" name="comname" onchange="parseLeader(this.value)">
    			<option>选择公司...</option>
    		</select>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">客户方负责人:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input type="text" id="comper" name="comper" readonly/>
    	</td>
    	<td align="right" bgcolor="#FAFAF1" height="22">项目经理:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<select id="empFk" name="empFk" >
    			<option>选择项目经理...</option>
    		</select>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22" >开发人数:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input type="text" name="empcount"/></td>
    	<td align="right" bgcolor="#FAFAF1" height="22">开始时间:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input type="text" name="starttime" id="starttime"/>
    		<img onclick="WdatePicker({el:'starttime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
    		</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">立项时间:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input type="text" name="buildtime" id="buildtime"/>
    		<img onclick="WdatePicker({el:'buildtime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
    	</td>
    	<td align="right" bgcolor="#FAFAF1" height="22">预估成本:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input type="text" name="cost"/></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">级别:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<select  name="level">
    			<option value="紧急">紧急</option>
    			<option value="一般">一般</option>
    			<option value="暂缓">暂缓</option></select>
    	</td>
    	<td align="right" bgcolor="#FAFAF1" height="22">计划完成时间:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input type="text" name="endtime" id="endtime"/>
    		<img onclick="WdatePicker({el:'endtime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
    	</td>
    </tr>
    
    <tr >
    	<td align="right" bgcolor="#FAFAF1" >备注:</td>
    	<td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    		<textarea type="text" rows=15 cols=130 name="remark">
    		</textarea><span id="number">
    	</span>
    	</td>
    </tr>
        
             /*href=”javascript:void(0);”这么做往往是为了保留链接的样式,但不让链接执行实际操作*/
    	<a class="coolbg" href="javascript:void(0)" onclick="commit()">保存</a>
    	<a href="javascript:history.go(-1)" class="coolbg">返回</a>
    
    
  2. controller层

    @RequestMapping(value = "/saveMgr", method = RequestMethod.POST)
    public String saveManager(Project project){
        projectService.saveManager(project);
        //使用重定向,前端跳转访问302
        return "redirect:/prj/prjLists";
    }
    
  3. service层

    @Override
    public Integer saveManager(Project project) {
        return projectMapper.insertSelective(project);
    }
    
4. 项目列表显示
  1. 修改menu.jsp

    <li><a href='${pageContext.request.contextPath}/prj/prjLists' target='main'>基本信息管理</a> </li>
    
  2. 修改project-base.jsp

    /*遍历属性对应*/
    <c:forEach items="${projects}" var="project" varStatus="index">
        <tr align='center' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22" >
            <td><input name="id" type="checkbox" id="id" value="101" name="${project.pid}" class="np"></td>
            <td>${project.pid}</td>
            <td align="left"><a href=''><u>${project.pname}</u></a></td>
            <td>${project.comname}</td>
            <td>${project.comper}</td>
            <td>${project.empFk}</td>
            <td>${project.empcount}</td>
            <td>
                <fmt:formatDate value="${project.starttime}" pattern="yyyy-MM-dd"/>
            </td>
            <td>
                <fmt:formatDate value="${project.buildtime}" pattern="yyyy-MM-dd"/>
            </td>
            <td>
                <fmt:formatDate value="${project.endtime}" pattern="yyyy-MM-dd"/>
            </td>
            <td>${project.level}</td>
            <td><a href="project-base-edit.jsp">编辑</a> | <a href="project-base-look.jsp">查看详情</a></td>
        </tr>
    </c:forEach>
    
问题1:

项目表中存储的是customer表公司列对应的id、employee表中人物的id,需要联表查询返回结果,我只写了直接从project表中查询,并将结果返回给网页,导致网页上公司名称和项目经理的名称是各自的id。(后面进行修改)

/*联表查询,需要在projectMapper.xml配置,实现函数接口*/
SELECT
	ec.*, e.ename
FROM
	(
		SELECT
			p.pid,
			p.pname,
			c.comname,
			p.comper,
			p.starttime,
			p.buildtime,
			p.endtime,
			p.remark,
			p.empcount,
			p.emp_fk AS 'empfk'
		FROM
			project p
		JOIN customer c ON c.id = p.comname
	) ec
JOIN employee e ON ec.empfk = e.eid

解决思路:在ProjectMapper中自定义查询接口,并在ProjectMapper.xml中配置多表查询到的列属性,以及将查询结果返回接口实现类,如图:

将查询到的列对应:

在这里插入图片描述

查询结果映射:

在这里插入图片描述

并在project中添加新的属性,并设置对应的get和set方法。

问题2:

由于表是临时表,在实现search功能的时候,导致公司名称和项目经理显示为空

解决思路:同样定义查询语句,实现接口。

实现编辑,查看详情功能
  1. 由于前一步骤的显示导致这里编辑界面的显示存在同样的问题。
  2. 剩余的编辑查看,反选全选、条件搜索等功能与客户信息管理的类似。
  3. 后面看视频修改mapper配置文件,定制查询语句如下:
<resultMap id="接口名称"   type="映射类">
	<id column=" " property=" "></id>
	<result column=" " property=" "></result>
	<result column=" " property=" "></result>
	<result column=" " property=" "></result>
	……
	<result column="comname " property=" customer.comname"></result>
</resultMap>

/*联表查询,需要在projectMapper.xml配置,实现函数接口*/
SELECT
	ec.*, e.ename
FROM
	(
		SELECT
			p.pid,
			p.pname,
			c.comname,
			p.comper,
			p.starttime,
			p.buildtime,
			p.endtime,
			p.remark,
			p.empcount,
			p.emp_fk AS 'empfk'
		FROM
			project p
		JOIN customer c ON c.id = p.comname
	) ec
JOIN employee e ON ec.empfk = e.eid
where 
	<if test="cid==0">
		ec.pname like concat(concat('%',#{keywork}),'%') or ec.ename like concat(concat('%',#{keywork}),'%')
	</if>
	<if test="cid==1">
		ec.pname like concat(concat('%',#{keywork}),'%') 
        </if>
        <if test="cid==2">
        	ec.ename like concat(concat('%',#{keywork}),'%')
        </if>
	<if test="orderby==1">
		order by buildtime
        </if>
	<if test="orderby==2">
		order by endtime
        </if>        

2. 需求分析管理

1. 添加需求
  1. 需求:analysis表与项目表一对一,需要注意的是,每个项目一旦设计需求后,就不再需要添加需求了,所以项目不应该再出现在项目的选择中。

  2. 修改project-need-add.jsp

    //异步显示未添加需求的项目
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
        $(function () {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/prj/showprj",
                success: function (msg) {
                    $(msg).each(function (index,item) {
                        var option = "<option value='"+item.pid+"'>"+item.pname+"</option>";
                        $("#pronameList").append(option);
                        var proname = item.pname;
                        $("#proname").val(proname);
                    })
                }
            });
        });
    </script>
    
    
    <form id="form2" name="form2">
    <input type="hidden" name="proname" id="proname">
    <table width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
    <tr bgcolor="#E7E7E7">
    	<td height="24" colspan="2" background="skin/images/tbg.gif">&nbsp;添加新需求&nbsp;</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">选择项目:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<select id="pronameList" name="id">
    			<option value=1>选择项目...</option>
    		</select>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">标题:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name="title"/>
    		<input type="text" name="addtime" id="addtime" placeholder="添加日期"/>
    		<img οnclick="WdatePicker({el:'addtime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
    		<input type="text" name="updatetime" id="updatetime" placeholder="更新日期"/>
    		<img οnclick="WdatePicker({el:'updatetime',minDate:'%y-%M-%d'})" src="${pageContext.request.contextPath}/static/js/My97DatePicker/skin/datePicker.gif" width="16" height="22" align="absmiddle">
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">简单描述:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<textarea rows=10 cols=130 name="simpledis"></textarea></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">详细描述:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<textarea rows=15 cols=130 name="detaileddis"></textarea></td>
    </tr>
    
    <tr >
    	<td align="right" bgcolor="#FAFAF1" >备注:</td>
    	<td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    		<textarea rows=10 cols=130 name="remark"></textarea>
    	</td>
    </tr>
    
    
  3. controller层

    @RequestMapping(value = "/showprj", method = RequestMethod.GET)
    @ResponseBody
    public List<Project> showprj(){
        return projectService.showprj();
    }
    
  4. service层

    List<Project> showprj();
    
    
    //mybatis逆向工程生成的查询接口,不能满足我们的需求,需要我们自定义
    @Override
    public List<Project> showprj() {
        return projectMapper.getProjectListNotAnalyse();
    }
    
  5. mapper

    List<Project> getProjectListNotAnalyse();
    
  6. xml

      <select id="selectPrjLists" resultMap="BaseResultMap">
        SELECT
    	ec.*, e.ename
        FROM
            (
                SELECT
                    p.pid,
                    p.pname,
                    c.comname,
                    p.comper,
                    p.starttime,
                    p.buildtime,
                    p.endtime,
                    p.remark,
                    p.empcount,
                    p.emp_fk AS 'empfk'
                FROM
                    project p
                JOIN customer c ON c.id = p.comname
            ) ec
        JOIN employee e ON ec.empfk = e.eid
      </select>
    
2. 剩余页面的功能与前面的实现类似

有一个知识点儿是,前端数据提交表保存还可以这样写

  1. project-need-add.jsp

    <script>
        function commit() {
            $.ajax({
                type:"POST",
                url:"${pageContext.request.contextPath}/analy/saveAna",
                data: $("#form2").serialize(),   //数据序列化,表中的数据要与数据库的映射类的属性相同
                success:function (msg) {
                    if(msg.statusCode == 200){
                        window.location.href="${pageContext.request.contextPath}/analy/showAna";
                        alert(msg.statusCode);
                    }
                },
                error:function () {
                    window.location.href="${pageContext.request.contextPath}/analy/showAna";
                    alert("数据保存失败");
                    alert(msg.message);
                }
    
            });
        }
    </script>
    

3. 模块管理(多对一)

  1. 分析:一个项目由多个功能模块实现。

  2. 修改project-model-add.jsp(实现:选择项目即可确定需求的功能)

    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
        $(function () {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/mod/modprj",
                success: function (msg) {
                    $(msg).each(function (index,item) {
                        var option = "<option value='"+item.pid+"'>"+item.pname+"</option>";
                        $("#pronameList").append(option);
                        var proname = item.pname;
                        $("#proname").val(proname);
                    })
                }
            });
        });
    
        function parserLoader(id) {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/mod/modAna/"+id,
                success:function (msg) {
                    $("#analysisFk").val(msg.id)
                }
            });
        }
    </script>
    
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">选择项目:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<select id="pronameList" name="proname" οnchange="parserLoader(this.value)">
    			<option value=1>请选择项目...</option>
    		</select></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">选择需求:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input id="analysisFk" name="analysisFk">
    	</td>
    </tr>
    

    遇到一个比较坑的是在项目名称存储的时候,因为前面使用id关联,导致存储的项目名称是每一个项目对应的id,后面显示的时候又和前面基本信息管理的问题类似,后面使用前端获取下拉框中的内容。搞定

    project-model-add.jsp

    <script>
        function parserLoader(id) {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/mod/modAna/"+id,
                success:function (msg) {
                    $("#analysisFk").val(msg.id)
                    var type = $("#pronameList").find("option:selected").text();
                    $("#proname").val(type);
                    alert(type);
                }
            });
        }
    </script>
    

    剩余页面上的功能和前面类似。

4. 功能管理

功能管理与模块的关系是多对一,同样和前面模块类似,选定项目后,可以确定需求,但是模块则不需要确定。因为模块与需求是多对一的,所以这里应该是可以选择为那个模块添加功能。

  1. 修改project-function-add.jsp

    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
        $(function () {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/fun/funprj",
                success: function (msg) {
                    $("#pronameList").empty();   //每次选择下拉框之前清除原有的内容,否则一直追加
                    $(msg).each(function (index,item) {
                        var option = "<option value='"+item.pid+"'>"+item.pname+"</option>";
                        $("#pronameList").append(option);
                    })
                }
            });
        });
    
        function parserLoaderAna(id) {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/fun/funAna/"+id,
                success:function (msg) {
                    $("#proname").val(msg.proname);
                    $("#analysisname").val(msg.title)
                    $("#analysisnameList").empty();
                    $(msg).each(function (index,item) {
                        var option = "<option value='"+item.id+"'>"+item.title+"</option>";
                        $("#analysisnameList").append(option);
                    })
                }
            });
        }
    
        function parserLoaderMod(id) {
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/fun/funMod/"+id,
                success:function (msg) {
                    $("#modeleFk").empty();
                    $(msg).each(function (index,item) {
                        var option = "<option value='"+item.id+"'>"+item.modname+"</option>";
                        $("#modeleFk").append(option);
                    })
                }
            });
        }
    </script>
    
    
    <td align="right" bgcolor="#FAFAF1" height="22">选择项目:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
        <input type="hidden" id="proname" name="proname">
        <select id="pronameList" name="pronameList" οnclick="parserLoaderAna(this.value)">
            <option value=1>请选择项目...</option>
        </select>
    </td>
    </tr>
    <tr >
        <td align="right" bgcolor="#FAFAF1" height="22">选择需求:</td>
        <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
            <input type="hidden" id="analysisname" name="analysisname">
            <select id="analysisnameList" name="analysisnameList" οnclick="parserLoaderMod(this.value)">
                <option value=1>请选择需求...</option>
            </select>
    
        </td>
    </tr>
    
    

5. 附件上传

  1. 文件上传前端配置

    1. 同步文件上传
      1.前端页面表单属性:
        form:type=post
        encytype="multipart/form-data"
    2. input标签类型:
        input:type="file"
        
    3. 后端
       上传和下载的jar包
       springmvc.xml文件中配置CommonsMultiPartResolver
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="defaultEncoding" value="UTF-8"/>
            <property name="maxUploadSize" value="#{500*1024*1024}"/>
        </bean>
       
       在attachment类中没有对应的属性保存附件的信息需要在目标方法的参数上使用MulTipartFile 类型来接收
    
  2. 修改project-file-add.jsp,同步方式

    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
    	$(function () {
    		$.ajax({
    			type:"GET",
    			url:"${pageContext.request.contextPath}/attach/attprj",
    			success: function (msg) {
    				$(msg).each(function (index,item) {
    					var option = "<option value='"+item.pid+"'>"+item.pname+"</option>";
    					$("#pronameList").append(option);
    				})
    			}
    		});
    	});
    
    	function commit() {
    	    $("#form2").submit();
    	}
    </script>
    
    <form id="form2" name="form2" action="${pageContext.request.contextPath}/attach/saveAttach" enctype="multipart/form-data" method="post">
    
    <table width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
    <tr bgcolor="#E7E7E7">
    <td height="24" colspan="2" background="skin/images/tbg.gif">&nbsp;添加附件&nbsp;</td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">选择项目:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<select id="pronameList" name="proFk">
    		<option value=1>请选择...</option>
    	</select></td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">附件名称:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<input size="26" name="attname"/>
    </td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">附件信息描述:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<input size="52" name="attdis"/>
    </td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">附件:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<input type="file" name="attachment"/>
    </td>
    </tr>
    
    
    <tr >
    <td align="right" bgcolor="#FAFAF1" >备注:</td>
    <td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    	<textarea rows=10 cols=130 name="remark"></textarea>
    </td>
    </tr>
    
  3. controller层

    package com.anzhi.projectmanage.controller;
    
    import com.anzhi.projectmanage.bean.Attachment;
    import com.anzhi.projectmanage.bean.Project;
    import com.anzhi.projectmanage.bean.ProjectExample;
    import com.anzhi.projectmanage.service.AttachmentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpSession;
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import java.util.UUID;
    
    @Controller
    @RequestMapping("/attach")
    public class AttachmentController {
        @Autowired
        AttachmentService attachmentService;
    
        @RequestMapping(value = "/attprj", method = RequestMethod.GET)
        @ResponseBody
        public List<Project> modPrjList(ProjectExample projectExample){
            return attachmentService.attPrjList(projectExample);
        }
    
        @RequestMapping(value = "/saveAttach", method = RequestMethod.POST)
        public String saveAttach(Attachment attach, MultipartFile attachment, HttpSession session){
            //FASTDFS 文件服务器
            ServletContext context =session.getServletContext();
            String realPath = context.getRealPath("/upload");
            File file = new File(realPath);
            if(!file.exists()){
                file.mkdirs();
            }
    
            String originalFilename = attachment.getOriginalFilename();
            String realName = UUID.randomUUID().toString().replaceAll("-", "") + originalFilename;
            try {
                attachment.transferTo(new File(realPath+"/"+realName));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
    
            //将文件的存储路径保存到path中
            attach.setPath(realPath+"/"+realName);
    
            attachmentService.saveAtta(attach);
    
            return "redirect:/project-file.jsp";
        }
    
    }
    
  4. 异步方式

    <%@ page language="java"  pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>添加附件</title>
    <link rel="stylesheet" type="text/css" href="skin/css/base.css">
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
    	$(function () {
    		$.ajax({
    			type:"GET",
    			url:"${pageContext.request.contextPath}/attach/attprj",
    			success: function (msg) {
    				$(msg).each(function (index,item) {
    					var option = "<option value='"+item.pid+"'>"+item.pname+"</option>";
    					$("#projects").append(option);
    				})
    			}
    		});
    	});
    
        function commit() {
            //下面属性要和表单对应
            var pid= $("#projects").val();
            var attname=$("#attname").val();
            var attdis=$("#attdis").val();
            var remark=$("#remark").val();
            var file=$("#file")[0].files[0];  //传一个文件
            var formdata = new FormData();
            formdata.append("proFk",pid);
            formdata.append("attname",attname);
            formdata.append("attdis",attdis);
            formdata.append("remark",remark);
            formdata.append("attachment",file);
    
            $.ajax({
                type:"post",
                url:"${pageContext.request.contextPath}/attach/saveAttach",
                data:formdata,
                cache:false,//不要在浏览器端缓存
                processData:false, //告诉浏览器,不要进行数据转换
                contentType:false, //告诉浏览器,不要设置编码
                success:function(msg){
                    if(msg.statusCode == 200){
                        window.location.href="${pageContext.request.contextPath}/project-file.jsp";
                    }else{
                        if(confirm("您确定要离开该页面么?")){
                            window.location.href="${pageContext.request.contextPath}/project-file.jsp";
                        }
                    }
                }
    
            });
        }
    </script>
    </head>
    <body leftmargin="8" topmargin="8" background='skin/images/allbg.gif'>
    
    <!--  快速转换位置按钮  -->
    <table width="98%" border="0" cellpadding="0" cellspacing="1" bgcolor="#D1DDAA" align="center">
    <tr>
    <td height="26" background="skin/images/newlinebg3.gif">
    <table width="58%" border="0" cellspacing="0" cellpadding="0">
    <tr>
    <td >
    当前位置:项目管理>>添加附件
    </td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    
    <form name="form2">
    
    <table width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
    <tr bgcolor="#E7E7E7">
    <td height="24" colspan="2" background="skin/images/tbg.gif">&nbsp;添加附件&nbsp;</td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">选择项目:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<select id="projects" name="proFk">
    		<option value=1>请选择...</option>
    	</select></td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">附件名称:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<input size="26" id="attname" name="attname"/>
    </td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">附件信息描述:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<input size="52" id="attdis" name="attdis"/>
    </td>
    </tr>
    <tr >
    <td align="right" bgcolor="#FAFAF1" height="22">附件:</td>
    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    	<input type="file" id="file" name="attachment"/>
    </td>
    </tr>
    
    
    <tr >
    <td align="right" bgcolor="#FAFAF1" >备注:</td>
    <td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    	<textarea rows=10 cols=130 id="remark" name="remark"></textarea>
    </td>
    </tr>
    </table>
    
    </form>
    </body>
    </html>
    
    剩余的功能:查询、下载、排序等功能后面再实现,存在些问题。

2. 日常办公-》dailyOffice;同上

  1. 需求分析:当公司接到订单,并立项,分析对应需求,添加相应模块,将模块拆分成各个子功能分配到每个员工,此时指派的时候需要相应的部门leader分配任务,此时就需要用户登录,给员工指定相应的任务。

1. 所以首先完成用户登录的功能:

  1. 验证码原理:

    1. 首先在服务器端生成一个n个字符的字符串,然后保存到session,并将这个字符转换成img图片,传递到浏览器端;
    2. 用户根据浏览器显示的验证码图片,输入对应的字符,然后提交表单
    3. 在服务器端将用户提交的验证码字符[request域]和session服务端保存的验证码进行比较,如果相等,认为验证码输入正确,然后就可以验证用户名和密码是否正确,如果不相等,直接重定向到当前页面,反之,允许登录进行后续操作,并将用户信息保存到session中
  2. 验证码框架:纯java实现(课程资料)

    utils层:

    package com.anzhi.utils;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    
    /**
     * 验证码工具类
     */
    public class ValidateCode {
    
        private int width = 90;//验证码宽度 默认值:90
        private int height = 40;//验证码高度 默认值:40
        private int codeCount = 4;//验证码个数  默认值:4
        private int lineCount = 19;//混淆线个数  默认值:19
        private int fontSize = 20;//字体大小像素
        //存储session中的key值 默认值:"validateCode"
        private String sessionKey = "validateCode";
    
        public ValidateCode() {
        }
    
        /**
         * @param width    验证码宽度
         * @param height   验证码高度
         * @param fontSize 字体大小像素
         */
        public ValidateCode(int width, int height, int fontSize) {
            this.width = width;
            this.height = height;
            this.fontSize = fontSize;
        }
    
        /**
         * @param width      验证码宽度
         * @param height     验证码高度
         * @param fontSize   字体大小像素
         * @param sessionKey 存储session中的key值
         */
        public ValidateCode(int width, int height, int fontSize, String sessionKey) {
            this.width = width;
            this.height = height;
            this.fontSize = fontSize;
            this.sessionKey = sessionKey;
        }
    
        /**
         * @param width      验证码宽度
         * @param height     验证码高度
         * @param codeCount  验证码个数
         * @param fontSize   字体大小像素
         * @param sessionKey 存储session中的key值
         */
        public ValidateCode(int width, int height, int codeCount, int fontSize, String sessionKey) {
            this.width = width;
            this.height = height;
            this.codeCount = codeCount;
            this.fontSize = fontSize;
            this.sessionKey = sessionKey;
        }
    
        /**
         * @param width      验证码宽度
         * @param height     验证码高度
         * @param codeCount  验证码个数
         * @param lineCount  混淆线个数
         * @param fontSize   字体大小像素
         * @param sessionKey 存储session中的key值
         */
        public ValidateCode(int width, int height, int codeCount, int lineCount, int fontSize, String sessionKey) {
            this.width = width;
            this.height = height;
            this.codeCount = codeCount;
            this.lineCount = lineCount;
            this.fontSize = fontSize;
            this.sessionKey = sessionKey;
        }
    
    
        char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
                'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    
        /**
         * 具体获取验证码的方法
         *
         * @param time time为时戳,这样的话可以避免浏览器缓存验证码
         * @throws IOException
         */
        public void getCode(HttpServletRequest request, HttpServletResponse response) {
            //定义随机数类
            Random r = new Random();
            //定义存储验证码的类
            StringBuilder builderCode = new StringBuilder();
            //定义画布
            BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //得到画笔
            Graphics g = buffImg.getGraphics();
            //1.设置颜色,画边框
            g.setColor(Color.gray);
            g.drawRect(0, 0, width, height);
            //2.设置颜色,填充内部
            g.setColor(Color.white);
            g.fillRect(1, 1, width - 2, height - 2);
            //3.设置干扰线
            // g.setColor(Color.gray);
            for (int i = 0; i < lineCount; i++) {
                int _R = (int) Math.floor(Math.random() * 256);
                int _G = (int) Math.floor(Math.random() * 256);
                int _B = (int) Math.floor(Math.random() * 256);
                g.setColor(new Color(_R, _G, _B, 255));
                g.drawLine(r.nextInt(width), r.nextInt(width), r.nextInt(width), r.nextInt(width));
            }
            //4.设置验证码
            g.setColor(Color.blue);
            //4.1设置验证码字体
            g.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, fontSize));
            for (int i = 0; i < codeCount; i++) {
                char c = codeSequence[r.nextInt(codeSequence.length)];
                builderCode.append(c);
                g.drawString(c + "", ((width / codeCount) * i + 2), height * 4 / 5);
            }
            try {
                //5.输出到屏幕
                ServletOutputStream sos = response.getOutputStream();
                ImageIO.write(buffImg, "png", sos);
                //6.保存到session中
                HttpSession session = request.getSession();
                session.setAttribute("" + sessionKey + "", builderCode.toString());
                //7.禁止图像缓存。
                response.setHeader("Pragma", "no-cache");
                response.setHeader("Cache-Control", "no-cache");
                response.setDateHeader("Expires", 0);
                response.setContentType("image/png");
                //8.关闭sos
                sos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    问题记录:5、6步骤对换一下,先获取session ID,再输出到屏幕,因为在某些情况,会导致在Response响应(response.getOutputStream())之后,才创建Session(request.getSession()),而此时已经找不到Session ID,所以会报错。我复现场景是这样的:在重启服务器后,在上一次网页刷新登录页面进行登录,此时就会出现session ID无法获取的情况。

    controller层

    package com.anzhi.sysmanage.controller;
    
    import com.anzhi.sysmanage.bean.Employee;
    import com.anzhi.utils.ValidateCode;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    @Controller
    @RequestMapping("/code")
    public class CodeController {
    
        @RequestMapping(value="/getCode")
        public void getCode(@RequestParam(value = "time") String time,
                            HttpServletRequest request,
                            HttpServletResponse response) {
            ValidateCode code = new ValidateCode(70, 30, 4, 30, 25, "validateCode");
            code.getCode(request, response);
        }
    
    
    }
    
    package com.anzhi.sysmanage.controller;
    
    import com.anzhi.projectmanage.bean.Project;
    import com.anzhi.projectmanage.bean.ProjectExample;
    import com.anzhi.sysmanage.bean.Employee;
    import com.anzhi.sysmanage.service.EmployeeService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.servlet.mvc.support.RedirectAttributes;
    
    import javax.servlet.http.HttpSession;
    import java.util.List;
    
    @Controller
    @RequestMapping(value = "/emp")
    public class EmployeeController {
    
        @Autowired
        EmployeeService employeeService;
    
        /*
        * 携带参数到重定向页面
        * 1. 在目标方法参数上使用:RedirectAttributes,
        * 2. 使用RedirectAttributes 携带数据重定向不能直接重定向到页面
        * */
        @RequestMapping(value = "/login", method = RequestMethod.POST)
        public String login(Employee employee, String code, HttpSession session, RedirectAttributes redirectAttributes){
           //获取到登录时,存储在session中的验证属性值validateCode,这是在验证码中指定好的属性名称
            String validateCode = (String)session.getAttribute("validateCode");
            if(code.equalsIgnoreCase(validateCode)){
                session.removeAttribute(validateCode);
                employee = employeeService.login(employee);
                if(employee!=null){
                    //设置session对应的键,在报销中需要通过loginUser键获取employee对应的属性
                    session.setAttribute("loginUser", employee);
                    return "redirect:/index.jsp";
                }else{
                    redirectAttributes.addFlashAttribute("errorMsg","用户名或密码错误");
                    //不能直接重定向页面
                    return "redirect:/login";
                }
            }
            redirectAttributes.addFlashAttribute("errorMsg","验证码错误");
            return "redirect:/login";
        }
    
    
        @RequestMapping(value = "/logout", method = RequestMethod.GET)
        public String logout(HttpSession session){
            session.invalidate();
            return "redirect:/login.jsp";
        }
    
        @RequestMapping(value = "/getPrjAnaJson", method = RequestMethod.GET)
        @ResponseBody
        public List<Project> getPrjAnaJson(ProjectExample projectExample){
            return employeeService.getPrjAnaJson(projectExample);
        }
    }
    
  3. login登录:

    login.jsp

    <base href="${pageContext.request.contextPath}/">
    <script type="text/javascript" src="static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
        if(${!empty errorMsg}){
            alert("${errorMsg}")
        }
        $(function () {
            $("#image").click(function () {
                $(this).attr("src", "code/getCode?time="+new Date());   //加时间戳,使验证码刷新变动
            });
        });
    </script>
    
    
    
    
    <TABLE id=table2 cellSpacing=1 cellPadding=0 width="100%" border=0>
        <TBODY>
            <TR>
                <TD align=middle width=81><FONT color=#ffffff>用户名:</FONT></TD>
                <TD><INPUT class=regtxt title=请填写用户名 maxLength=16 size=16 id=username name="username"></TD>
            </TR>
            <TR>
               <TD align=middle width=81><FONT color=#ffffff>密&nbsp; 码:</FONT></TD>
               <TD><INPUT class=regtxt title=请填写密码 type=password maxLength=16 size=16 id=pass name="password"></TD>
            </TR>
            <TR>
               <TD align=middle width=81><FONT color=#ffffff>验证码:</FONT></TD>
               <TD><INPUT style="width: 80px; height: 20px" class=regtxt title=请填写验证码 maxLength=50 size=16 name="code">
               	     <img id="image" style="margin-top: 5px" src="code/getCode?time="+<%=new Date()%>>
             </TR>
        </TBODY>
    </TABLE>
    
  4. service层

    package com.anzhi.sysmanage.service.Impl;
    
    import com.anzhi.projectmanage.bean.Project;
    import com.anzhi.projectmanage.bean.ProjectExample;
    import com.anzhi.projectmanage.mapper.ProjectMapper;
    import com.anzhi.sysmanage.bean.Employee;
    import com.anzhi.sysmanage.bean.EmployeeExample;
    import com.anzhi.sysmanage.mapper.EmployeeMapper;
    import com.anzhi.sysmanage.service.EmployeeService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class EmployeeServiceImpl  implements EmployeeService {
        @Autowired
        EmployeeMapper employeeMapper;
    
        @Autowired
        ProjectMapper projectMapper;
    
        @Override
        public Employee login(Employee employee) {
            EmployeeExample employeeExample = new EmployeeExample();
            EmployeeExample.Criteria criteria = employeeExample.createCriteria();
            criteria.andUsernameEqualTo(employee.getUsername());
            criteria.andPasswordEqualTo(employee.getPassword());
            List<Employee> employees = employeeMapper.selectByExample(employeeExample);
            if(employees.size()>0){
                return employees.get(0);
            }
            return null;
        }
    
        @Override
        public List<Project> getPrjAnaJson(ProjectExample projectExample) {
            return projectMapper.getPrjAnaJsonLists();
        }
    }
    

    springmvc.xml后端配置登录login页面

    <!--如果发送的请求不想通过controller,只想直接地跳转到目标页面,这时候就可以使用mvc:view-controller标签-->
    <mvc:view-controller path="/login" view-name="login"></mvc:view-controller>
    

    web.xml配置(前端)

    <!--指定先要加载的首页-->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
    

2. 报销功能:

报销需求分析:

  1. 不同的角色对于报销查询的信息、以及增删等权限是不同的。需要根据角色的需求对应展示相应的数据。比如:

    角色添加报销的时候,需要获取登录角色的的id,添加对应的报销内容;同样查询的时候,查询的内容也只能是自己的报销记录等;对于财务,则没有限制,可以查询所有员工的报销信息,并具有审核的权限

  2. 分页

    1. 分页的意义:

      1. 减轻服务器的压力;
      2. 提高查询速率,给用户更好的体验;
    2. 分页分为:前端分页、和后端分页

    3. 分页插件:mybatis:支持多种数据库

      1. 使用步骤:

        1. 导入jar包;

          pom.xml

          <!--mybatis分页工具-->
          <dependency>
              <groupId>com.github.pagehelper</groupId>
              <artifactId>pagehelper</artifactId>
              <version>5.2.0</version>
          </dependency>
          
        2. 在mybatis的全局配置文件中配置一个PageHelper的插件

          <plugins>
              <!-- com.github.pagehelper为PageHelper类所在包名 -->
              <plugin interceptor="com.github.pagehelper.PageInterceptor">
                  <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
                  <property name="helperDialect" value="mysql"/>
              </plugin>
          </plugins>
          
        3. 在我们调查列表之前使用PageHelper.startPage()来设置分页信息

  3. 修改menu.jsp

    /*替换原本的日常办公*/
    <dl class='bitem'><dt οnclick=showHide('items2_1')><b>日常办公</b></dt><dd style='display:none' class='sitem' id=items2_1><ul class='sitemu' id=1>
    <li><a href='task-add.jsp' target='main'>创建任务</a> </li>
    <li><a href='task.jsp' target='main'>任务信息</a> </li>
    <li><a href='task-my.jsp' target='main'>我的任务</a> </li>
    <li><a href='notice-send.jsp' target='main'>通知公告</a></li>
    <li><a href='archives.jsp' target='main'>档案管理</a> </li>
    	<li><a href='archives.jsp' target='main'>我的档案</a> </li>
    <li><a href='message-give.jsp' target='main'>消息推送</a> </li>
    <li><a href='baoxiao-task.jsp' target='main'>报销审批</a> </li>
    	<li><a href='mybaaoxiao-base.jsp' target='main'>我的报销</a> </li>
    </ul></dd></dl>
    
  4. 填加新的页面

    报销的页面,在课件资料中

  5. 报销信息保存

    mybaoxiao-add.jsp(和前面保存步骤相同,不同的是controller的传参)

    <%@ page language="java"  pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>添加附件</title>
    <link rel="stylesheet" type="text/css" href="skin/css/base.css">
    	<base src="${pageContext.request.contextPath}/">
    	<script type="text/javascript" src="static/js/jquery-1.8.3.js"></script>
    	<script type="text/javascript">
            function commit() {
                $("#form9").submit();
            }
    	</script>
    
    </head>
    <body leftmargin="8" topmargin="8" background='skin/images/allbg.gif'>
    
    <!--  快速转换位置按钮  -->
    <table width="98%" border="0" cellpadding="0" cellspacing="1" bgcolor="#D1DDAA" align="center">
    <tr>
     <td height="26" background="skin/images/newlinebg3.gif">
      <table width="58%" border="0" cellspacing="0" cellpadding="0">
      <tr>
      <td >
        当前位置:报销管理>>添加新的报销
     </td>
     </tr>
    </table>
    </td>
    </tr>
    </table>
    
    <form name="form2" action="${pageContext.request.contextPath}/bx/saveInfo" id="form9" method="post">
    
    <table width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
    <tr bgcolor="#E7E7E7">
    	<td height="24" colspan="2" background="skin/images/tbg.gif">&nbsp;添加新的报销单&nbsp;</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">支出类型:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<select name="paymode">
    			<option value="出差票据">出差票据</option>
    			<option value="办公采购">办公采购</option>
    			<option value="其他">其他</option>
    		</select>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">总金额:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input size="26" name="totalmoney"/>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">使用时间:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input size="52" name="bxtime"/>
    	</td>
    </tr>
    
    <tr >
    	<td align="right" bgcolor="#FAFAF1" >备注:</td>
    	<td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    		<textarea rows=10 cols=130 name="bxremark"></textarea>
    	</td>
    </tr>
    
    
    <tr bgcolor="#FAFAF1">
    <td height="28" colspan=4 align=center>
    	&nbsp;
    	<a href="javascript:commit()" class="coolbg">保存</a>
    	<a href="javascript:history.o(-1)" class="coolbg">返回</a>
    </td>
    </tr>
    </table>
    
    </form>
      
    
    </body>
    </html>
    

    controller层

    @RequestMapping(value = "/saveInfo", method = RequestMethod.POST)
    public String saveInfo(BaoXiao baoXiao, HttpSession session){
        //通过session获取当前对象id,根据前面登录时传入session的属性名
        //这里需要注意的是,session中未实现序列化(Serializable)的用户,是无法写入磁盘的(活化、钝化,去做了解)
        //loginUser属性是前面用户登陆时就已经存储好的键,通过该键可以直接获取当前登录的用户信息
        Employee loginUser = (Employee)session.getAttribute("loginUser");
        //将其取出存储到报销数据库的外键中
        baoXiao.setEmpFk(loginUser.getEid());
        baoXiaoService.saveInfo(baoXiao);
        return "redirect:/bx/getMyList";
    }
    

    service层

        @Override
        public void saveInfo(BaoXiao baoXiao) {
            baoXiao.setBxstatus(0);
            String bxid = UUID.randomUUID().toString().replaceAll("-", "");
            //数据库中id长度最大为64位,可以拼接一个64位长度,也可以不用
            //String suffix = UUID.randomUUID().toString().replaceAll("-", "");
            baoXiao.setBxid(bxid);
            baoXiaoMapper.insert(baoXiao);
        }
    
  6. 分页的具体使用:

    controller层

    @RequestMapping(value = "/getMyList", method = RequestMethod.GET)
    //defaultValue属性用来定义一个参数的自定义属性
    public ModelAndView getMyList(HttpSession session, @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum){
        Employee loginUser = (Employee)session.getAttribute("loginUser");
        //将其取出存储到报销数据库的外键中
        Integer id = loginUser.getEid();
        //将获取到的对象进行封装,封装为PageInfo,进行分页
        PageInfo<BaoXiao> page = baoXiaoService.getMyyList(id, pageNum);
        ModelAndView mv = new ModelAndView("mybaoxiao-base");
        mv.addObject("page", page);
        return mv;
    }
    

    service层

        @Override
        public PageInfo<BaoXiao> getMyyList(Integer id, Integer pageNum) {
            BaoXiaoExample baoXiaoExample = new BaoXiaoExample();
            BaoXiaoExample.Criteria criteria = baoXiaoExample.createCriteria();
            criteria.andEmpFkEqualTo(id);
            //每页显示3条数据
            PageHelper.startPage(pageNum,3);
            List<BaoXiao> baoXiaos = baoXiaoMapper.selectByExample(baoXiaoExample);
            //包装,并设置导航页5
            PageInfo<BaoXiao> pages = new PageInfo<BaoXiao>(baoXiaos,5);
            return pages;
        }
    
    

    mybaoxiao-base.jsp

    <script type="text/javascript">
        function queryList() {
            var pagNum = $("#pageNum").val();
            /*必须输入为正整数*/
            var reg = /^[1-9]\d*$/;
            if (pagNum == null || pagNum == "") {
                alert("不能为空");
                return false;
            }else if(!reg.test(pagNum)){
                alert("请输入整数");
                return false;
            }else{
                window.location.href="${pageContext.request.contextPath}/bx/getMyList?pageNum="+pagNum;
            }
        }
    </script>
    
    
    
    
    /*page.list = page.getList(), 可以直接遍历page, 下面的写法同样如此*/
    <c:forEach items="${page.list}" var="bs" varStatus="index">
        <tr align='center' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22" >
            <td><input name="id" type="checkbox" id="id" value="${bs.bxid}" class="np"></td>
            <td>${index.count}</td>
            <td>${bs.totalmoney}</td>
            <td align="center">
                <a href=''>
                    <u>
                        <fmt:formatDate value="${bs.bxtime}" pattern="yyyy-MM-dd"></fmt:formatDate>
                    </u>
                </a>
            </td>
            <td>${bs.bxremark}</td>
    
            <c:if test="${bs.bxstatus == 0}">
                <td>未审批</td>
                <td><a href="mybaoxiao-edit.jsp?bxid=${bs.bxid}">编辑</a> </td>
            </c:if>
            <c:if test="${bs.bxstatus == 1}">
                <td>驳回</td>
                <td><a href="javascript:void(0)" style="pointer-events:none;color: grey" >编辑</a> </td>
            </c:if>
            <c:if test="${bs.bxstatus == 2}">
                <td>已审批</td>
                <td><a href="mybaoxiao-edit.jsp?bxid=${bs.bxid}">编辑</a> </td>
            </c:if>
            <c:if test="${bs.bxstatus == 3}">
                <td>审批并付款</td>
                <td><a href="javascript:void(0)" style="pointer-events:none;color: grey" >编辑</a> </td>
            </c:if>
    
        </tr>
    </c:forEach>
    
    
    <tr align="right" bgcolor="#EEF4EA">
        <td height="36" colspan="12" align="center">
            <div>
                <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=1">首页</a>
                <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${page.pageNum-1}">上一页</a>
                <c:forEach items="${page.navigatepageNums}" var="pageNum">
                    <c:if test="${pageNum == page.pageNum}">
                        <span style="color: red; font-weight: bold">${pageNum}</span>
                    </c:if>
                    <c:if test="${pageNum != page.pageNum}">
                        <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${pageNum}">${pageNum}页</a>
                    </c:if>
                </c:forEach>
                <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${page.pageNum+1}">下一页</a>
                <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${page.pages}">末页</a>
                &nbsp;&nbsp;跳转到<input size="1px" id="pageNum" οnblur="queryList()">&nbsp;页
            </div>
        </td>
    </tr>
    
    
1. 页的细节问题

在首页的时候,点击上一页,发现显示是当前页,但是,页数没有明显地区分了

解决:

<property name="reasonable" value="true"></property>

或者翻页改为下面的形式:并且添加了跳转页面的功能

<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
<script type="text/javascript">
    function queryList() {
        var pagNum = $("#pageNum").val();
        var reg = /^[1-9]\d*$/;
        if (pagNum == null || pagNum == "") {
            alert("不能为空");
            return false;
        }else if(!reg.test(pagNum)){
            alert("请输入整数");
            return false;
        }else{
            window.location.href="${pageContext.request.contextPath}/bx/getMyList?pageNum="+pagNum;
        }
    }
</script>




<tr align="right" bgcolor="#EEF4EA">
    <td height="36" colspan="12" align="center">
        <div>
            <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=1">首页</a>
            <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${page.pageNum-1}">上一页</a>
            <c:forEach items="${page.navigatepageNums}" var="pageNum">
                <c:if test="${pageNum == page.pageNum}">
                    <span style="color: red; font-weight: bold">${pageNum}</span>
                </c:if>
                <c:if test="${pageNum != page.pageNum}">
                    <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${pageNum}">${pageNum}页</a>
                </c:if>
            </c:forEach>
            <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${page.pageNum+1}">下一页</a>
            <a href="${pageContext.request.contextPath}/bx/getMyList?pageNum=${page.pages}">末页</a>
            &nbsp;&nbsp;跳转到<input size="1px" id="pageNum" οnblur="queryList()">&nbsp;页
        </div>
    </td>
</tr>

3. 分页条件查询功能:

  1. mybaoxiao-base.jsp

    /*放在(当前位置:个人报销管理>>报销列表)表单下面*/
    
    <!--  搜索表单  -->
    <form name='form3' action='' method='get'>
        <input type='hidden' name='dopost' value='' />
        <table width='98%'  border='0' cellpadding='1' cellspacing='1' bgcolor='#CBD8AC' align="center" style="margin-top:8px">
            <tr bgcolor='#EEF4EA'>
                <td background='skin/images/wbg.gif' align='center'>
                    <table border='0' cellpadding='0' cellspacing='0'>
                        <tr>
                            <td width='90' align='center'>搜索条件:</td>
                            <td width='160'>
                                <select name='search_status' style='width:150px'>
                                    <option >选择类型...</option>
                                    <option value='0'>未审批</option>
                                    <option value='1'>驳回</option>
                                    <option value='2'>已审批</option>
                                    <option value='3'>已付款</option>
                                </select>
                            </td>
                            <td width='70'>
                                关键字:
                            </td>
                            <td width='160'>
                                <input type='text' name='search_lke_keyword' value='' style='width:120px' />
                            </td>
                            <td>
                                &nbsp;&nbsp;&nbsp;<input name="imageField" type="image" src="${pageContext.request.contextPath}/skin/images/frame/search.gif" width="45" height="20" border="0" class="np" />
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </form>
    
    
  2. controller将条件搜索与查询信息合并编写(另一种写法,也可以按照原本的写法,重新写一个接口请求)

    @RequestMapping(value = "/getMyList", method = RequestMethod.GET)
    public ModelAndView getMyList(HttpServletRequest request, HttpSession session, @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum){
        Employee loginUser = (Employee)session.getAttribute("loginUser");
    
        /*
            * 合并搜条件的回显
            * 搜索以search_前缀开头的,最终请求样式如下
            * ${pageContext.request.contextPath}/bx/getMyList?serach_status=1&search_keyword=wd
            * map的key是浏览器传递参数去掉search_之后剩余的部分
            * */
        Map<String, Object> parametMap = WebUtils.getParametersStartingWith(request,"search_");
    
        //将其取出存储到报销数据库的外键中
        Integer id = loginUser.getEid();
        PageInfo<BaoXiao> page = baoXiaoService.getMyyList(id,  parametMap, pageNum);
        ModelAndView mv = new ModelAndView("mybaoxiao-base");
        mv.addObject("page", page);
    
        return mv;
    }
    

    service层:

    @Override
    public PageInfo<BaoXiao> getMyyList(Integer id, Map<String, Object>parametMap, Integer pageNum) {
        BaoXiaoExample baoXiaoExample = new BaoXiaoExample();
        BaoXiaoExample.Criteria criteria = baoXiaoExample.createCriteria();
        criteria.andEmpFkEqualTo(id);
    
        //合并查询语句,这里需要注意的是状态查询是精确查询,关键字查询是模糊查询,所以我们可以先解析判断,
        //最后将结果封装为一个Map,在返回查询
        Map<String,String> mybatisMap = parseParameterMapToMybatisMap(parametMap);
        System.out.println(mybatisMap);
        String status = mybatisMap.get("status");
        if(status!=null && status!=""){
            criteria.andBxstatusEqualTo(Integer.parseInt(status));
        }
        String keyword = mybatisMap.get("keyword");
        if(keyword!=null && keyword!=""){
            criteria.andBxremarkLike(keyword);
        }
    
        PageHelper.startPage(pageNum,3);
        List<BaoXiao> baoXiaos = baoXiaoMapper.selectByExample(baoXiaoExample);
        //包装,并设置导航页5
        PageInfo<BaoXiao> pages = new PageInfo<BaoXiao>(baoXiaos,5);
    
        return pages;
    }
    
    private Map<String, String> parseParameterMapToMybatisMap(Map<String, Object> parametMap) {
        Map<String, String> resultMap = new HashMap<String, String>();
        Set<Map.Entry<String, Object>> entries = parametMap.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            String key = entry.getKey();
            String value = (String)entry.getValue();
            if(key.contains("like")){
                key = key.substring(key.indexOf("_")+1);
                value="%"+value+"%";
            }
            resultMap.put(key,value);
        }
    
        return resultMap;
    }
    
细节:

在得到查询结果的页面后,点击下一页后发现不在展示查询的结果,而是展示了所有的查询结果,这是因为第一次查询的时候将结果返回了服务器,第二次则没有,所以才会造成这样的情况。

解决:

将后端得到的结果继续给到前端,并将分页通用化

controller层

    @RequestMapping(value = "/getMyList", method = RequestMethod.GET)
    public ModelAndView getMyList(HttpServletRequest request, HttpSession session, @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum){
        Employee loginUser = (Employee)session.getAttribute("loginUser");

        /*
        * 合并搜条件的回显
        * 搜索以search_前缀开头的,最终请求样式如下
        * ${pageContext.request.contextPath}/bx/getMyList?serach_status=1&search_keyword=wd
        * map的key是浏览器传递参数去掉search_之后剩余的部分
        * */
        Map<String, Object> parametMap = WebUtils.getParametersStartingWith(request,"search_");
        String querstr = parseparameterMapToString(parametMap);

        /*
        * 通用分页:getRequestURI获取到当前的请求路径,并将属性值返回给页面
        * */
        String requestURI = request.getRequestURI();

        //将其取出存储到报销数据库的外键中
        Integer id = loginUser.getEid();
        PageInfo<BaoXiao> page = baoXiaoService.getMyyList(id,  parametMap, pageNum);
        ModelAndView mv = new ModelAndView("mybaoxiao-base");
        mv.addObject("page", page);
        mv.addObject("querstr",querstr);
        mv.addObject("requestURI",requestURI);
        return mv;
    }

    private String parseparameterMapToString(Map<String, Object> parametMap) {
        Set<Map.Entry<String, Object>> entries = parametMap.entrySet();
        String str = "";
        for (Map.Entry<String, Object> entry : entries) {
            String key = entry.getKey();
            String value = (String)entry.getValue();
            str = str+"&"+"search_"+key+"="+value;
        }
        return str;
    }

page.jsp

<%@ page language="java"  pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"  %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
        <title>我的报销分页</title>
        <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/skin/css/base.css">
        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
        <script type="text/javascript">
            function queryList() {
                var pagNum = $("#pageNum").val();
                /*输入页为整型*/
                var reg = /^[1-9]\d*$/;
                if (pagNum == null || pagNum == "") {
                    alert("不能为空");
                    return false;
                }else if(!reg.test(pagNum)){
                    alert("请输入整数");
                    return false;
                }else{
                    window.location.href="${requestURI}?pageNum="+pagNum+"${querstr}";
                }
            }
        </script>

    </head>

    <tr align="right" bgcolor="#EEF4EA">
        <td height="36" colspan="12" align="center">
            <div>
                <a href="${requestURI}?pageNum=1${querstr}">首页</a>
                <a href="${requestURI}?pageNum=${page.pageNum-1}${querstr}">上一页</a>
                <c:forEach items="${page.navigatepageNums}" var="pageNum">
                    <c:if test="${pageNum == page.pageNum}">
                        <span style="color: red; font-weight: bold">${pageNum}</span>
                    </c:if>
                    <c:if test="${pageNum != page.pageNum}">
                        <a href="${requestURI}?pageNum=${pageNum}${querstr}">${pageNum}页</a>
                    </c:if>
                </c:forEach>
                <a href="${requestURI}?pageNum=${page.pageNum+1}${querstr}">下一页</a>
                <a href="${requestURI}?pageNum=${page.pages}${querstr}">末页</a>
                &nbsp;&nbsp;跳转到<input size="1px" id="pageNum" οnblur="queryList()">&nbsp;页
            </div>
        </td>
    </tr>

mybaoxiao-base.jsp

/*引入page页*/
<jsp:include page="page.jsp"/>

4. 通知公告

  1. 用课程中给到的资料替换项目的通知公告页面,并修改menu中通知公告需要跳转的页面

  2. 发布新公告

    <%@ page language="java"  pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
            <title>发件箱</title>
            <link rel="stylesheet" type="text/css" href="skin/css/base.css">
            <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
            <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/moment.min.js"></script>
            <script type="text/javascript">
                $(function(){
                    $.ajax({
                        type:'GET',
                        url:'${pageContext.request.contextPath}/notice/jsonList',
                        success:function(msg){
                            if(msg.map.statusCode==200){
                                $(msg.map.noticeList).each(function (index,item) {
                                    alert("-----------");
                                    var tr = "<tr align='center' bgcolor='#FFFFFF' onMouseMove='javascript:this.bgColor='#FCFDEE';' onMouseOut='javascript:this.bgColor='#FFFFFF';' height='22' >"
                                    +"<td><input name='id' type='checkbox' id='id' value='"+item.nid+"' class='np'></td>"
                                    +"<td>"+item.nid+"</td>"
                                    +"<td>"+item.ntitle+"</td>"
                                    +"<td align='center'><span >"+item.remark+"</span></td>"
                                    +"<td>"+moment(item.ndate).format('YYYY-MM-DD')+"</td>"
                                    +"<td><a >删除</a>|<a >编辑</a></td>"
                                    "</tr>"
                                   /* $("#list-table").find("tr:eq(1)").after(tr); */   <%--这句查出来的数据顺序是反的--%>
                                    $("#list-table").find("tr[id='focus-tr']").before(tr); 
                                })
                            }
                        },
                        error:function(){
                            alert("网页异常");
                        }
                    });
                });
    
                function parseDate(fmt) {
                    var date = new Date(fmt);
                    var month = date.getMonth()+1;
                    var day = date.getDate();
                    if(date.getMonth()<9){
                        month = "0"+month;
                    }
                    if(date.getDate()<9){
                        day="0"+day;
                    }
                    return date.getFullYear()+"-"+month+"-"+day;
                }
            </script>
    
        </head>
        <body leftmargin="8" topmargin="8" background='skin/images/allbg.gif'>
    
            <!--  快速转换位置按钮  -->
            <table width="98%" border="0" cellpadding="0" cellspacing="1" bgcolor="#D1DDAA" align="center">
                <tr>
                    <td height="26" background="skin/images/newlinebg3.gif">
                        <table width="58%" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <td >
                                    当前位置:信息箱>>通知公告
                                </td>
                                <td>
                                    <input type='button' class="coolbg np" onClick="location='notice-send.jsp';" value='发布新通告' />
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
    
            <!--  搜索表单  -->
    
            <!--  内容列表   -->
            <form name="form2">
    
                <table id="list-table" width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
                    <tr bgcolor="#E7E7E7">
                        <td height="24" colspan="12" background="skin/images/tbg.gif">&nbsp;发件箱&nbsp;</td>
                    </tr>
                    <tr align="center" bgcolor="#FAFAF1" height="22" id="tr2">
                        <td width="4%">选择</td>
                        <td width="6%">序号</td>
                        <td width="10%">标题</td>
                        <td width="10%">内容</td>
                        <td width="8%">发送时间</td>
                        <td width="8%">操作</td>
                    </tr>
    
                    <tr id="focus-tr"></tr>
                    
                    <%--<tr align='center' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22" >
        <td><input name="id" type="checkbox" id="id" value="101" class="np"></td>
            <td>1</td>
            <td>项目完成的咋样?</td>
            <td align="center"><span >最近工作累不?项目完成的咋样?加油哈</span></td>
            <td>2015-02-03</td>
            <td><a >删除</a></td>
            </tr>--%>
    
    
                    <tr bgcolor="#FAFAF1">
                        <td height="28" colspan="12">
                            &nbsp;
                            <a href="" class="coolbg">全选</a>
                            <a href="" class="coolbg">反选</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                            <a href="" class="coolbg">&nbsp;删除&nbsp;</a>
                            <a href="" class="coolbg">&nbsp;导出Excel&nbsp;</a>
                        </td>
                    </tr>
                    <tr align="right" bgcolor="#EEF4EA">
                        <td height="36" colspan="12" align="center"><!--翻页代码 --></td>
                    </tr>
                </table>
    
            </form>
        </body>
    </html>
    
  3. controller层

    package com.anzhi.dailyOffice.controller;
    
    import com.anzhi.dailyOffice.bean.Notice;
    import com.anzhi.dailyOffice.bean.NoticeExample;
    import com.anzhi.dailyOffice.service.NoticeService;
    import com.anzhi.utils.ResultEntity;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.Date;
    import java.util.List;
    
    @Controller
    @RequestMapping(value = "/notice")
    public class NoticeController {
    
        @Autowired
        NoticeService noticeService;
    
        @RequestMapping(value = "/saveInfo", method = RequestMethod.POST)
        @ResponseBody
        public ResultEntity saveInfo(Notice notice){
            noticeService.saveInfo(notice);
            return ResultEntity.success();
        }
    
        @RequestMapping(value = "/jsonList", method = RequestMethod.GET)
        @ResponseBody
        public ResultEntity getJsonList(NoticeExample notice){
            List<Notice> noticeList = noticeService.getJsonList(notice);
            return ResultEntity.success().put("noticeList", noticeList);
        }
    }
    
  4. service层

    package com.anzhi.dailyOffice.service.Impl;
    
    
    import com.anzhi.dailyOffice.bean.Notice;
    import com.anzhi.dailyOffice.bean.NoticeExample;
    import com.anzhi.dailyOffice.mapper.NoticeMapper;
    import com.anzhi.dailyOffice.service.NoticeService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.Date;
    import java.util.List;
    
    @Service
    public class NoticeServiceImpl implements NoticeService {
        @Autowired
        NoticeMapper noticeMapper;
    
        @Override
        public void saveInfo(Notice notice) {
            notice.setNdate(new Date());
            noticeMapper.insert(notice);
        }
    
        @Override
        public List<Notice> getJsonList(NoticeExample notice) {
            return noticeMapper.selectByExample(notice);
        }
    }
    
  5. 分页功能:采用异步的方式进行

    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/moment.min.js"></script>
    

controller层

```java
@RequestMapping(value = "/jsonList", method = RequestMethod.GET)
@ResponseBody
public ResultEntity getJsonList(HttpServletRequest request, @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum){
    Map<String, Object> parametMap = WebUtils.getParametersStartingWith(request,"search_");
    String querstr = ParseparameterMapToString.parseparameterMapToString(parametMap);
    String requestURI = request.getRequestURI();

    PageInfo<Notice> page = noticeService.getJsonList(pageNum,parametMap);

    return ResultEntity.success().put("page", page).put("querstr",querstr).put("requestURI",requestURI);
}

service层

@Override
public PageInfo<Notice> getJsonList(Integer pageNum, Map<String,Object> parametMap){
    NoticeExample noticeExample = new NoticeExample();
    NoticeExample.Criteria criteria = noticeExample.createCriteria();

    //合并查询语句,这里需要注意的是状态查询是精确查询,关键字查询是模糊查询,所以我们可以先解析判断,
    //最后将结果封装为一个Map,在返回查询
    Map<String,String> mybatisMap = ParseparameterMapToString.parseParameterMapToMybatisMap(parametMap);
    PageHelper.startPage(pageNum,3);
    List<Notice> notices = noticeMapper.selectByExample(noticeExample);
    //包装,并设置导航页5
    PageInfo<Notice> pages = new PageInfo<Notice>(notices,5);

    return pages;
}

未完成功能:

  1. 查询,以及最下面页面显示不突出显示
  2. 解决思路:
    1. 对页数进行判断,然后突显??
    2. 查询与前面类似,后续完成

问题:

  1. 在分页导航中每页显示3条数据的时候,9条数据只显示了6条,当分页导航为10,每页数据显示为10的时候,9条数据显示正常

  2. 解决:

    <script>
        $(function(){
            $.ajax({
                type:'GET',
                url:'${pageContext.request.contextPath}/notice/jsonList',
                success:function(msg){
                    if(msg.map.statusCode==200){
                        //1.遍历数据
                        $(msg.map.page.list).each(function (index,item) {
                            var tr = "<tr name='appendtr' align='center' bgcolor='#FFFFFF' onMouseMove='javascript:this.bgColor='#FCFDEE';' onMouseOut='javascript:this.bgColor='#FFFFFF';' height='22' >"
                            +"<td><input name='id' type='checkbox' id='id' value='"+item.nid+"' class='np'></td>"
                            +"<td>"+((msg.map.page.pageNum-1)*msg.map.page.pageSize+(index+1))+"</td>"
                            +"<td>"+item.ntitle+"</td>"
                            +"<td align='center'><span >"+item.remark+"</span></td>"
                            +"<td>"+moment(item.ndate).format('YYYY-MM-DD')+"</td>"
                            +"<td><a >删除</a>|<a >编辑</a></td>"
                            +"</tr>"
                            $("#tr").before(tr);
                        })
                        //2. 分页
                        var div = "<div id='appendDiv'> </div>";
                        var firstPage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum=1"+msg.map.querstr+"'>首页</a>  &nbsp";
                        var prePage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+(msg.map.page.pageNum-1)+msg.map.querstr+"'>上一页</a>  &nbsp";
                        var nextPage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+(msg.map.page.pageNum+1)+msg.map.querstr+"'>下一页</a> &nbsp";
                        var endPage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+msg.map.page.pages+msg.map.querstr+"'>末页</a> &nbsp";
    
                        var pageslist="";
                        $(msg.map.page.navigatepageNums).each(function (index, item) {
                            pageslist = pageslist+"&nbsp; <a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+item+msg.map.querstr+"'>第"+item+"页</a> &nbsp";
                        })
                        $(div).append(firstPage).append(prePage).append(pageslist).append(nextPage).append(endPage).appendTo($("#page-td"));
    
                    }
                },
                error:function(){
                    alert("网页异常");
                }
            });
        });
    
        //再次显示的时候,将点击的页链接再次显示,同时移除原有链接(在前面下拉框中的重复显示可以移除在显示,没试过,我直接改为onclick然后清除)
        function findList(fmt) {
            $.ajax({
                type:'GET',
                url:fmt,
                success:function(msg){
                    if(msg.map.statusCode==200){
                        //添加name属性,清空原有的tr保证每次数据不是直接在页面后追加
                        $("tr[name=appendtr]").remove();
                        $("#appendDiv").remove();
                        //1.遍历数据
                        $(msg.map.page.list).each(function (index,item) {
                            var tr = "<tr name='appendtr' align='center' bgcolor='#FFFFFF' onMouseMove='javascript:this.bgColor='#FCFDEE';' onMouseOut='javascript:this.bgColor='#FFFFFF';' height='22' >"
                            +"<td><input name='id' type='checkbox' id='id' value='"+item.nid+"' class='np'></td>"
                            +"<td>"+((msg.map.page.pageNum-1)*msg.map.page.pageSize+(index+1))+"</td>"
                            +"<td>"+item.ntitle+"</td>"
                            +"<td align='center'><span >"+item.remark+"</span></td>"
                            +"<td>"+moment(item.ndate).format('YYYY-MM-DD')+"</td>"
                            +"<td><a >删除</a>|<a >编辑</a></td>"
                            +"</tr>"
                            $("#tr").before(tr);
                        });
                        //2. 分页
                        var div = "<div id='appendDiv'> </div>";
                        var firstPage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum=1"+msg.map.querstr+"'>首页</a>  &nbsp";
                        var prePage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+(msg.map.page.pageNum-1)+msg.map.querstr+"'>上一页</a>  &nbsp";
                        var nextPage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+(msg.map.page.pageNum+1)+msg.map.querstr+"'>下一页</a> &nbsp";
                        var endPage = "<a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+msg.map.page.pages+msg.map.querstr+"'>末页</a> &nbsp";
    
                        var pageslist="";
                        $(msg.map.page.navigatepageNums).each(function (index, item) {
                            pageslist = pageslist+"&nbsp; <a οnclick='findList(this.name)' href='javascript:void(0)' name='"+msg.map.requestURI+"?pageNum="+item+msg.map.querstr+"'>第"+item+"页</a> &nbsp";
                        });
                        $(div).append(firstPage).append(prePage).append(pageslist).append(nextPage).append(endPage).appendTo($("#page-td"));
    
                    }
                },
                error:function(){
                    alert("网页异常");
                }
            });
    
            return false;
        }
    </script>
    
1. 显示遮罩和弹窗

使用异步请求显示公告,显示最新的三条数据

main.jsp

<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/moment.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
<script type="text/javascript">
    $(function () {
        $.ajax({
            type:"GET",
            url:"${pageContext.request.contextPath}/notice/getNewNotice",
            success:function (msg) {
                if(msg.map.statusCode==200){
                    $(msg.map.noticeList).each(function (index,item) {
                        var li = "<li class='ue-clear'>"
                        +"<span>"+moment(item.ndate).format("YYYY-MM-DD")+"</span>&nbsp;&nbsp;&nbsp;<a  οnclick='showWindow("+item.nid+")' href='#'class='notice-title'>"+item.ntitle+"</a>"
                        +"</li><p>"

                        $("#notice-list").append(li);
                    })
                }
            }
        });
    });
    function showWindow(nid) {
        $.ajax({
            type:"GET",
            url:"${pageContext.request.contextPath}/notice/info/"+nid,
            success:function (msg) {
                $("#ntitle").text(msg.ntitle).css({"font-size":"20px"});
                $("#content").text(msg.remark).css({"font-size":"15px"});
                $("#showdiv").show();
                $("#cover").css({"height":document.body.scrollHeight+"px"});
                $("#cover").show();
            }
        })
    }
    function closeWindow() {
        $("#showdiv").css({"display":"none"});
        $("#cover").css({"display":"none"});
    }
</script>

controller层

@RequestMapping(value = "/getNewNotice", method = RequestMethod.GET)
@ResponseBody
public ResultEntity getNewNoticeList(NoticeExample noticeExample){
    List<Notice> noticeList = noticeService.getNewNoticeList(noticeExample);
    return ResultEntity.success().put("noticeList",noticeList);
}

@RequestMapping(value = "/info/{nid}", method = RequestMethod.GET)
@ResponseBody
public Notice getNewNoticeInfo(@PathVariable("nid")Integer nid){
    Notice notice = noticeService.getNewNoticeInfo(nid);
    return notice;
}

service层

@Override
public List<Notice> getNewNoticeList(NoticeExample noticeExample) {
    noticeExample.setOrderByClause("ndate desc limit 3");
    List<Notice> noticeList =  noticeMapper.selectByExample(noticeExample);
    return noticeList;
}

@Override
public Notice getNewNoticeInfo(Integer nid) {
    return noticeMapper.selectByPrimaryKey(nid);
}

5. 档案管理(后面有时间再做吧)

  1. 修改menu.jsp页面,使档案管理跳转到档案管理的页面。档案管理页面在课程资料中
  2. 导入excel解析,然后在查看详情的页面需要联表查询,传入对应的id查询,然后做保存

6. 定时任务

  1. 应用场景:比如对于长期不使用我们平台的客户,就很意味着这个客户很可能丢失了,然后对其作出标记。可以采取对相应的客户采取挽回措施。

  2. 定时任务框架Quartz:定时发送邮件的task(Job),重启机器的task(Job),优惠券到期发送短信提醒的task(Job)

    1. 导jar包

      pom.xml

      <!--定时框架-->
      <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
      <dependency>
          <groupId>org.quartz-scheduler</groupId>
          <artifactId>quartz</artifactId>
          <version>2.3.0</version>
      </dependency>
      
      
    2. beans-quartz.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">
      
          <!--1. 配置job作业,指定作业的对象-->
          <bean id="logPrinter" class="com.anzhi.jobs.LogPrinter"></bean>
          <!--2. JobDetail对象,对象、对象的方法-->
          <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
              <property name="targetObject" ref="logPrinter"/>
              <property name="targetMethod" value="printLog"/>
          </bean>
          <!--3.触发器-->
          <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
              <property name="jobDetail" ref="jobDetail"/>
              <property name="startDelay" value="10000"/>
              <property name="repeatInterval" value="5000"/>
          </bean>
      
          <!--4.配置scheduler容器-->
          <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
              <property name="triggers">
                  <list>
                      <ref bean="simpleTrigger"/>
                  </list>
              </property>
          </bean>
      </beans>
      
    3. 测试

      package com.anzhi.test.controller;
      
      
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class Quartz {
          public static void main(String[] args) {
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans-quartz.xml");
          }
      }
      
    4. 石英表达式

      <!--3.2石英触发器-->
      <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
          <property name="jobDetail" ref="jobDetail"/>
          <property name="cronExpression" value="0/5 * * * * ?"/>
      </bean>
      
      

      写法:

      Cron表达式
      由6或7个由空格分隔的时间字段组成
      5/10 2/15 3-4 * * MON,WED,FRI *
      
      位置时间域名允许值允许的特殊字符
      10-59, - * /
      2分钟0-59, - * /
      3小时0-23, - * /
      4日期1-31, - * ? / L W C
      5月份1-12, - * /
      6星期1-7, - * ? / L C #
      7年(可选)空值1970-2099, - * /

      星号(*):可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”;

      ●问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符;

      ●减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12;

      ●逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;

      ●斜杠(/):x/y表达一个等步长序列,x为起始值,y为增量步长值。如在秒字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;

      ●L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的 31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后 X天”,例如,6L表示该月的最后星期五;

      ●W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星 期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨 月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围;

      ●LW组合:在日期字段可以组合使用LW,它的意思是当月的最后一个工作日;

      ●井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;

      ● C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。

      表示式说明
      "0 0 12 * * ? "
      “0 15 10 ? * *”每天10:15运行
      “0 15 10 * * ?”每天10:15运行
      “0 15 10 * * ? *”每天10:15运行
      “0 15 10 * * ? 2008”在2008年的每天10:15运行
      “0 * 14 * * ?”每天14点到15点之间每分钟运行一次,开始于14:00,结束于14:59。
      “0 0/5 14 * * ?” 0/5 * 9 * * *每天14点到15点每5分钟运行一次,开始于14:00,结束于14:55。
      “0 0/5 14,18 * * ?”每天14点到15点每5分钟运行一次,此外每天18点到19点每5钟也运行一次。
      “0 0-5 14 * * ?”每天14:00点到14:05,每分钟运行一次。
      “0 10,44 14 ? 3 WED”3月每周三的14:10分到14:44,每分钟运行一次。
      “0 15 10 ? * MON-FRI”每周一,二,三,四,五的10:15分运行。
      “0 15 10 15 * ?”每月15日10:15分运行。
      “0 15 10 L * ?”每月最后一天10:15分运行。
      “0 15 10 ? * 6L”每月最后一个星期五10:15分运行。
      “0 15 10 ? * 6L 2007-2009”在2007,2008,2009年每个月的最后一个星期五的10:15分运行。
      “0 15 10 ? * 6#3”每月第三个星期五的10:15分运行。

7. 发帖功能

3. 信息箱-》msg:同上

1. 发送邮件

  1. 邮件框架的使用

    配置jar包

    <!--发送邮件框架-->
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
    
  2. 配置spring整合email

    <?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">
    
        <!-- Spring提供的发送电子邮件的高级抽象类 -->
        <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <!-- 邮件smtp服务器地址 -->
            <property name="host" value="smtp.qq.com" />
            <!-- 发件人邮箱用户名 -->
            <property name="username" value="2550364626@qq.com" />
            <!-- 邮箱密码:不是邮箱密码,而是邮箱的授权码, 自己开一下 -->
            <property name="password" value="*****************" />
            <!-- 编码格式 -->
            <property name="defaultEncoding" value="UTF-8"/>
            <!-- 邮箱服务器属性设置 -->
            <property name="javaMailProperties">
                <props>
                    <!-- 邮箱服务器是否支持验证 -->
                    <prop key="mail.smtp.auth">true</prop>
                    <!-- 邮箱服务器连接超时时间  毫秒-->
                    <prop key="mail.smtp.timeout">300000</prop>
                </props>
            </property>
        </bean>
    
    </beans>
    
  3. 测试

    import org.junit.Test;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.JavaMailSenderImpl;
    import org.springframework.mail.javamail.MimeMessageHelper;
    
    import javax.mail.internet.MimeMessage;
    
    public class EmailTes {
    
        @Test
        public void testEmail() throws Exception{
            //获取容器对象
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans-email.xml");
            //从容器中获取JavaMailSenderImpl对象
            JavaMailSenderImpl bean = context.getBean(JavaMailSenderImpl.class);
            //创建邮件队象
            MimeMessage mimeMessage = bean.createMimeMessage();
            //使用MimeMessageHelper对MimeMessage对象封装
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
            //通过helper设置
            mimeMessageHelper.setFrom("2550364626@qq.com");
    
            //发送邮件
            mimeMessageHelper.setTo("2475891850@qq.com");
            mimeMessageHelper.setSubject("anzhi 的测试");
            mimeMessageHelper.setText("测试一波,打扰了");
    
            bean.send(mimeMessage);
            System.out.println("Email PASS");
        }
    }
    

2. 项目应用

定时发送邮件

message-seed.jsp

<%@ page language="java"  pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>发信息</title>
        <base src="${pageContext.request.contextPath}/">
        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/moment.min.js"></script>
        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
        <script type="text/javascript">
            $(function () {
                $.ajax({
                    type:"GET",
                    url:"${pageContext.request.contextPath}/msg/msgList",
                    success:function (msg) {
                        $(msg).each(function (index,item) {
                            var option = "<option value='"+item.archives.email+"'>"+item.ename+"</option>";
                            $("#others").append(option);
                        })
                    }
                });
            });
            function commit() {
                $("#form2").submit();
            }
        </script>
        <link rel="stylesheet" type="text/css" href="skin/css/base.css">
    </head>
    <body leftmargin="8" topmargin="8" background='skin/images/allbg.gif'>

        <!--  快速转换位置按钮  -->
        <table width="98%" border="0" cellpadding="0" cellspacing="1" bgcolor="#D1DDAA" align="center">
            <tr>
                <td height="26" background="skin/images/newlinebg3.gif">
                    <table width="58%" border="0" cellspacing="0" cellpadding="0">
                        <tr>
                            <td >
                                当前位置:信息箱>>发信息
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>

        <form name="form2" id="form2" action="${pageContext.request.contextPath}/email/saveInfo" method="post">

            <table width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
                <tr bgcolor="#E7E7E7">
                    <td height="24" colspan="2" background="skin/images/tbg.gif">&nbsp;发信息&nbsp;</td>
                </tr>
                <tr >
                    <td align="right" bgcolor="#FAFAF1" height="22">收件人:</td>
                    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
                        <select id="others" name="ename">
                            <option value="1">请选择联系人...</option>
                        </select>
                    </td>
                </tr>
                <tr >
                    <td align="right" bgcolor="#FAFAF1" height="22">标题:</td>
                    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
                        <input name="title"/>
                    </td>
                </tr>

                <tr >
                    <td align="right" bgcolor="#FAFAF1" height="22">发送时间:</td>
                    <td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
                        <input type="text" name="sendtime"/>
                    </td>
                </tr>

                <tr >
                    <td align="right" bgcolor="#FAFAF1" height="22">内容:</td>
                    <td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
                        <textarea rows=15 cols=130 name="content"></textarea>
                    </td>
                </tr>


                <tr bgcolor="#FAFAF1">
                    <td height="28" colspan=4 align=center>
                        &nbsp;
                        <a href="javascript:commit()" class="coolbg">保存</a>
                    </td>
                </tr>
            </table>

        </form>


    </body>
</html>

查询数据库中可以发送邮件的员工,通过session获取id不是本人的员工,且邮箱不为空的员工,所以需要自定义查询语句

EmployeeMapper.xml

<!--映射表-->
<resultMap id="getOthersResultMap" type="com.anzhi.sysmanage.bean.Employee">
    <id column="eid" property="eid"></id>
    <result column="ename" property="ename"></result>
    <result column="email" property="archives.email"></result>
</resultMap>
<select id="getOthers" resultMap="getOthersResultMap">
    SELECT e.eid, e.ename, a.email
    FROM employee e LEFT JOIN archives a
    on e.eid = a.emp_fk where e.eid !=#{msgid} and a.email is not null;
</select>

EmployeeMapper.java

List<Employee> getOthers(Integer msgid);

将定时配置与spring整合

beans.xml

<!--发送邮件配置引入-->
<import resource="beans-email.xml"></import>
<!--定时配置无法引入,因为是我们自己设定时间,所以不能引入时间配置-->

controller层

package com.anzhi.msg.controller;

import com.anzhi.msg.service.MessageService;
import com.anzhi.sysmanage.bean.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.List;

@Controller
@RequestMapping(value = "/msg")
public class MessageController {

    @Autowired
    MessageService messageService;

    @RequestMapping(value = "/msgList", method = RequestMethod.GET)
    @ResponseBody
    public List<Employee> getOthers(HttpSession session){
        Employee employee = (Employee)session.getAttribute("loginUser");
        Integer msgid = employee.getEid();
        List<Employee> employees = messageService.getOthers(msgid);
        return employees;
    }
}



package com.anzhi.msg.controller;

import com.anzhi.jobs.EmailJob;
import com.anzhi.msg.bean.Email;
import com.anzhi.msg.service.EmailService;
import com.anzhi.sysmanage.bean.Employee;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpSession;
import java.util.Date;

@Controller
@RequestMapping(value = "/email")
public class EmailController {

    @Autowired
    private JavaMailSenderImpl javaMailSender;  //将email对象传入

    @Autowired
    private EmailService emailService;

    @RequestMapping(value = "/saveInfo", method = RequestMethod.POST)
    public String saveInfo(Email email, HttpSession session) throws Exception{
        System.out.println(email);
        //创建JobDetail对象,其中EmailJob必须实现了Job接口
        JobDetail job = JobBuilder.newJob(EmailJob.class).build();

        //将email对象传入
        JobDataMap jobDataMap = job.getJobDataMap();
        jobDataMap.put("email", email);
        jobDataMap.put("javaMailSenderImpl", javaMailSender);

        //创建SimpleTrigger对象,指定对象名称、组名  设置任务重复执行间隔时间,重复执行次数 启动时间
        SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().startAt(new Date()).build();
        //创建任务管理器Scheduler对象
        Scheduler sched= StdSchedulerFactory.getDefaultScheduler();
        jobDataMap.put("scheduler",sched);
        //为Scheduler对象新增JOB以及对应的SimpleTrigger

        sched.scheduleJob(job, trigger);
        //启动定时任务管理器
        sched.start();
        //关闭定时任务管理器
        //sched.shutdown(true);

       //在发送邮件的同时保存邮件
        Employee employee = (Employee) session.getAttribute("loginUser");
        Integer eid = employee.getEid();
        email.setEmpFk(eid);
        emailService.saveInfo(email);

        return "redirect:/message.jsp";
    }
}

EmailJob.java

package com.anzhi.jobs;

import com.anzhi.msg.bean.Email;
import org.quartz.*;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.internet.MimeMessage;
import java.io.File;

public class EmailJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //获取Controller层传入的参数
        JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap();
        Email email = (Email)dataMap.get("email");
        JavaMailSenderImpl javaMailSender = (JavaMailSenderImpl)dataMap.get("javaMailSenderImpl");
        Scheduler sched = (Scheduler)dataMap.get("scheduler");

        try{
            //获取容器对象
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans-email.xml");
            //从容器中获取JavaMailSenderImpl对象
            JavaMailSenderImpl bean = context.getBean(JavaMailSenderImpl.class);
            //创建邮件队象
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            //使用MimeMessageHelper对MimeMessage对象封装 添加附件发送
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
            //通过helper设置
            mimeMessageHelper.setFrom("2550364626@qq.com");

            //发送邮件
            mimeMessageHelper.setTo(email.getEname());
            mimeMessageHelper.setSubject(email.getTitle());
            mimeMessageHelper.setText(email.getContent());

            javaMailSender.send(mimeMessage);
            System.out.println("Email PASS");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                sched.shutdown(true);
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }

    }
}

如果要发送附件,需要将附件路径存储到email中,并存入jobDataMap.put(“attachement”,file);然后再定时任务中取出,通过email相应的方法发送。

剩余查询显示后面再做。

3. 技术拓展(图片展示)

  1. Echarts:下载并引用echarts.jsp

  2. spring与echarts整合

  3. echarts.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>echarts</title>
        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/echarts.js"></script>
        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    </head>
    <body>
        <div id="main" style="width: 600px;height: 400px;"></div>
    </body>
    
    <script type="text/javascript">
        window.οnlοad=function () {
            var  names=[];
            var values=[];
            $.ajax({
                type:"GET",
                url:"${pageContext.request.contextPath}/echart/getData",
                success:function (msg) {
                    for (key in msg) {
                        names.push(key);
                        values.push(msg[key]);
                    }
    		
                    /*异步的时候,需要在请求的时候就取值展示即放到回调函数success中,会产生还没取到到值就展示的现象*/
                    var chart = echarts.init(document.getElementById("main"));
                    var option = {
                        title:{
                            text:'ECharts 入门示例'
                        },
                        xAxis:{
                            data:names
                        },
                        yAxis:{},
                        series:[{
                            name:'销量',
                            type:'bar',
                            data:values
                        }]
    
                    };
                    chart.setOption(option);
                }
            })
        }
    
    </script>
    </html>
    
    

    controller层

    package com.anzhi.projectmanage.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Controller
    @RequestMapping(value = "/echart")
    public class EchartController {
    
        @RequestMapping(value = "/getData", method = RequestMethod.GET)
        @ResponseBody
        public Map<String, Object> getDatas(){
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("衬衫",5);
            map.put("羊毛衫",20);
            map.put("雪纺衫",36);
            map.put("裤子",10);
    
            return map;
        }
    
    }
    

4. 富文本编辑器

  1. 下载ueditor

  2. 练习:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>ueditor</title>
        <script type="text/javascript" charset="utf-8" src="${pageContext.request.contextPath}/static/js/utf8-jsp/ueditor.config.js"></script>
        <script type="text/javascript" charset="utf-8" src="${pageContext.request.contextPath}/static/js/utf8-jsp/ueditor.all.min.js"> </script>
        <!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败-->
        <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文-->
        <script type="text/javascript" charset="utf-8" src="${pageContext.request.contextPath}/static/js/utf8-jsp/lang/zh-cn/zh-cn.js"></script>
    </head>
    <body>
     <script id="editor" type="text/plain" style="width:1024px;height:500px;"></script>
    
     <script type="text/javascript">
        //实例化编辑器
        //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例
        var ue = UE.getEditor('editor');
     </script>
    </body>
    </html>
    

4. 客户信息管理-》customermanage;同上

1.添加客户:

  1. 将target中与客户对应文件拷到工程中对应的目录下

  2. 完成添加客户的功能:

    修改customeradd.js

    //可以直接作为整个页面资源的路径,不用每个都添加
    <base href="${pageContext.request.contextPath}/">
    
    /*导入jquery包*/
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
        function commit() {
            $("#form2").submit();
        }
    </script>
    /*提交表单*/
    <a href="javascript:commit()" class="coolbg">保存</a>   
    /*表单每行属性要与数据库列名对应*/
    <form id="form2" name="form2" action="${pageContext.request.contextPath}/cust/saveInfo" method="post">
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司名称:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name="comname"/></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司联系人:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name="companyperson"/></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司地址:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input size="60" name="comaddress"/></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">联系电话:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name="comphone"/></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">座机:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name="camera"/></td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司简介:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<textarea rows=15 cols=130 name="present"></textarea></td>
    </tr>
    
    <tr >
    	<td align="right" bgcolor="#FAFAF1" >备注:</td>
    <td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    		<textarea rows=10 cols=130 name="remark"></textarea>
    </td>
    </tr>    
    
  3. controller层

    CustomermanageController.java
        package com.anzhi.custormermanage.controller;
    
    import com.anzhi.custormermanage.bean.Customer;
    import com.anzhi.custormermanage.service.CustomermanageService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.stereotype.Service;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.Date;
    
    @Controller
    @RequestMapping(value = "/cust")
    public class CustomermanageController {
    
        @Autowired
        CustomermanageService customermanageService;
        @RequestMapping(value = "/saveInfo", method = RequestMethod.POST)
        public String saveInfo(Customer customer){
            System.out.println("---------调用---------------");
            customer.setAddtime(new Date());
            System.out.println(customer);
            customermanageService.saveInfo(customer);
            return "redirect:/customer.jsp";
        }
    }
    
  4. Service层

    CustomermanageService.java   
    package com.anzhi.custormermanage.service;
       
       import com.anzhi.custormermanage.bean.Customer;
       
       public interface CustomermanageService {
           void saveInfo(Customer customer);
       }
       
       package com.anzhi.custormermanage.service.Impl;
       
       import com.anzhi.custormermanage.bean.Customer;
       import com.anzhi.custormermanage.mapper.CustomerMapper;
       import com.anzhi.custormermanage.service.CustomermanageService;
       import org.springframework.beans.factory.annotation.Autowired;
       import org.springframework.stereotype.Service;
       
       @Service
       public class CustomermanagerServiceImpl implements CustomermanageService {
           @Autowired
           CustomerMapper customerMapper;
       
           public void saveInfo(Customer customer) {
               int i = customerMapper.insert(customer);
               System.out.println(i);
           }
       }
    

2. 回显查询

  1. 修改customer.jsp

    /*路径更改为绝对路径,否则访问customer-add.jsp出错。这是因为转发, customer-add.jsp路径资源问题,更改为绝对路径*/
    <input type='button' class="coolbg np" onClick="location='${pageContext.request.contextPath}/customer-add.jsp';" value='添加客户信息' />
    
    /*同样路径问题,更改为绝对路径*/
    &nbsp;&nbsp;&nbsp;<input name="imageField" type="image" src="${pageContext.request.contextPath}/skin/images/frame/search.gif" width="45" height="20" border="0" class="np" />
    
    /*遍历元素,将内容回显给网页,customers属性要与controller层中的属性对应*/
    <c:forEach items="${customers}" var="customer" varStatus="index">
        <tr align='center' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22" >
            <td><input name="id" type="checkbox" id="id" value="${customer.id}" class="np"></td>
            <td>${index.count}</td>
            <td>${customer.companyperson}</td>
            <td align="center">${customer.comname}</td>
            <td>
                /*日期格式*/
                <fmt:formatDate value="${customer.addtime}" pattern="yyyy-MM-dd"></fmt:formatDate>
            </td>
            <td>${customer.comphone}</td>
            <td><a href="customer-edit.jsp">编辑</a> | <a href="customer-look.jsp">查看详情</a></td>
        </tr>
    </c:forEach>
    
  2. 修改customer-add.jsp

    /*返回功能,有很多种,使用js实现*/
    <a href="javascript:history.go(-1)" class="coolbg">返回</a>
    
  3. Controller层

    CustomermanageController.java

    @RequestMapping(value = "/getLists", method = RequestMethod.GET)
    public ModelAndView getLists(CustomerExample customerExample){
        List<Customer> customers = customermanageService.getLists(customerExample);
        //指定页面展示
        ModelAndView mv = new ModelAndView("customer");
        //这里的属性要与上述的属性对应
        mv.addObject("customers", customers);
        return mv;
    }
    
  4. Service层

    public List<Customer> getLists(CustomerExample customerExample) {
        //查询
        return customerMapper.selectByExample(customerExample);
    }
    

3. 查看详细信息

  1. 修改customer.jsp

    <td><a href="customer-edit.jsp">编辑</a> | <a 
            /*点击查看客户信息需要将每个客户的id传给后台,通过id查询*/                                 
    	href="${pageContext.request.contextPath}/cust/details/${customer.id}">查看详情</a></td>
    
  2. 修改customer-look.jsp

    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22" >公司名称:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		${customer.comname}
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司联系人:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		${customer.companyperson}
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司地址:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		${customer.comaddress}
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">联系电话:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		${customer.comphone}
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">座机:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		${customer.camera}
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司简介:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22"><p>
    		${customer.present}
    	</p></td>
    </tr>
    
    <tr >
    	<td align="right" bgcolor="#FAFAF1" >备注:</td>
    	<td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    		${customer.remark}
    	</td>
    </tr>
    
    ……
    	/*返回显示*/
    	<a href="javascript:history.go(-1)" class="coolbg">返回</a>
    
  3. controller层

    @RequestMapping(value = "/details/{cid}",method = RequestMethod.GET)
    //获取到网页的id传给后台查询
    public String getCustomerDetailes(@PathVariable("cid") Integer cid, Map<String, Object> map){
        Customer customer = customermanageService.getCustomerDetailes(cid);
        //        可以使用ModelAndView回显给页面
        //        ModelAndView mv = new ModelAndView("customer-look");
        //        mv.addObject("customer", customer);
        //使用map将元素回显给页面展示
        map.put("customer", customer);
        return "customer-look";
    }
    
  4. service层

    CustomermanageService.java
    	Customer getCustomerDetailes(Integer cid);
    CustomermanagerServiceImpl.java
    	public Customer getCustomerDetailes(Integer cid){
           		 return customerMapper.selectByPrimaryKey(cid);
      	  }
    

4. 编辑客户

  1. 修改customer-edit.jsp

    /*添加jquery,定义提交表达函数*/
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
    	function commit() {
    		$("form2").submit();
        }
    </script>
    
    <form id="form2" name="form2" action="${pageContext.request.contextPath}/cust/updateCustomer" method="post">
        /*传递id参数,根据客户id修改客户信息,隐藏id(即页面不显示)传递*/
    <input type="hidden" name="id" value="${customer.id}">
    <input type="hidden" name="_method" value="put">
    <table width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
    <tr bgcolor="#E7E7E7">
    	<td height="24" colspan="2" background="skin/images/tbg.gif">&nbsp;编辑客户信息&nbsp;</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22" >公司名称:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name = "comname" value="${customer.comname}"/>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司联系人:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name = "companyperson" value="${customer.companyperson}"/>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司地址:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input size="60" name  = "comaddress" value="${customer.comaddress}"/>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">联系电话:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name = "comphone" value="${customer.comphone}"/>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">座机:</td>
    	<td  align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<input name = "camera" value="${customer.camera}"/>
    	</td>
    </tr>
    <tr >
    	<td align="right" bgcolor="#FAFAF1" height="22">公司简介:</td>
    	<td align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" height="22">
    		<textarea rows=15 cols=130 name="present">${customer.present}</textarea>
    	</td>
    </tr>
    
    <tr >
    	<td align="right" bgcolor="#FAFAF1" >备注:</td>
    	<td colspan=3 align='left' bgcolor="#FFFFFF" onMouseMove="javascript:this.bgColor='#FCFDEE';" onMouseOut="javascript:this.bgColor='#FFFFFF';" >
    		<textarea rows=10 cols=130 name="remark">${customer.remark}</textarea>
    	</td>
    </tr>
    
    
    <tr bgcolor="#FAFAF1">
    <td height="28" colspan=4 align=center>
    	&nbsp;
    	<a href="javascript:commit()" class="coolbg">保存</a>
    	<a href="javascript:history.go(-1)" class="coolbg">返回</a>
    </td>
    
    
  2. 修改customer.jsp

     /*编辑访问类似于查看详情*/      
    <td><a href="${pageContext.request.contextPath}/cust/edit/${customer.id}">编辑</a> | <a href="${pageContext.request.contextPath}/cust/details/${customer.id}">查看详情</a></td>
    
  3. controller层

    /*使用ModelAndView实现*/
    @RequestMapping(value = "/edit/{cid}", method = RequestMethod.GET)
    public ModelAndView editCustomer(@PathVariable("cid") Integer cid, CustomerExample customerExample){
        ModelAndView mv = new ModelAndView("customer-edit");
        Customer customer = customermanageService.getCustomerDetailes(cid);
        mv.addObject("customer", customer);
        return mv;
    }
    
    /*更新操作*/
    @RequestMapping(value = "/updateCustomer", method = RequestMethod.PUT)
    public String updateCustomer(Customer customer){
        System.out.println(customer);
        customermanageService.updateCustomer(customer);
        return "redirect:/cust/getLists";
    }
    
    
  4. service层

    CustomermanageService.java
    Integer updateCustomer(Customer customer);
       
    CustomermanagerServiceImpl.java
    public Integer updateCustomer(Customer customer) {
        return customerMapper.updateByPrimaryKeySelective(customer);
    }
    
    

5. 全选和反选

  1. 修改customer.jsp

    //javascript需要每一个元素逐渐赋值
    //jquery:设置一组元素,相当于wie这一组中的每一个元素都设置一遍
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
     function chooseAll() {
            $("#listTable input").attr("checked", "checked");
        }
        function inverse() {
            $("#listTable input").each(function () {
                var checked = $(this).prop("checked");
                $(this).prop("checked", !checked);
            });
        }
    </script>
    
    
    
    //id属性
    <table id="listTable" width="98%" border="0" cellpadding="2" cellspacing="1" bgcolor="#D1DDAA" align="center" style="margin-top:8px">
    
    
    <a href="javascript:chooseAll()" class="coolbg">全选</a>
    <a href="javascript:inverse()" class="coolbg">反选</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    
    

6. 批量删除

  1. customer.jsp

        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
        <script type="text/javascript">
    
            ……
            
            function batchDelete() {
                var ids = [];
                $("#listTable").find("input:checked").each(function () {
                    var cid = $(this).val();
                    ids.push(cid);
                });
                alert(ids);
                $.ajax({
                    type:"POST",
                    url:"${pageContext.request.contextPath}/cust/del",
                    //将ids数组放入数据区传参
                    data: {"_method":"delete", "ids":ids},
                    success:function (msg) {
                        if(msg.statusCode == 200){
                            window.location.href="${pageContext.request.contextPath}/cust/getLists";
                            alert("数据删除成功");
                        }else{
                            window.location.href="${pageContext.request.contextPath}/cust/getLists";
                            alert(msg.message);
                        }
                    },
                    // success在执行成功的情况下进入判断,error在后台服务器异常下执行
                    error:function () {
                        window.location.href="${pageContext.request.contextPath}/cust/getLists";
                        alert("数据删除失败,存在关联数据");
                    }
                });
            }
        </script>
    
    
    ……
    
        <a href="javascript:batchDelete()" class="coolbg">&nbsp;删除&nbsp;</a>
    
    
  2. controller层

    //请求方式为DELETE
    @RequestMapping(value = "/del", method = RequestMethod.DELETE)
    //将结果作为json数据传递给前端
    @ResponseBody
    public Map<String, Object> batchDelete(@RequestParam("ids[]") Integer[] ids){
        System.out.println(ids);
        boolean result = customermanageService.batchDelete(ids);
        Map<String, Object> map = new HashMap<String, Object>();
        if(result){
            map.put("statusCode", 200);
            map.put("message", "删除成功");
        }else{
            map.put("statusCode", 500);
            map.put("message", "删除失败");
        }
        return map;
    }
    
    
  3. service层

    CustomermanagerServiceImpl.java
        
    public boolean batchDelete(Integer[] ids) {
        //讲数组转换为List集合
        List<Integer> list = Arrays.asList(ids);
        CustomerExample example = new CustomerExample();
        //创建sql条件语句
        CustomerExample.Criteria criteria = example.createCriteria();
        criteria.andIdIn(list);
        int result = customerMapper.deleteByExample(example);
        return ids.length == result;
    }
    
    

7. 条件查询

  1. 修改customer.jsp

    <!--  搜索表单  -->
    <form name='form3' action='${pageContext.request.contextPath}/cust/search' method='get'>
    
        <select name='cid' style='width:150px'>
            <option value='0'>选择类型...</option>
            <option value='1'>客户所在公司名称</option>
            <option value='2'>联系人姓名</option>
        </select>
        
        
        <select name='orderby' style='width:120px'>
            	<option value='0'>排序...</option>
            	<option value='1'>逆序</option>
            
            
    // 不用修改,点击搜索,input类型提交表单
    <td>
                &nbsp;&nbsp;&nbsp;<input name="imageField" type="image" src="${pageContext.request.contextPath}/skin/images/frame/search.gif" width="45" height="20" border="0" class="np" />
    </td>
    
    
  2. controller层

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public ModelAndView search(Integer cid, String keyword, Integer orderby){
        List<Customer> customer = customermanageService.search(cid, keyword, orderby);
        ModelAndView mv = new ModelAndView("customer");
        mv.addObject("customers", customer);
        return mv;
    }
    
  3. service层

    CustomermanageService.java
        List<Customer> search(Integer cid, String keyword, Integer orderby);
    
    
    // 根据网页的查询条件,联系人姓名和公司所在名称可以根据主键id确定,keyword关键字,搜索排序orderby
    public List<Customer> search(Integer cid, String keyword, Integer orderby) {
    
        CustomermanagerServiceImpl.java
         public List<Customer> search(Integer cid, String keyword, Integer orderby) {
            CustomerExample example = new CustomerExample();
            CustomerExample.Criteria criteria = example.createCriteria();
            CustomerExample.Criteria companyperson = example.createCriteria();
            //当cid=0;意味着查询可能在公司以及联系人中都有
            if(cid==0){
                criteria.andComnameLike("%"+keyword+"%");
                companyperson.andCompanypersonLike("%"+keyword+"%");
                //查询结果是两种查询结果或的结果
                example.or(companyperson);
            }else if(cid==1){
                // 按照公司所在名称检索
                criteria.andComnameLike("%"+keyword+"%");
            }else if(cid==2){
                // 按照联系人姓名检索,注意这里使用criteria来调用andCompanypersonLike方法构造查询语句,如果companyperson先构造,就使用如果companyperson调用查询(原因学习了再说。)
                criteria.andCompanypersonLike("%"+keyword+"%");
            }
            if(orderby==1){
                example.setOrderByClause("id desc");
            }
            List<Customer> customers = customerMapper.selectByExample(example);
            return customers;
        }
    
    
  4. 配置tomcat插件的编码格式,否则查询结果乱码无法前端显示

    pom.xml

    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <path>/OA</path>
            <port>8080</port>
            <uriEncoding>UTF-8</uriEncoding>
        </configuration>
    </plugin>
    

8. 导出Excel

  1. 导出excel功能

    1. POI

    2. 导入excel需要的依赖包

      <!--POI,excel依赖-->
      <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>3.16</version>
      </dependency>
      
    3. controller层

      @RequestMapping(value = "/exportExcel", method = RequestMethod.GET)
      @ResponseBody
      public Map<String, Object> exportExcel(CustomerExample customerExample){
          System.out.println();
          Workbook workbook = new HSSFWorkbook();
      
          //在表格中创建sheet1表格
          Sheet customerex = workbook.createSheet("customers");
          //时间转换
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      
          //创建行
          Row row = customerex.createRow(0);
          List<Customer> customers = customermanageService.getLists(customerExample);
          Cell[] cell = new HSSFCell[5];
          for(int i=0; i<5; i++){
              cell[i] = row.createCell(i);
          }
      
          cell[0].setCellValue("序号");
          cell[1].setCellValue("联系人");
          cell[2].setCellValue("公司名称");
          cell[3].setCellValue("添加时间");
          cell[4].setCellValue("联系电话");
      
          for(int i=0; i<customers.size(); i++){
              Customer customer = customers.get(i);
              Row row2 = customerex.createRow(i+1);
              Cell[] cell2 = new HSSFCell[5];
              for(int j=0; j<5; j++){
                  cell2[j] = row2.createCell(j);
              }
              cell2[0].setCellValue(customer.getId());
              cell2[1].setCellValue(customer.getCompanyperson());
              cell2[2].setCellValue(customer.getComname());
              Date addtime = customer.getAddtime();
              String addtimeString = sdf.format(addtime);
              cell2[3].setCellValue(addtimeString);
              cell2[4].setCellValue(customer.getComphone());
          }
      
          OutputStream fileout = null;
          try{
              fileout = new FileOutputStream("F:\\customers.xls");  //xls后缀可以打开,xlsx不行,需要使用XSSF来实现
              ((HSSFWorkbook) workbook).write(fileout);
          } catch (IOException e) {
              e.printStackTrace();
          }finally {
              if(fileout != null){
                  try {
                      fileout.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      
          Map<String, Object> map = new HashMap<String, Object>();
          map.put("statusCode", 200);
          map.put("message", "导出成功");
          return map;
      }
      
    4. 前端customer.jsp

      <script>
          function exportExcel() {
              $.ajax({
                  type:"GET",
                  url:"${pageContext.request.contextPath}/cust/exportExcel",
                  success:function (msg) {
                      if(msg.statusCode==200){
                          alert(msg.message);
                      }
                  }
              });
          }
      </script>
      

9. 拓展excel解析

  1. POIReader.java

    package com.yjy.poitest;
    
    import java.io.FileInputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    
    import com.yjy.bean.Hospital;
    
    public class POIReader {
        /*
         * 1:连接数据库
         * 如果数据有10万条左右需要添加上
         * rewriteBatchedStatements=true,mysql默认关闭了batch处理,通过此参数进行打开,
         * 这个参数可以重写向数据库提交的SQL语句。
           useServerPrepStmts=false,如果不开启(useServerPrepStmts=false),
                      使用com.mysql.jdbc.PreparedStatement进行本地SQL拼装,最后送到db上就是已经替换了?后的最终SQL.
         * */
    	static final String url="jdbc:mysql://localhost:3306/test?useServerPrepStmts=false&rewriteBatchedStatements=true";
    	static final String user="root";
    	static final String pass="root";
    	static final String driver="com.mysql.jdbc.Driver";
    	static Connection con = null;
    	public static Connection getCon(){
    		try{
    			Class.forName(driver);
    			con = DriverManager.getConnection(url, user, pass);
    			return con;
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		
    		return con;
    	}
    	
    	public static List readExcel() {
    		/*
    		 * 读取文件中的内容
    		 * */
    		FileInputStream fis = null;
    		List<Hospital> list = new ArrayList<Hospital>();		
    		try{
    			fis = new FileInputStream("E:/hospital.xls"); 
    			//创建新excel文档
    			HSSFWorkbook hssfWorkbook = new HSSFWorkbook(fis);
    			//循环工作表
    			System.out.println(hssfWorkbook.getNumberOfSheets());
    			for(int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++){
    				//获取指定索引的页
    				HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
    				if(hssfSheet == null){
    					continue;
    				}
    				//循环当前页中的具体行
    				for(int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++){
    					//根据索引获取具体的行,第一行为表头所以索引从1开始
    					HSSFRow hssfRow = hssfSheet.getRow(rowNum);
    					if(hssfRow != null){
    						//获取当前行指定索引的列对象					
    						HSSFCell id = hssfRow.getCell(0);
    						HSSFCell jps = hssfRow.getCell(1);
    						HSSFCell province = hssfRow.getCell(2);
    						HSSFCell city = hssfRow.getCell(3);
    						HSSFCell title = hssfRow.getCell(4);
    						HSSFCell buildDate = hssfRow.getCell(5);
    						HSSFCell money = hssfRow.getCell(6);
    						HSSFCell percent = hssfRow.getCell(7);
    						
    						Hospital hp = new Hospital();
    						hp.setId((int)id.getNumericCellValue());
    						hp.setHospitalOn(jps.getStringCellValue());
    						hp.setProvince(province.getStringCellValue());
    						hp.setCity(city.getStringCellValue());
    						hp.setTitle(title.getStringCellValue());
    						hp.setBuildDate(buildDate.getDateCellValue());
    						hp.setMoney(money.getNumericCellValue());
    						hp.setPercent(percent.getNumericCellValue());
    						list.add(hp);						
    					}
    				}				
    			}			
    		}catch(Exception e){
    			e.printStackTrace();
    		}	
    		
    		return list;
    	}
    	
    	public static void main(String[] args) {
    		//获取连接
    		Connection  con= getCon();
    		List<Hospital> list = readExcel();
    		String sql = "insert into hospital(id,hospitalOn,province,city,title,buildDate,money,percent) values(?,?,?,?,?,?,?,?)";
    	    try{
    	    	//开启事务
    	    	con.setAutoCommit(false);
    	    	PreparedStatement ps = con.prepareStatement(sql);
    	    	for(Hospital hp:list){
    	    		ps.setInt(1,hp.getId());
    	    		ps.setString(2,hp.getHospitalOn());
    	    		ps.setString(3,hp.getProvince());
    	    		ps.setString(4,hp.getCity());
    	    		ps.setString(5,hp.getTitle());
    	    		ps.setDate(6,new java.sql.Date(hp.getBuildDate().getTime()));
    	    		ps.setDouble(7,hp.getMoney());
    	    		ps.setDouble(8,hp.getPercent());
    	    		ps.addBatch();
    	    	}
    	    	ps.executeBatch();
    	    	con.commit();
    	    }catch(Exception e){
    	    	e.printStackTrace();
    	    }
    	}
    	
    }
    
  2. POIWrite.java

    package com.yjy.poitest;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFDataFormat;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.HorizontalAlignment;
    
    import com.yjy.bean.Hospital;
    
    public class POIWriter {
        public static void main(String[] args) throws Exception{
            /*
    		 * 构建一组数据
    		 * 
    		 * */   	
            List<Hospital> list = new ArrayList<Hospital>();
            for(int i=0;i<1000;i++){
                Hospital h = new Hospital();
                h.setId(i+1);
                h.setTitle("医疗"+i);
                h.setCity("上海"+i);
                h.setProvince("中国"+i);
                h.setHospitalOn("骨科"+i);
                h.setBuildDate(new java.util.Date());
                h.setMoney(3.456+i);
                h.setPercent(0.01);
                list.add(h);
            }
    
            //创建新excel文档,07版本之前均可以这么写
            HSSFWorkbook workBook = new HSSFWorkbook();
    
            //新建工作表
            HSSFSheet sheet = workBook.createSheet("第一页");  
            //设置单元格的高度
            sheet.setColumnWidth(0, 2500);  
            sheet.setColumnWidth(1, 5000);
    
            //新建行
            HSSFRow row = sheet.createRow(0);  
    
            //第一行中有几个字段
            HSSFCell cell[] = new HSSFCell[8];  
            for(int i = 0; i < cell.length; i++){ 
                //取第一行第一列
                cell[i] = row.createCell(i);  
            } 
            //给第一行所有列赋值
            cell[0].setCellValue("id");  
            cell[1].setCellValue("hospitalOn");  
            cell[2].setCellValue("province");  
            cell[3].setCellValue("city");  
            cell[4].setCellValue("title");  
            cell[5].setCellValue("buildDate");
            cell[6].setCellValue("money");
            cell[7].setCellValue("百分比");
    
            for(int i = 0; i < list.size(); i++){  
                Hospital hospital = list.get(i);  
                HSSFRow dataRow = sheet.createRow(i+1);  
                //创建盛放所有列的数组
                HSSFCell dataCell[] = new HSSFCell[8];  
                for(int j = 0; j < dataCell.length; j++){  	
                    //取得第一行所有列
                    dataCell[j] = dataRow.createCell(j);  
                }  
                dataCell[0].setCellValue(hospital.getId());  
                dataCell[1].setCellValue(hospital.getHospitalOn());  
                dataCell[2].setCellValue(hospital.getProvince());  
                dataCell[3].setCellValue(hospital.getCity());  
                dataCell[4].setCellValue(hospital.getTitle());         
                dataCell[5].setCellValue(hospital.getBuildDate());
                dataCell[6].setCellValue(hospital.getMoney());
                dataCell[7].setCellValue(hospital.getPercent());
                //创建样式
                HSSFCellStyle cellStyle = workBook.createCellStyle();
                //日期
                HSSFDataFormat format= workBook.createDataFormat();
                cellStyle.setDataFormat(format.getFormat("yyyy年MM月dd日"));
                dataCell[5].setCellStyle(cellStyle); 
    
                //小数
                HSSFCellStyle cellStyle1 = workBook.createCellStyle();
                HSSFDataFormat format1= workBook.createDataFormat();
                cellStyle1.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));
                //货币格式
                //cellStyle1.setDataFormat(format1.getFormat("¥#,##0"));
                dataCell[6].setCellStyle(cellStyle1);
    
                //百分比
                HSSFCellStyle cellStyle2 = workBook.createCellStyle();
                HSSFDataFormat format2= workBook.createDataFormat();
                cellStyle2.setDataFormat(format2.getFormat("0%"));
                dataCell[7].setCellStyle(cellStyle2);                                   
            } 
    
            File file = new File("E:\\hospital.xls");  
            FileOutputStream fos = new FileOutputStream(file);  
            workBook.write(fos);  
            fos.close(); 
    
        }
    }
    
    
  3. 上传Excel功能

5. 系统管理-》sysmanage同上

  1. 人员管理分析:

    在这里插入图片描述

  2. ztree树的使用

    1. 引入ztree所需要的js和css样式

    2. 提供一个显示ztree的容器

    3. 初始化ztree

    4. 练习:

      ztree.jsp

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>ztree</title>
          <link rel="stylesheet" href="../../../css/demo.css" type="text/css">
          <link rel="stylesheet" href="${pageContext.request.contextPath}/static/js/ztree/zTreeStyle.css" type="text/css">
          <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.js"></script>
          <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/ztree/jquery.ztree.all-3.5.min.js"></script>
          <script type="text/javascript">
              var setting = {
                  //这里可以给后台发送异步请求
                  async:{
                      enable:true,
                      url:"",
                      type:"get",
                      autoParam:[]
                  }
              };
      
              var zNodes =[
                  { name:"父节点1 - 展开", open:true,
                      children: [
                          { name:"父节点11 - 折叠",
                              children: [
                                  { name:"叶子节点111"},
                                  { name:"叶子节点112"},
                                  { name:"叶子节点113"},
                                  { name:"叶子节点114"}
                              ]},
                          { name:"父节点12 - 折叠",
                              children: [
                                  { name:"叶子节点121"},
                                  { name:"叶子节点122"},
                                  { name:"叶子节点123"},
                                  { name:"叶子节点124"}
                              ]},
                          { name:"父节点13 - 没有子节点", isParent:true}
                      ]},
                  { name:"父节点2 - 折叠",
                      children: [
                          { name:"父节点21 - 展开", open:true,
                              children: [
                                  { name:"叶子节点211"},
                                  { name:"叶子节点212"},
                                  { name:"叶子节点213"},
                                  { name:"叶子节点214"}
                              ]},
                          { name:"父节点22 - 折叠",
                              children: [
                                  { name:"叶子节点221"},
                                  { name:"叶子节点222"},
                                  { name:"叶子节点223"},
                                  { name:"叶子节点224"}
                              ]},
                          { name:"父节点23 - 折叠",
                              children: [
                                  { name:"叶子节点231"},
                                  { name:"叶子节点232"},
                                  { name:"叶子节点233"},
                                  { name:"叶子节点234"}
                              ]}
                      ]},
                  { name:"父节点3 - 没有子节点", isParent:true}
      
              ];
      
              $(document).ready(function(){
                  $.fn.zTree.init($("#treeDemo"), setting, zNodes);
              });
          </script>
      </head>
      <body>
      <div class="zTreeDemoBackground left">
          <ul id="treeDemo" class="ztree"></ul>
      </div>
      </body>
      </html>
      
  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值