人员入场

This commit is contained in:
lSun 2025-05-19 15:36:47 +08:00
parent 10f4b5b029
commit e92d85f58c
15 changed files with 406 additions and 33 deletions

View File

@ -172,4 +172,8 @@ public class WorkerMsgDetailBean {
*/
private String collectId;
private String checkupDate;
private String checkupFilePath;
}

View File

@ -3,6 +3,7 @@ package com.bonus.bmw.person.controller;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.bonus.bmw.basic.entity.ProjectBean;
import com.bonus.bmw.basic.service.UserService;
import com.bonus.bmw.config.IpAndPathConfig;
import com.bonus.bmw.person.entity.PersonComprehensiveBean;
@ -14,6 +15,8 @@ import com.bonus.common.core.table.PageTableRequest;
import com.bonus.common.core.table.PageTableResponse;
import com.bonus.common.log.annotation.Log;
import com.bonus.common.log.enums.BusinessType;
import com.bonus.common.security.annotation.RequiresPermissions;
import com.bonus.common.security.utils.SecurityUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -27,10 +30,17 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 人员 综合
*
* @author fly
*/
@Slf4j
@ -47,7 +57,7 @@ public class PersonComprehensiveController {
@PostMapping("/getPersonList")
@Log(title = "人员综合信息-查询list", businessType = BusinessType.SELECT)
// @RequiresPermissions("sys:personComprehensive:query")
public PageTableResponse selectPersonComprehensiveList(PageTableRequest request){
public PageTableResponse selectPersonComprehensiveList(PageTableRequest request) {
return service.selectPersonComprehensiveList(request);
}
@ -66,7 +76,7 @@ public class PersonComprehensiveController {
return service.savePerson(o);
}
public void insertPersonRequired(PersonComprehensiveBean o){
public void insertPersonRequired(PersonComprehensiveBean o) {
String u = service.getExistPerson(o.getIdNumber().trim());
String b = service.getBlackPerson(o.getIdNumber().trim());
if (u != null || b != null) {
@ -87,6 +97,7 @@ public class PersonComprehensiveController {
}
return R.ok();
}
//验证手机号
@PostMapping("/verifyPersonPhone")
public R verifyPersonPhone(String phone) {
@ -123,7 +134,7 @@ public class PersonComprehensiveController {
public R<List<String>> getHolidaysList(String nation) {
try {
return service.getHolidaysList(nation);
}catch (Exception e){
} catch (Exception e) {
return R.fail("接口异常:" + e.getMessage());
}
}
@ -136,7 +147,7 @@ public class PersonComprehensiveController {
ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
FaceResult faceResult = arcFaceHelper.getFaceFeatures(url + bean.getFacePhoto());
return R.ok(faceResult);
}catch (Exception e){
} catch (Exception e) {
return R.fail("人脸检测失败:" + e.getMessage());
}
}
@ -186,16 +197,16 @@ public class PersonComprehensiveController {
try {
String filePath = "ynRealName/" + mkdirsName + "/" + DateUtil.year(date) + "/" + DateUtil.month(date) + "/" + fileName;
//保存文件基础数据
if("社保文件".equals(bean.getFileType())){
if ("社保文件".equals(bean.getFileType())) {
bean.setSocialSecurityPath(filePath);
service.insertSocialSecurityFile(bean);
}else if("工资卡文件".equals(bean.getFileType())){
} else if ("工资卡文件".equals(bean.getFileType())) {
bean.setWageCardPath(filePath);
Date d = DateUtil.parse(DateUtil.now());
DateTime newDate = DateUtil.offsetSecond(d, RandomUtil.randomInt(180));
bean.setUploadTime(newDate.toString());
service.insertWageFile(bean);
}else if("合同文件".equals(bean.getFileType())){
} else if ("合同文件".equals(bean.getFileType())) {
bean.setContractPath(filePath);
service.insertContractFile(bean);
}
@ -225,6 +236,7 @@ public class PersonComprehensiveController {
}
return map;
}
public static String[] chars = new String[]{"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",
@ -244,4 +256,77 @@ public class PersonComprehensiveController {
}
@GetMapping("/downloads")
@Log(title = "获取工程下的社保报告", businessType = BusinessType.SELECT)
public void downloadPdfs(PersonComprehensiveBean bean, HttpServletResponse response) throws IOException {
// 1. 查询人员信息
List<PersonComprehensiveBean> people = service.getDownloads(bean);
if (people == null || people.isEmpty()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "没有找到相关数据");
return;
}
// 获取操作系统类型并确定基础路径
String os = System.getProperty("os.name").toLowerCase();
String basePath;
if (os.contains("win")) { // Windows 系统
basePath = "e://yn/real_name/";
} else { // Windows 系统
basePath = "/data/real_name/";
}
response.setContentType("application/zip");
String proName ="";
if(people.size()>0){
proName = people.get(0).getProName();
}
// response.setHeader("Content-Disposition", "attachment; filename=体检报告-" + proName + ".zip");
// 设置下载文件名带编码处理
try {
String originalFileName = "体检报告-" + proName + ".zip";
String encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.toString()).replace("+", "%20");
response.setHeader("Content-Disposition",
"attachment; filename=\"" + originalFileName + "\"; filename*=UTF-8''" + encodedFileName);
} catch (UnsupportedEncodingException e) {
response.setHeader("Content-Disposition", "attachment; filename=download.zip");
}
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
for (PersonComprehensiveBean person : people) {
String checkupFilePath = person.getCheckupFilePath(); // 原始路径
if (checkupFilePath == null || checkupFilePath.isEmpty()) {
continue;
}
// 提取真实姓名身份证号
String name = person.getName();
String idCard = person.getIdNumber();
if (name == null || idCard == null) {
continue;
}
// 构建新文件名姓名_身份证号.pdf
String newFileName = name + "_" + idCard + ".pdf";
// 去掉原始路径前缀
String subPath = checkupFilePath.replaceFirst("^ynRealName/", "");
// 构建完整本地路径
File file = new File(basePath + subPath);
if (!file.exists()) {
continue;
}
// 添加到 ZIP 并使用新文件名
ZipEntry zipEntry = new ZipEntry(newFileName);
zos.putNextEntry(zipEntry);
Files.copy(file.toPath(), zos);
zos.closeEntry();
}
}
}
}

View File

@ -156,4 +156,6 @@ public interface PersonComprehensiveDao {
* @param o
*/
void deleteCheckupFile(PersonComprehensiveBean o);
List<PersonComprehensiveBean> getDownloads(PersonComprehensiveBean bean);
}

View File

@ -38,4 +38,6 @@ public interface PersonComprehensiveService {
void insertContractFile(PersonComprehensiveBean bean);
R<List<String>> getHolidaysList(String nation);
List<PersonComprehensiveBean> getDownloads(PersonComprehensiveBean bean);
}

View File

@ -560,6 +560,11 @@ public class PersonComprehensiveServiceImp implements PersonComprehensiveService
return R.ok(list);
}
@Override
public List<PersonComprehensiveBean> getDownloads(PersonComprehensiveBean bean) {
return dao.getDownloads(bean);
}
private List<PersonComprehensiveBean> listThread(List<PersonComprehensiveBean> list) {
Map<String,Object> map = new HashMap<>();
map.put("type","postType");

View File

@ -416,7 +416,9 @@
bs.SUB_NAME AS subName,
po.`name` AS subComName,
bp.`name` AS proName,
bst.team_name AS teamName
bst.team_name AS teamName,
bw.checkup_date as checkupDate,
checkup.PHOTO_PATH as checkupFilePath
FROM
bm_worker bw
LEFT JOIN ( SELECT id_number, project_id, sub_id, team_id FROM bm_worker_ein_history WHERE is_active = '1' AND is_furlough_person = '0' AND exit_status != '1' GROUP BY id_number ) bweh ON bweh.id_number = bw.id_number
@ -432,6 +434,7 @@
AND td.`type` = 'postType'
AND td.is_active = '1'
LEFT JOIN bm_worker_photo bwp ON bwp.ID_NUMBER = bw.id_number and bwp.PHOTO_TYPE = '3' and bwp.IS_ACTIVE = '1'
LEFT JOIN bm_worker_checkup checkup ON checkup.ID_NUMBER = bw.id_number AND checkup.IS_ACTIVE = 1
WHERE
bw.id_number = #{idNumber}
</select>

View File

@ -619,5 +619,30 @@
where nation = #{nation} and is_active = 1
</select>
<select id="getDownloads" resultType="com.bonus.bmw.person.entity.PersonComprehensiveBean">
SELECT
bw.`name`,
bw.id_number AS idNumber,
bw.sex,
bw.phone,
bw.checkup_date as checkupDate,
checkup.PHOTO_PATH as checkupFilePath,
bp.`name` as proName
FROM
bm_worker bw
LEFT JOIN bm_worker_checkup checkup ON checkup.ID_NUMBER = bw.id_number
AND checkup.IS_ACTIVE = 1
left join bm_worker_ein_history bweh on bweh.id_number = bw.id_number
and bweh.is_active = '1'
LEFT JOIN bm_project bp ON bp.id = bweh.project_id
AND bp.is_active = '1'
WHERE
bw.IS_ACTIVE = 1 AND checkup.PHOTO_PATH is not null
<if test="proId != null and proId != ''">
and bp.id = #{proId}
</if>
GROUP BY bw.id_number
</select>
</mapper>

View File

@ -505,4 +505,72 @@ input:-ms-input-placeholder { /* Internet Explorer 10+ */
content: '';
display: block;
clear: both;
}
#checkup{
float: left;
width: 100%;
height: 15%;
}
#checkup .safetyExamTitle{
width: 100%;
padding: 25px 0;
float: left;
}
#checkup .safetyExamTitle>span{
border-left: 6px solid #409EFF;
font-weight: 600 !important;
text-indent: 10px !important;
color: #666666;
}
#checkup .safetyExamContent{
width: 100%;
height: 72%;
float: left;
}
#checkup .safetyExamContent .safetyExamLeft{
width: 38%;
height: 100%;
margin-left: 4%;
float: left;
}
#checkup .safetyExamContent .safetyExamLeft>div{
padding: 13px 0;
}
#checkup .safetyExamContent .safetyExamLeft>div>span{
display: inline-block;
}
#checkup .safetyExamContent .safetyExamLeft>div>span:nth-child(1){
width: 30%;
font-weight: 600;
color: #999999;
text-align: right;
}
#checkup .safetyExamContent .safetyExamLeft>div>span:nth-child(2){
width: 67%;
margin-left: 1%;
}
#checkup .safetyExamContent .safetyExamContentRight{
width: 35%;
height: 100%;
margin-left: 6%;
float: left;
}
#checkup .safetyExamContent .safetyExamContentRight>div{
padding: 13px 0;
}
#checkup .safetyExamContent .safetyExamContentRight>div>span{
display: inline-block;
}
#checkup .safetyExamContent .safetyExamContentRight>div>span:nth-child(1){
width: 30%;
font-weight: 600;
color: #999999;
text-align: right;
}
#checkup .safetyExamContent .safetyExamContentRight>div>span:nth-child(2){
width: 67%;
margin-left: 1%;
}

View File

@ -0,0 +1,3 @@
(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=f.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)});
//# sourceMappingURL=FileSaver.min.js.map

View File

@ -2,6 +2,7 @@ var idNumber = localStorage.getItem('idNumbers');
var lightStatus = localStorage.getItem('lightStatus');
var example = null;
var pers = null;
var checkupFilePath = "";
layui.use(['layer', 'form'], function () {
var layer = layui.layer;
pers = checkPermission();
@ -143,6 +144,18 @@ function setData() {
}
$('#theoryScore').text(data.lightStatusBean.teamExamScore);
$("#checkupDate").text(data.checkupDate);
console.log("checkupFilePath:",data.checkupFilePath)
if(data.checkupFilePath!="" && data.checkupFilePath != null ){
checkupFilePath = data.checkupFilePath;
document.getElementById("checkup_imgs").style.display = "none";
$("#checkup_img").text("1");
}else{
checkupFilePath = "";
document.getElementById("checkup_img").style.display = "none";
$("#checkup_imgs").text("0");
}
//合同信息
if(data.contractBean != null){
$('#contractCode').text(dataConversion(data.contractBean.contractCode, '--'));
@ -374,3 +387,7 @@ function GetQueryString(idNumber){
var r = window.location.search.substr(1).match(reg);
if(r!=null)return decodeURI(r[2]); return null;
}
function getCheckup(){
window.open(ctxPath +"/" + checkupFilePath);
}

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>人员综合信息录入-批量导出体检报告</title>
<link rel="stylesheet" type="text/css" media="screen" href="../../../../css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" media="screen" href="../../../../css/dataTables.bootstrap.min.css">
<link rel="stylesheet" type="text/css" media="screen" href="../../../../layui/css/layui.css">
<link rel="stylesheet" type="text/css" media="screen" href="../../../../css/work/data_table_setting.css">
</head>
<body>
<div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<header style="height: 100%">
<div align="left">
<table style="width: 100%">
<tr>
<td>
<form class="layui-form" onsubmit="return false">
<div class="form-group" style="margin-top: 0.5%">
<div class="layui-inline" >
<label class="layui-form-label" >工程:</label>
<div class="layui-input-inline" >
<select id="proId" name="proId" lay-search="" >
</select>
</div>
</div>
<button id="downloadBt" class="layui-btn layui-btn-sm" style="margin-left:1% "><i class="layui-icon">&#xe615;</i>批量下载</button>
</div>
</form>
</td>
</tr>
</table>
</div>
</header>
</div>
</div>
</body>
</html>
<script type="text/javascript" src="../../../../js/libs/jquery-3.6.0.js"></script>
<script type="text/javascript" src="../../../../js/jq.js"></script>
<script type="text/javascript" src="../../../../js/plugin/datatables/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="../../../../js/plugin/datatables/dataTables.bootstrap.min.js"></script>
<script type="text/javascript" src="../../../../js/my/permission.js"></script>
<script type="text/javascript" src="../../../../layui/layui.js"></script>
<script type="text/javascript" src="../../../../js/publicJs.js"></script>
<script type="text/javascript" src="../../../../js/dict.js"></script>
<script type="text/javascript" src="../../../../js/select.js"></script>
<script type="text/javascript" src="../../../../js/FileSaver.min.js"></script>
<script type="text/javascript" src="personEntryCheckup.js"></script>

View File

@ -0,0 +1,72 @@
var pers = checkPermission();
var example;
layui.use(['form', 'layer'], function () {
getProByOrgId("", "", "");
$("#downloadBt").click(function () {
downloads();
});
});
function downloads() {
var proId = $('#proId').val();
if (proId == null || proId == "") {
layer.msg("请先选择工程");
return;
}
// 直接跳转到后端接口,触发文件下载
// window.location.href = ctxPath + '/personComprehensive/downloads?proId=' + encodeURIComponent(proId);
// 使用 fetch 发起 GET 请求
fetch(ctxPath + '/personComprehensive/downloads?proId=' + encodeURIComponent(proId))
.then(response => {
if (response.status === 404) {
// 如果服务端返回 404则读取响应文本并显示为错误消息
return response.text().then(text => {
throw new Error(text);
});
} else if (response.ok) {
// 获取 Content-Disposition 头以提取文件名
const contentDisposition = response.headers.get('Content-Disposition');
let filename = "体检报告.zip"; // 默认文件名
// 尝试从 Content-Disposition 中提取文件名
if (contentDisposition) {
// 查找 filename*
const utf8FilenameMatch = contentDisposition.match(/filename\*=UTF-8''([^;]+)/i);
if (utf8FilenameMatch && utf8FilenameMatch[1]) {
// 解码 filename* 中的值
filename = decodeURIComponent(utf8FilenameMatch[1].trim());
} else {
// 如果没有 filename*,尝试获取 filename
const filenameMatch = contentDisposition.match(/filename="([^"]+)"/i);
if (filenameMatch && filenameMatch[1]) {
filename = decodeURIComponent(filenameMatch[1]);
}
}
}
// 将响应体转换为 blob 并创建下载链接
return response.blob().then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename; // 使用从服务器获取的文件名
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
});
} else {
throw new Error('网络错误,请稍后再试');
}
})
.catch(error => {
console.error('下载出错:', error);
if (error.message.includes("没有找到相关数据")) {
layer.msg("没有找到相关数据,请检查输入条件。");
} else {
alert('下载失败:' + error.message);
}
});
}

View File

@ -72,6 +72,10 @@
href="../../../../downloads/人员库_导入模板.xlsx" download="人员库_导入模板.xlsx">
<i class="layui-icon">&#xe601;</i> 模板下载
</a>
<button class="layui-btn layui-btn-sm"
onclick="checkup()" style="">批量导出体检报告
</button>
</div>
</form>
</td>
@ -118,4 +122,5 @@
<script type="text/javascript" src="../../../../layui/layui.js"></script>
<script type="text/javascript" src="../../../../js/publicJs.js"></script>
<script type="text/javascript" src="../../../../js/dict.js"></script>
<script type="text/javascript" src="../../../../js/FileSaver.min.js"></script>
<script type="text/javascript" src="personEntryList.js"></script>

View File

@ -358,31 +358,23 @@ function buttonCheckup(idNumber,checkupFilePath, permission, pers) {
}
function downloadCheckup(idNumber, checkupFilePath) {
if(!checkupFilePath) {
layer.msg('没有可下载的文件');
return;
}
// 构建完整URL添加强制下载参数
// var url = fileUrl + '/' + checkupFilePath + '?response-content-disposition=attachment';
var url = "http://116.63.172.211:1918/hnBmw/gzRealName/contract/pdf/2023/09/13/1694175351382_sign.pdf" + '?response-content-disposition=attachment'
// 创建一个隐藏的a标签
var link = document.createElement('a');
link.style.display = 'none';
link.href = url;
link.setAttribute('download', idNumber + '_体检报告.pdf');
link.setAttribute('target', '_self');
// 添加到body并触发点击
document.body.appendChild(link);
link.click();
// 清理DOM
setTimeout(function() {
document.body.removeChild(link);
}, 100);
layer.msg('开始下载...');
// var url = "http://116.63.172.211:1918/hnBmw/gzRealName/contract/pdf/2023/09/13/1694175351382_sign.pdf"
var url = ctxPath +"/" + checkupFilePath;
console.log(url);
fetch(url)
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = idNumber + '_体检报告.pdf'; // 设置下载文件的名字
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url); // 清除创建的对象URL
layer.msg('开始下载...');
})
.catch(() => layer.msg('下载失败'));
}
function importData(){
@ -433,3 +425,18 @@ function importDataThread(formData, idx) {
});
$("#basePersonFile").val("");
}
/**
* 批量下载体检预约报告
*/
function checkup(){
var height = '45%';
var width = '40%';
var index = layer.open({
title: ['批量下载', 'color:#3B70A1;background-color:#E8ECEB;font-size:20px'],
type: 2,
content: 'personEntryCheckup.html',
area: [width, height],
maxmin: false,
});
}

View File

@ -94,6 +94,28 @@
</div>
</div>
</div>
<div id="checkup">
<div class="safetyExamTitle">
<span>&nbsp;&nbsp;体检报告</span>
</div>
<div class="safetyExamContent">
<div class="safetyExamLeft">
<div>
<span>体检日期</span>
<span id="checkupDate">--</span>
</div>
</div>
<div class="safetyExamContentRight">
<div>
<span>体检报告PDF附件</span>
<span id="checkup_img" onclick="getCheckup()" style="color: #0C60E2;cursor:pointer;">--</span>
<span id="checkup_imgs" >--</span>
</div>
</div>
</div>
</div>
<div id="dayPlan" style="display: none">
<div class="dayPlanTitle">
<span>&nbsp;&nbsp;日计划内容</span>