wangshan 7 gadi atpakaļ
vecāks
revīzija
f96c3919a4

+ 2 - 0
README.md

@@ -13,6 +13,8 @@ pkg目录,已经在版本控制中排除,不会被提交。
 业务代码放在bsw目录中,按前后台\模块划分
 系统配置文件统一放在config.json中。
 
+/**dev2.3**/
+新增消息管理功能,对剑鱼app用户进行推送消息,监控消息利用率。
 
 
 

+ 6 - 5
core/src/config.json

@@ -1,15 +1,15 @@
 {
     "webServerPort": "80",
-    "redisServers": "enterprise=192.168.3.14:1379,service=192.168.3.14:2379,other=192.168.3.14:3379,sso=192.168.3.14:1379,credit=192.168.3.14:3379",
+    "redisServers": "enterprise=192.168.3.18:3379,service=192.168.3.18:3379,other=192.168.3.18:3379,sso=192.168.3.18:3379,credit=192.168.3.18:3379",
     "useRedis": false,
-    "mongodbServers": "192.168.3.18:27080",	
-    "elasticsearch": "http://192.168.3.18:9800",
+    "mongodbServers": "192.168.3.11:27080",	
+    "elasticsearch": "http://192.168.3.11:9800",
     "jyescsearch": "http://192.168.3.18:9200",
     "elasticPoolSize": 30,
     "mongodbPoolSize": 5,
     "mongodbName": "qfw",
 	"cassandra": [
-        "192.168.3.18"
+        "192.168.3.207"
     ],
     "cassandrasize":5,
     "smtp": {
@@ -56,5 +56,6 @@
 		"s_avatar": [8,99]
     },
 	"jyWebdomain":"http://192.168.110.101:82",
-	"qmxWebdomain":"http://192.168.110.101"
+	"qmxWebdomain":"http://192.168.110.101",
+	"jyadd":"http://webws.qmx.top/jyapp/free/message/"
 }

+ 2 - 1
core/src/jgpush.json

@@ -4,7 +4,8 @@
     "appSecret": "d7a4e79978cd73cd61a5c7f7",
     "alertlen": 100,
     "title": {
-        "feedback": "剑鱼客服回答了您的问题!"
+        "feedback": "剑鱼客服回答了您的问题!",
+        "message": "您有新的消息!"
     },
     "config": {
         "platform": "all",

+ 1 - 1
core/src/main.go

@@ -68,7 +68,7 @@ func init() {
 	conf.Size = SysConfig.EntMongodbPoolSize
 	mongodbutil.Config = append(mongodbutil.Config, conf)
 
-	mongodbutil.InitMongodbPool()
+	//mongodbutil.InitMongodbPool()
 	//redis配置
 	redis.InitRedis(SysConfig.Redisservers)
 	//初始化elastic

+ 1 - 0
core/src/qfw/coreconfig/SysConfig.go

@@ -39,6 +39,7 @@ type config struct {
 	JyWebdomain        string                 `json:"jyWebdomain"`
 	QmxWebdomain       string                 `json:"qmxWebdomain"`
 	ServiceApp         int                    `json:"serviceApp"`
+	Jyadd              string                 `json:"jyadd"`
 }
 type smtp struct {
 	Addr     string `json:"addr"`

+ 1 - 0
core/src/qfw/manage/article.go

@@ -159,6 +159,7 @@ func (a *Article) Updatearticle() error {
 			redis.Del("other", "/front/weixincontent/"+_id)
 			redis.Del("other", "jyblog"+se.EncodeString(_id))
 			redis.Del("other", "/")
+			redis.Del("other", "jymessage_"+se.EncodeString(_id))
 			redis.Del("other", "latestNews") //最新消息
 		} else {
 			flag = "false"

+ 3 - 1
core/src/qfw/manage/articlecontent.go

@@ -7,6 +7,7 @@ package manage
 import (
 	"fmt"
 	"html/template"
+	. "qfw/coreconfig"
 	"qfw/util"
 	"qfw/util/mongodb"
 	. "qfw/util/mongodb"
@@ -26,7 +27,7 @@ func (n *Article) Newscontent(_id string) error {
 			r := mongodb.FindById("content", _id, `{"s_title":1,"l_createdate":1,"s_editorname":1,"s_author":1,"releasetime":1,s_contenttype":1,"praise":1,"s_pic":1,"s_pic1":1,"s_content":1,,"s_description":1,"s_keywords":1,"s_source":1,"s_url":1,"s_record":1}`)
 			if nil != r && len(*r) > 0 {
 				author, _ := (*r)["s_author"].(string)
-				fmt.Println("author:", r)
+				//fmt.Println("author:", r)
 				if len(author) < 1 {
 					(*r)["s_author"] = ""
 				}
@@ -36,6 +37,7 @@ func (n *Article) Newscontent(_id string) error {
 				release := (*r)["releasetime"]
 				(*r)["releasetime"] = util.FormatDateWithObj(&release, util.Date_Full_Layout)
 				(*r)["s_content"] = template.HTML((*r)["s_content"].(string))
+				(*r)["s_preurl"] = SysConfig.Jyadd + se.EncodeString((*r)["_id"].(string)) + ".html"
 				n.T = *r
 				return n.Render("/manage/newscontent.html")
 			} else {

+ 1 - 2
core/src/qfw/manage/articlelist.go

@@ -5,7 +5,6 @@
 package manage
 
 import (
-	"log"
 	"qfw/util"
 	"qfw/util/elastic"
 	. "qfw/util/mongodb"
@@ -45,7 +44,7 @@ func (e *Article) GetJsonList(list string) error {
 			}
 			query = query + `}`
 			res["totalRows"] = elastic.Count("content", "content", elastic.MakeQuery(query, "", "", -1, -1))
-			log.Println(query, "==", elastic.MakeQuery(query, "", "", -1, -1))
+			//log.Println(query, "==", elastic.MakeQuery(query, "", "", -1, -1))
 			data := *elastic.GetPage("content", "content", query, `{"releasetime":-1}`, `"s_title","l_createdate","s_contenttype","s_source","releasetime","s_editorname","s_type","_id"`, (currentPage-1)*size, size)
 			for _, v := range data {
 				release := v["releasetime"]

+ 1 - 0
core/src/qfw/manage/manage.go

@@ -12,4 +12,5 @@ func init() {
 	xweb.AddAction(&WebServerManage{})
 	xweb.AddAction(&CAudit{})
 	xweb.AddAction(&manage{})
+	xweb.AddAction(&Message{})
 }

+ 182 - 0
core/src/qfw/manage/message.go

@@ -0,0 +1,182 @@
+package manage
+
+import (
+	"fmt"
+	"qfw/jgpush"
+	"qfw/util"
+	. "qfw/util/mongodb"
+	"strings"
+	"time"
+	uc "ucbsutil"
+	ca "ucbsutil/cassandra"
+
+	"github.com/go-xweb/xweb"
+	"gopkg.in/mgo.v2/bson"
+)
+
+type Message struct {
+	*xweb.Action
+	//消息管理
+	index     xweb.Mapper `xweb:"/manage/message/(\\w+)"`
+	sendIndex xweb.Mapper `xweb:"/manage/message/sendIndex"`
+	detail    xweb.Mapper `xweb:"/manage/message/detail"`
+	sase      xweb.Mapper `xweb:"/manage/message/send"`
+	list      xweb.Mapper `xweb:"/manage/message/list"`
+	content   xweb.Mapper `xweb:"/manage/message/content/(\\w+)"`
+	receive   xweb.Mapper `xweb:"/front/message/receive"`
+}
+
+//
+func (m *Message) Content(id string) error {
+	defer util.Catch()
+	if m.GetSession("loginName") == nil {
+		return m.Redirect("/")
+	} else {
+		r := FindById("message_app", id, nil)
+		if nil != r {
+			(*r)["_id"] = strings.Split(fmt.Sprintf("%s", (*r)["_id"]), `"`)[1]
+			data_3 := (*r)["l_submitdate"]
+			(*r)["l_submitdate"] = util.FormatDateWithObj(&data_3, util.Date_Full_Layout)
+		}
+		m.T = *r
+		return m.Render("/manage/message/detail.html")
+	}
+}
+
+//
+func (m *Message) List() error {
+	defer util.Catch()
+	if m.GetSession("loginName") == nil {
+		return m.Redirect("/")
+	} else {
+		if m.Method() == "POST" {
+			size, _ := m.GetInteger("perPage")
+			if size > 100 {
+				m.ServeJson(&map[string]interface{}{
+					"msg": "soory,size too many!",
+				})
+			} else {
+				currentPage, _ := m.GetInteger("currentPage")
+				search := m.GetString("query")
+				res := map[string]interface{}{}
+				query := `{`
+				if len(search) > 0 {
+					query = query + `"s_title":{"$regex":"` + search + `"}`
+				}
+				query = query + "}"
+				res["totalRows"] = Count("message_app", query)
+				data := *Find("message_app", query, `{"l_submitdate": -1}`, nil, false, (currentPage-1)*size, size)
+				for _, v := range data {
+					data_1 := v["l_submitdate"]
+					v["l_submitdate"] = util.FormatDateWithObj(&data_1, util.Date_Short_Layout)
+				}
+				res["data"] = data
+				res["currentPage"] = currentPage
+				m.ServeJson(&res)
+			}
+		}
+	}
+	return nil
+}
+
+//
+func (m *Message) Sase() error {
+	defer util.Catch()
+	flag := "F"
+	if m.GetSession("loginName") == nil {
+		return m.Redirect("/")
+	} else {
+		data := make(map[string]interface{})
+		data["s_title"] = m.GetString("title")
+		data["s_subtitle"] = m.GetString("subtitle")
+		data["s_url"] = m.GetString("url")
+		data["i_total"], _ = m.GetInteger("total")
+		data["i_delivery"], _ = m.GetInteger("delivery")
+		data["i_click"], _ = m.GetInteger("click")
+		data["s_sender"] = m.GetSession("loginName")
+		data["l_submitdate"] = time.Now().Unix()
+		id := Save("message_app", data)
+		if len(id) > 0 {
+			flag = "T"
+			jgpush.JPush()
+			title := m.GetString("title")
+			subtitle := m.GetString("subtitle")
+			if len([]rune(subtitle)) > 80 {
+				subtitle = string([]rune(subtitle)[:80]) + "..."
+			}
+			go sendMes(id, title, subtitle, m.GetString("url"))
+			//			jpushid := "18171adc035c24ee76e"
+			//			openid := "ocXeA0juxw7b7A_bjXVy0NSJF5f0"
+			//			jgpush.JgpushD_Nc(subtitle, "message", []string{jpushid}, map[string]interface{}{
+			//				"url":    m.GetString("url") + "==" + id,
+			//				"openid": openid,
+			//				"title":  title,
+			//				"type":   "message",
+			//				"extend": map[string]interface{}{"linkType": "external"},
+			//			}, false)
+		}
+	}
+	m.ServeJson(map[string]interface{}{
+		"flag": flag,
+	})
+	return nil
+}
+
+//
+func sendMes(id, title, subtitle, url string) error {
+	defer util.Catch()
+	userData := Find("user", `{"i_ispush": 1, "i_type":{"$in": [1,2]}}`, `{"l_registedate":-1}`, `{"s_m_openid":1,"s_jpushid":1,"s_province":1,"s_city":1,"s_nickname":1}`, false, -1, -1)
+	var total = 0
+	for _, v := range *userData {
+		jpushid := util.ObjToString(v["s_jpushid"])
+		openid := util.ObjToString(v["s_m_openid"])
+		province := util.ObjToString(v["s_province"])
+		city := util.ObjToString(v["s_city"])
+		nickname := util.ObjToString(v["s_nickname"])
+		if jpushid != "" && openid != "" && id != "" {
+			total = total + 1
+			go ca.SaveCache("jy_message", map[string]interface{}{
+				"id":       uc.DayShortTime(),
+				"openid":   openid,
+				"mid":      id,
+				"title":    title,
+				"subtitle": subtitle,
+				"province": province,
+				"city":     city,
+				"nickname": nickname,
+				"action":   "S", //S:发送 D:送达 C:打开
+				"date":     time.Now().Unix(),
+				"url":      url,
+			})
+			jgpush.Jgconfig.Title["message"] = title
+			jgpush.JgpushNc(subtitle, "message", []string{jpushid}, map[string]interface{}{
+				"url":    url + "==" + id,
+				"openid": openid,
+				"title":  title,
+				"type":   "message",
+			}, false)
+		}
+	}
+	go Update("message_app", map[string]interface{}{"_id": bson.ObjectIdHex(id)}, map[string]interface{}{"$set": map[string]interface{}{"i_total": total}}, false, false)
+	return nil
+}
+
+//
+func (m *Message) Index(pageType string) error {
+	defer util.Catch()
+	if m.GetSession("loginName") == nil {
+		return m.Redirect("/")
+	} else {
+		var userid = m.GetSession("userId").(string)
+		u := FindOne("user", "{'_id':'"+userid+"'}")
+		u_type := (*u)["i_type"]
+		if u_type == 0 {
+			return m.Render("/manage/message/" + pageType + ".html")
+		} else {
+			return m.Redirect("/")
+		}
+
+	}
+}
+
+//

+ 1 - 1
core/src/timetask.json

@@ -1 +1 @@
-{"comment":{"c_rate":720,"commentrate":900},"market":{"demand":{"attr":["i_hits","i_bids","i_status"],"timepoint":"2018-05-18 16:51:32"},"service":{"attr":["i_hits","i_sales","i_comments","i_score","i_appcounts"],"timepoint":"2018-05-18 16:51:32"}},"marketisstart":true,"marketrate":300}
+{"comment":{"c_rate":720,"commentrate":900},"market":{"demand":{"attr":["i_hits","i_bids","i_status"],"timepoint":"2018-07-27 10:28:31"},"service":{"attr":["i_hits","i_sales","i_comments","i_score","i_appcounts"],"timepoint":"2018-07-27 10:28:31"}},"marketisstart":true,"marketrate":300}

+ 63 - 0
core/src/web/staticres/css/message.css

@@ -0,0 +1,63 @@
+.widget-box{
+	    background: #fff;
+    border: 1px solid #e0e0e0;
+    margin-bottom: 0px;
+	padding: 25px 50px;
+	min-height: 500px;
+}
+.widget-content{
+	border-bottom:0px;
+}
+.head .title{
+	float:left;
+	font-size: 16px;
+    font-weight: 700;
+    margin-left: 20px;
+}
+.head .back{
+	float:right;
+	margin-right: 20px;
+}
+.head{
+	line-height: 40px;
+    border-bottom: 1px solid #99D6DC;
+}
+#sidebar {
+    margin-left: 0px;
+}
+.sendform{
+	   padding: 30px 240px 30px 180px;
+}
+#fbt{
+	position:relative;
+}
+.count{
+	position: absolute;
+    right: 24px;
+    bottom: 3px;
+}
+#submit .btn{
+	    width: 81px;
+}
+.detail .cont{
+	margin-top: 30px;
+}
+.detail .title{
+	font-size: 16px;
+    font-weight: bold;
+    margin-bottom: 10px;
+}
+.detail .info{
+	margin-top: 25px;
+	font-size: 12px;
+	    color: #aaa;
+}
+.detail .info span:nth-child(1){
+	margin-right:25px;
+}
+.detail .url{
+	    margin: 30px 0px 20px;
+}
+.detail .url span:nth-child(1){
+	font-weight:bold;
+}

+ 1 - 0
core/src/web/templates/manage/addarticle.html

@@ -246,6 +246,7 @@ margin-top:-8px;
 		<option value="wxlm"> 微信栏目 </option>
 		<option value="zhsk"> 知识库 </option>
 		<option value="jybk"> 剑鱼博客 </option>
+		<option value="ggxx"> 公告消息 </option>
 		</select>
 		</div>
 		</div>

+ 3 - 1
core/src/web/templates/manage/articlelist.html

@@ -53,7 +53,7 @@ $(function(){
   ,classname:"table-hover"
   ,css:{"height":"430px"}
   //,post:{"contenttype":""}
-  ,buttons: ['<div style="margin:5px 20px 0px 30px;" class="controls pull-right"><span><a href="/manage/addarticle"><button class="btn btn-info" onclick="" type="button">添加文章</button></a></span></div><div style="width:50%;margin:5px" class="input-group pull-right" id="search"><input type="text" id="searchtext" value=""  data-original-title="Search" class="form-control" placeholder="请输入检索条件..."><span class="input-group-btn"><button class="btn btn-success" onclick="SearchContent()" data-original-title="Search" id="searchtip" type="button" style="height:38px;">检索</button></span></div><div style="margin:5px;" class="controls pull-right"><select class="form-control" id="select" ><option value=""> 请选择栏目 </option><option value="qykb"> 企业网快报 </option><option value="mtpj">媒体评价 </option><option value="hyzx">行业资讯 </option><option value="zcfg"> 政策法规 </option><option  value="zthd"> 专题活动 </option><option value="zh" > 展会 </option><option value="qtlm"> 其他栏目 </option><option value="wxlm"> 微信栏目 </option><option value="zhsk"> 知识库 </option><option value="jybk"> 剑鱼博客 </option></select></div>']
+  ,buttons: ['<div style="margin:5px 20px 0px 30px;" class="controls pull-right"><span><a href="/manage/addarticle"><button class="btn btn-info" onclick="" type="button">添加文章</button></a></span></div><div style="width:50%;margin:5px" class="input-group pull-right" id="search"><input type="text" id="searchtext" value=""  data-original-title="Search" class="form-control" placeholder="请输入检索条件..."><span class="input-group-btn"><button class="btn btn-success" onclick="SearchContent()" data-original-title="Search" id="searchtip" type="button" style="height:38px;">检索</button></span></div><div style="margin:5px;" class="controls pull-right"><select class="form-control" id="select" ><option value=""> 请选择栏目 </option><option value="qykb"> 企业网快报 </option><option value="mtpj">媒体评价 </option><option value="hyzx">行业资讯 </option><option value="zcfg"> 政策法规 </option><option  value="zthd"> 专题活动 </option><option value="zh" > 展会 </option><option value="qtlm"> 其他栏目 </option><option value="wxlm"> 微信栏目 </option><option value="zhsk"> 知识库 </option><option value="jybk"> 剑鱼博客 </option><option value="ggxx"> 公告消息 </option></select></div>']
   , url: '/manage/articlelist/list'
   , columns: [
         {
@@ -97,6 +97,8 @@ $(function(){
 			v = "知识库"
 			}else if(v == "jybk") {
 			v = "剑鱼博客"
+			}else if(v == "ggxx") {
+			v = "公告消息"
 			}
 			return v
 		}

+ 200 - 0
core/src/web/templates/manage/message/detail.html

@@ -0,0 +1,200 @@
+<html>
+<head>
+<title>详细信息</title>
+{{include "/common/inc.html"}}
+<link href="{{Msg "seo" "cdn"}}/css/message.css" rel="stylesheet">
+<script src="/js/validform-min.js"></script>
+<script type="text/javascript" src="/js/zDrag.js"></script>
+<script type="text/javascript" src="/js/zDialog.js"></script>
+<script src="{{Msg "seo" "cdn"}}/js/upload.js"></script>
+<script src="{{Msg "seo" "cdn"}}/js/jquery.cityselect.js"></script> 
+<style type="text/css">
+.widget-content {
+table-layout: fixed;
+font-size:14px;
+}
+#message{background-color:#f5f5f5;}
+</style>
+</head>
+<body>
+
+{{include "/manage/audithead.html"}}
+<!-- 中间 -->
+<div class="row" style="width:96%; margin:0 auto; margin-top:10px;">
+<div>
+{{include "/manage/slider.html"}}
+	
+		<div id="content" class="detail send">
+	    <div class="widget-box">
+		<div class="widget-content nopadding">
+		<div class="head">
+			<div class="title">消息查看</div>
+			<div class="back" onclick="javascript :history.back(-1);"><button class="btn btn-info" onclick="" type="button">返回</button></div>
+			<div style="clear:both;"></div>
+		</div>
+			
+		<div class="cont">
+			<form class="registerform form-horizontal" role="form" id="auditcontent" method="post">
+	        
+	        <div class="form-group">
+	        <label id="col-sm-3" class="col-sm-3 control-label" for="name"></label>
+		    <div class="col-sm-6" style="text-align:center;">
+	        	<div class="title">{{.T.s_title}}</div>
+	        	<div class="subtitle">{{.T.s_subtitle}}</div>
+	        	<div class="info">
+					发送人:<span>{{.T.s_sender}}</span>
+					发送时间:<span>{{.T.l_submitdate}}</span>
+				</div>
+			</div>
+			<div class="col-sm-3">
+			</div>
+			</div>
+	        <div class="form-group">
+	        <label id="col-sm-1" class="col-sm-1 control-label" for="name"></label>
+		    <div class="col-sm-10">
+	        	<div class="url"><span>url链接:</span><span>{{.T.s_url}}</span></div>
+			</div>
+			<div class="col-sm-1">
+			</div>
+			</div>
+	        <div class="form-group">
+	        <label id="col-sm-1" class="col-sm-1 control-label" for="name"></label>
+		    <div class="col-sm-10">
+	        	<div style="font-weight:bold;">转化率:</div>
+				<div class="mgform">
+		       		<div id="container" style="height: 400px"></div>
+				</div>
+			</div>
+			<div class="col-sm-1">
+			</div>
+			</div>
+			
+	       	</form>
+		</div>
+		</div>
+		</div>
+		
+		</div>
+		
+	</div>
+</div>
+<div style="display:none;">
+	<form id="uploadForm" enctype="multipart/form-data"> 
+		<input type="file" class="uploadimg"  name="cauditupload"/>
+		<input type="text" name="type" value="cauditupload"/>
+	</form>
+</div>
+
+{{include "/common/bottom.html"}}
+<script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts.min.js"></script>
+<script type="text/javascript">
+var dom = document.getElementById("container");
+var myChart = echarts.init(dom);
+var app = {};
+option = null;
+app.title = '剑鱼消息发送 - 条形图';
+var mgdata = new Array();//[32000, 36000, 40000];
+var total = {{.T.i_total}};
+var base = 1;
+mgdata[0]={{.T.i_click}};
+mgdata[1]={{.T.i_delivery}};
+mgdata[2]={{.T.i_total}};
+if(total!=0){
+	for(var i=1;i<total.toString().length;i++){
+		base=base*10;
+	}
+}
+var maxcount = Math.ceil(total/base)*base;
+var interval = maxcount/10;
+var math = mgdata[mgdata.length-1];
+option = {
+	color: function(params) {
+		// build a color map as your need.
+		var colorList = [
+			'#FCCE10', '#51E682', '#5B74F3',
+		];
+		return colorList[params.dataIndex]
+	},
+	shadowBlur: 20,
+	shadowColor: 'rgba(0, 0, 0, 0.5)',
+	/*legend: {
+		data: [date]
+	},*/
+    tooltip: {
+        trigger: 'item'
+    },
+	grid: {
+		left: '4%',
+		right: '10%',
+		bottom: '4%',
+        top: '4%',
+		containLabel: true
+	},
+	xAxis: {
+		type: 'value',
+		boundaryGap: [0, 0.01],
+		min: 0,
+		max: maxcount,
+		interval: interval,
+		axisLabel: {
+			formatter: '{value}',
+			textStyle: {
+				//color: '#fff',  
+				fontWeight: '30'
+			}
+		}
+	},
+	yAxis: {
+		type: 'category',
+		data: ['打开人数', '送达人数', '目标人数'],
+		axisLabel: {
+			show: true,
+			interval: 0,
+			rotate: 0,
+			margin: 10,
+			inside: false,
+			textStyle: {
+				//color: '#fff',
+				fontWeight: '30'
+			}
+		}
+	},
+	series: [{
+		type: 'bar',
+		barWidth: '40%',
+		label: {
+			normal: {
+				show: true,
+				position: 'right',
+				// formatter: '{c}',
+				formatter: function(v) {
+					var val = v.data;
+					var index = v.dataIndex;
+					if (index == 2) {
+						return val;
+					}else if (index == 0) {
+						if (val == 0) {
+							return val + '--打开率0%';
+						}else{
+							return val + '--打开率' + Math.round(val*100 / math) + '%';
+						}
+					}else if (index == 1) {
+						if (val == 0) {
+							return val + '--送达率0%';
+						}else{
+							return val + '--送达率' + Math.round(val*100 / math) + '%';
+						}
+					}
+				},
+				//color: '#000',
+			}
+		},
+		data: mgdata
+	}]
+};
+if (option && typeof option === "object") {
+    myChart.setOption(option, true);
+}
+</script>
+</body>
+</html>

+ 207 - 0
core/src/web/templates/manage/message/index.html

@@ -0,0 +1,207 @@
+<html>
+<head>
+<title>消息列表</title>
+{{include "/common/inc.html"}}
+<script src="{{Msg "seo" "cdn"}}/js/validform-min.js"></script>
+<style type="text/css">
+<!--
+body{
+background-color:#FFFFFF;
+}
+#content table{
+table-layout: fixed;
+border:0px;
+font-size:14px;
+}
+.table>thead>tr>th:nth-child(1){
+width:35%;
+padding-left: 15px;
+}
+.table>thead>tr>th:nth-child(2){
+width:10%;
+}
+.table>thead>tr>th:nth-child(3){
+width:20%;
+}
+.table>thead>tr>th:nth-child(4){
+width:35%;
+}
+.table>thead>tr>th{
+border:0px;
+}
+.table>tbody>tr>td{
+white-space: nowrap;
+text-overflow: ellipsis;
+overflow: hidden;
+border:0px;
+border-bottom:1px dashed #999999;
+    padding: 2px 8px;
+}
+#sidebar { margin-left:0px;}
+#message{background-color: #f5f5f5;}
+-->
+.first span:nth-child(1){
+	border: 1px solid #5B74F3;
+    max-width: 110px;
+    background-color: #5B74F3;
+    width: 110px;
+}
+.second span:nth-child(1){
+	border: 1px solid #51E682;
+    max-width: 110px;
+    background-color: #51E682;
+    width: 80px;
+}
+.three span:nth-child(1){
+	border: 1px solid #FCCE10;
+    max-width: 110px;
+    background-color: #FCCE10;
+    width: 60px;
+}
+#subfrom span:nth-child(1){
+    height: 12px;
+	display: inline-block;
+	margin-right:5px;
+}
+#subfrom span:nth-child(2){
+	position: relative;
+    top: -1px;
+	font-size:13px;
+}
+.second{
+	margin:-3px 0px;
+}
+.table>tbody>tr>td:nth-child(1){
+	line-height:24px;
+	padding-left: 15px;
+}
+.table>tbody>tr>td:nth-child(2),.table>tbody>tr>td:nth-child(3){
+	padding-top: 15px;
+}
+</style>
+
+</head>
+<body>
+
+{{include "/manage/audithead.html"}}
+<!-- 中间 -->
+<div class="row" style="width:96%; margin:0 auto; margin-top:10px;">
+<div>
+{{include "/manage/slider.html"}}	
+		
+		<div id="content">		
+<!-- 中间 -->
+<script>
+$(function(){
+	$("#audit").datatable({
+   perPage: 10
+  ,showPagination:true
+  ,checkbox:"" //check radio
+  ,checkboxHeader:false
+  ,idField:"_id"
+  ,classname:"table-hover"
+  //,css:{"height":"430px"}
+  //,post:{"contenttype":""}
+  ,buttons: ['<div style="margin:5px 20px 0px 30px;" class="controls pull-right"><span><a href="/manage/message/sendIndex"><button class="btn btn-info" onclick="" type="button">发送消息</button></a></span></div><div style="width:50%;margin:5px" class="input-group pull-right" id="search"><input type="text" id="searchtext" value=""  data-original-title="Search" class="form-control" placeholder="请输入检索条件..."><span class="input-group-btn"><button class="btn btn-success" onclick="SearchContent()" data-original-title="Search" id="searchtip" type="button" style="height:38px;">检索</button></span></div>']
+  , url: '/manage/message/list'
+  , columns: [
+        {
+            title: "标题",
+			 field: "s_title",
+		 // css:{color:'#000000'} ,
+		 //  classname:"active",
+			callback:function(ct,cd,val,k,m){
+			var v=ct["s_title"];
+			var subv = ct["s_subtitle"];
+			var id = ct["_id"];
+			if(v) v="<a style='font-weight:bold;text-decoration: none;' href='/manage/message/content/"+id+"'>"+v+"</a></br><span>"+subv+"</span>"
+			return v
+		}	
+        },
+		{
+            title: "发送人", 
+			field: "s_sender",
+			callback:function(ct,cd,val,k,m){
+				return ct["s_sender"]
+			}
+        },
+		{
+            title: "发送时间",
+           	field: "l_submitdate",
+		  	callback:function(ct,cd,val,k,m){
+			var regS = new RegExp("\\/","g");
+			var v=ct["l_submitdate"]//.replace(regS,"-");
+			return v
+		  }
+        },
+		{
+            title: "消息统计"
+          , field: "s_total"
+		,callback:function(ct,cd,val,k,m){
+			var total=ct["i_total"];
+			var delivery=ct["i_delivery"];
+			var click=ct["i_click"];
+			var defpercent = Math.round(delivery*100/total)*0.3+"%";
+			var clickpercent = Math.round(click*100/total)*0.3+"%";
+			var totalpercent = "";
+			if(total==0){
+				defpercent="1px";
+				clickpercent="1px";
+				totalpercent = "1px";
+			}
+			var v="<div class='first' id='subfrom'><span style='width:"+totalpercent+"'></span><span>"+total+"</span></div>"+
+				"<div class='second' id='subfrom'><span style='width:"+defpercent+"'></span><span>"+delivery+"</span></div>"+
+				"<div class='three' id='subfrom'><span style='width:"+clickpercent+"'></span><span>"+click+"</span></div>"
+			return v
+		}
+        }
+    ]
+});
+
+})
+function SearchContent(){
+	var find=$("#audit").data("datatable")
+	if(!find.options.opost) find.options.opost=find.options.post||{};
+	find.options.post=$.extend(find.options.opost,{query:$("#searchtext").val()});
+	find.options.currentPage=1
+	find.render();
+}
+</script>
+<div id="audit"></div>
+</div>
+</div>
+
+</div>
+{{include "/common/bottom.html"}}
+<script src="/js/qfwtable.js"></script>
+<script type="text/javascript">
+$(function (){
+	$(".backTop").click(function (){
+		$(window).scrollTop(0);
+	});
+	$('#loginModal').on('shown.bs.modal', function () {
+		$("#username").focus();
+	});
+	var obj = $(".navbar-nav li a.qfw-navbar-active");
+	$(".navbar-nav li a").mouseover(function (){
+		obj.removeClass("qfw-navbar-active");
+		$(this).addClass("qfw-navbar-active");
+	}).mouseout(function (){
+		$(this).removeClass("qfw-navbar-active");
+		obj.addClass("qfw-navbar-active");
+	});
+	$(".registerform").Validform({
+		tiptype:function(msg,o,cssctl){
+			cssctl($(o.obj).prev(),o.type);
+			$(o.obj).prev().text(msg).show();
+		}
+	});
+});
+
+</script>
+<script type="text/javascript">
+  $(function(){
+  })
+</script>
+</body>
+</html>

+ 127 - 0
core/src/web/templates/manage/message/sendIndex.html

@@ -0,0 +1,127 @@
+<html>
+<head>
+<title>发送消息</title>
+{{include "/common/inc.html"}}
+<link href="{{Msg "seo" "cdn"}}/css/message.css" rel="stylesheet">
+<script src="/js/validform-min.js"></script>
+<script type="text/javascript" src="/js/zDrag.js"></script>
+<script type="text/javascript" src="/js/zDialog.js"></script>
+<script src="{{Msg "seo" "cdn"}}/js/upload.js"></script>
+<script src="{{Msg "seo" "cdn"}}/js/jquery.cityselect.js"></script> 
+<style type="text/css">
+.widget-content {
+table-layout: fixed;
+font-size:14px;
+}
+#message{background-color:#f5f5f5;}
+</style>
+</head>
+<body>
+
+{{include "/manage/audithead.html"}}
+<!-- 中间 -->
+<div class="row" style="width:96%; margin:0 auto; margin-top:10px;">
+<div>
+{{include "/manage/slider.html"}}
+	
+		<div id="content" class="send">
+	    <div class="widget-box">
+		<div class="widget-content nopadding">
+		<div class="head">
+			<div class="title">消息发送</div>
+			<div class="back" onclick="javascript :history.back(-1);"><button class="btn btn-info" onclick="" type="button">返回</button></div>
+			<div style="clear:both;"></div>
+		</div>
+		<div class="sendform">
+			<form class="registerform form-horizontal" role="form" id="mgcontent" method="post">
+	        
+	        <div class="form-group">
+	        <label id="col-sm-2" class="col-sm-2 control-label" for="name">标题:</label>
+		    <div class="col-sm-6">
+	        <input class="form-control" maxlength="50"  id="title" name="title" value=""  style="background-color:#eee;"/>
+	        <input class="form-control" style="display:none"  id="total" name="total" value="0"  style="background-color:#eee;"/>
+	        <input class="form-control" style="display:none"  id="delivery" name="delivery" value="0"  style="background-color:#eee;"/>
+	        <input class="form-control" style="display:none"  id="click" name="click" value="0"  style="background-color:#eee;"/>
+			</div>
+			<div class="col-sm-4">
+			</div>
+			</div>
+	        <div class="form-group">
+	        <label id="col-sm-2" class="col-sm-2 control-label" for="name">副标题:</label>
+		    <div class="col-sm-10" id="fbt">
+				<span class="count">0/100</span>
+       			<textarea class="form-control" maxlength="100" id="subtitle" name="subtitle" value="" style="background-color:#eee;height: 120px;resize: none;"></textarea>
+			</div>
+			</div>
+	        <div class="form-group">
+	        <label id="col-sm-2" class="col-sm-2 control-label" for="name">URL链接:</label>
+		    <div class="col-sm-6">
+	        <input class="form-control" id="url" name="url" value=""  style="background-color:#eee;"/>
+			</div>
+			<div class="col-sm-4">
+			</div>
+			</div>
+			
+	        <div class="form-group" style="margin: 60px -15px 0px;">
+	        <label class="col-sm-2 control-label" for="name"></label>
+		    <div class="col-sm-6" id="submit">
+			<button class="btn btn-success" id="addsure" type="button">提交</button>
+			<button class="btn " onclick="javascript :history.back(-1);" type="button" style="margin-left: 60px;">取消</button>
+			</div>
+			<div class="col-sm-4">
+			</div>
+			</div>
+			</form>
+		</div>
+			
+		</div>
+		</div>
+		
+		</div>
+		
+	</div>
+</div>
+<div style="display:none;">
+	<form id="uploadForm" enctype="multipart/form-data"> 
+		<input type="file" class="uploadimg"  name="cauditupload"/>
+		<input type="text" name="type" value="cauditupload"/>
+	</form>
+</div>
+
+{{include "/common/bottom.html"}}
+<script type="text/javascript">
+$(function(){ 
+	//提交数据
+	$("#addsure").click(function(){
+		if($("#title").val()==""){
+			alert("请输入标题!")
+		}
+		if($("#subtitle").val()==""){
+			alert("请输入副标题!")
+		}
+		var Param = $("#mgcontent").serialize();
+	    $.ajax({    
+	        type:'post',        
+	        url:'/manage/message/send',    
+	        data:Param,    
+	        cache:false,    
+	        dataType:'json', 
+	        success:function(data){
+				console.log(data)
+				if(data.flag=="T"){
+					var con = confirm("发送成功!");
+					if(con){
+						history.back(-1)
+					}
+				}
+	        }    
+	    }); 
+	})
+	//
+	$("#subtitle").bind('input propertychange',function(){
+		$(".count").text($(this).val().length+"/100")
+	})
+})
+</script>
+</body>
+</html>

+ 6 - 1
core/src/web/templates/manage/newscontent.html

@@ -98,7 +98,11 @@ margin-top:-8px;
 						<div class="widget-box">
 							<div class="widget-content nopadding">
 							<div style="width:90%; margin:auto; margin-bottom:80px;">
-							<div style="margin:-5px -30px 0px 0px;" class="controls pull-right"><span><button class="btn btn-info" onClick="editarticle();" type="button">编辑</button></span><span style="margin-left:30px;"><button class="btn btn-info" onClick="delearticle();" type="button">删除</button></span></div>
+							<div style="top: 6px;position: absolute;right: 52px" class="controls pull-right">
+							{{if  eq .T.s_contenttype "ggxx"}}
+							<span><button class="btn btn-info" onClick="window.open('{{.T.s_preurl}}')" type="button">预览</button></span>{{end}}
+							<span style="margin-left:15px;"><button class="btn btn-info" onClick="editarticle();" type="button">编辑</button></span>
+							<span style="margin-left:15px;"><button class="btn btn-info" onClick="delearticle();" type="button">删除</button></span></div>
 							
 							<h4><p style="font-weight:bold; border-bottom:1px dashed #98D6DC; padding-bottom:20px;" class="text-center">{{.T.s_title}}</p></h4>
 							<div>
@@ -261,6 +265,7 @@ margin-top:-8px;
 		<option value="wxlm" {{if  eq .T.s_contenttype "wxlm"}} selected="selected" {{end}}> 微信栏目 </option>
 		<option value="zhsk" {{if  eq .T.s_contenttype "zhsk"}} selected="selected" {{end}}> 知识库 </option>
 		<option value="jybk" {{if  eq .T.s_contenttype "jybk"}} selected="selected" {{end}}> 剑鱼博客 </option>
+		<option value="ggxx" {{if  eq .T.s_contenttype "ggxx"}} selected="selected" {{end}}> 公告消息 </option>
 		</select>
 		</div>
 		</div>

+ 1 - 0
core/src/web/templates/manage/slider.html

@@ -8,6 +8,7 @@
 		<li id="ad"  class="list-group-item"><a style=" font-weight:normal;" href="/manage/ad"><i class="glyphicon glyphicon-euro"></i> <span>广告管理</span></a></li>
 		<li id="count"  class="list-group-item"><a style=" font-weight:normal;" href="/manage/count"><i class="glyphicon glyphicon-euro"></i> <span>数据统计</span></a></li>
 		<li id="cauditbar"  class="list-group-item"><a style=" font-weight:normal;" href="/manage/caudit"><i class="glyphicon glyphicon-euro"></i> <span>开发者认证</span></a></li>
+		<li id="message"  class="list-group-item"><a style=" font-weight:normal;" href="/manage/message/index"><i class="glyphicon glyphicon-euro"></i> <span>消息管理</span></a></li>
 	</ul>
  <style type="text/css">.glyphicon{font-family:'Glyphicons Halflings';}</style>
 </div>