From f26a0cab5bca17b7eab57f6330e576271e17a17f Mon Sep 17 00:00:00 2001
From: liuxiaolong <736321739@qq.com>
Date: 星期三, 13 十一月 2019 19:12:08 +0800
Subject: [PATCH] update ynSwagger,sync to master

---
 .gitignore                    |    2 
 controllers/cameraTimerule.go |    2 
 service/FaceCompareService.go |   11 
 controllers/es.go             |  403 +++++
 controllers/cameraTaskArgs.go |    4 
 controllers/dbtableperson.go  |  368 +++++
 controllers/task.go           |  116 +
 config/pro.yaml               |   94 +
 util/zip.go                   |  117 +
 controllers/cameraPolygon.go  |    1 
 extend/esutil/EsClient.go     |   14 
 controllers/syssetcont.go     |  194 ++
 extend/sys/sysinfo.go         |   58 
 controllers/camera.go         |   72 
 controllers/monitoring.go     |   19 
 config/test.yaml              |   81 
 models/dbtablepersons.go      |    6 
 controllers/pollConfig.go     |   21 
 extend/sys/system.go          |  235 +++
 controllers/tasklist.go       |   18 
 controllers/taglist.go        |   56 
 extend/config/config.go       |   85 
 service/FDetectClient.go      |   34 
 controllers/cluster.go        |   85 +
 controllers/sysRole.go        |   30 
 controllers/user.go           |  114 +
 extend/code/code.go           |    7 
 middlewares/auth/auth.go      |   81 
 controllers/capture.go        |   18 
 controllers/cameraTask.go     |   20 
 config/dev.yaml               |   69 
 service/SdkDownLoad.go        |  111 +
 controllers/area.go           |   77 
 controllers/esSearch.go       |  144 +
 controllers/sdk.go            |   49 
 service/FaceSdkService.go     |  287 ---
 middlewares/auth/jwt.go       |    4 
 router/router.go              |   91 +
 controllers/dbtablesCon.go    |  107 +
 controllers/fileController.go |  435 ++++-
 config/so.yaml                |    3 
 controllers/cameraPTZ.go      |   73 +
 controllers/eventPush.go      |   26 
 cache/cache.go                |   75 +
 controllers/initForData.go    |   40 
 main.go                       |   74 
 models/esSearch.go            |    6 
 controllers/sysMenu.go        |   40 
 48 files changed, 3,295 insertions(+), 782 deletions(-)

diff --git a/.gitignore b/.gitignore
index 3cb51d5..5f02d6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,5 @@
 .vscode
 .idea
-go.mod
-go.sum
 webserver.exe
 webserver
 docs
\ No newline at end of file
diff --git a/cache/cache.go b/cache/cache.go
index 08bf029..65ca7d7 100644
--- a/cache/cache.go
+++ b/cache/cache.go
@@ -1 +1,76 @@
 package cache
+
+import (
+	"basic.com/dbapi.git"
+	"basic.com/pubsub/protomsg.git"
+	"basic.com/valib/gopherdiscovery.git"
+	"basic.com/pubsub/cache.git/shardmap"
+	"basic.com/valib/logger.git"
+	"errors"
+	"github.com/gogo/protobuf/proto"
+	"fmt"
+	"github.com/satori/go.uuid"
+	"strconv"
+)
+
+const (
+	SERVER_KEY = "SERVERINFO"
+)
+
+var cMap *shardmap.ShardMap
+
+
+func Init(initChan chan bool,dbIp string,surveyPort int,pubSubPort int){
+	cMap = shardmap.New(uint8(32))
+	urlSurvey := "tcp://" + dbIp + ":" + strconv.Itoa(surveyPort)
+	urlPubSub := "tcp://" + dbIp + ":" + strconv.Itoa(pubSubPort)
+	client, _ := gopherdiscovery.ClientWithSub(urlSurvey, urlPubSub, "webServerProc_"+uuid.NewV4().String())
+	recvMsg := client.HeartBeatMsg()
+	fmt.Println(<-recvMsg)
+
+	initCacheData(initChan)
+
+	peers, _ := client.Peers()
+	for b := range peers{
+		updateData(b)
+	}
+}
+
+func initCacheData(initChan chan bool) {
+	initServerInfo()//鍒濆鍖栨湇鍔″櫒閰嶇疆淇℃伅
+
+	initChan <- true
+}
+
+var newUpdateMsg = &protomsg.DbChangeMessage{}
+
+func updateData(b []byte){
+	if err :=proto.Unmarshal(b,newUpdateMsg);err !=nil{
+		logger.Debug("dbChangeMsg unmarshal err:",err)
+		return
+	}
+	switch newUpdateMsg.Table {
+	case protomsg.TableChanged_T_Server:
+		initServerInfo()
+	default:
+		logger.Debug("other updateData operation")
+
+	}
+}
+
+func initServerInfo() {
+	var api dbapi.SysSetApi
+	b, s := api.GetServerInfo()
+	if b{
+		cMap.Set(SERVER_KEY,s)
+	}
+}
+
+func GetServerInfo() (conf protomsg.LocalConfig,err error) {
+	config, b := cMap.Get(SERVER_KEY)
+	if b {
+		return config.(protomsg.LocalConfig),nil
+	} else {
+		return conf,errors.New("conf not found")
+	}
+}
\ No newline at end of file
diff --git a/config/dev.yaml b/config/dev.yaml
index 0a5ece6..a4e7f65 100644
--- a/config/dev.yaml
+++ b/config/dev.yaml
@@ -1,33 +1,43 @@
 server:
     runmode: debug
-    jwtSecret: BASIC    
-    jwtExpire: 24  
+    jwtSecret: BASIC
+    jwtExpire: 24
     url: http://127.0.0.1:8080
-    imageUrl: http://192.168.1.203:6080
-    publicDomain: http://bsic.asuscomm.com
+    analyServerId: DSVAD010120190622
     networkAdapter: enp8s0
-dbpersoncompare:
-    url: 127.0.0.1:40010
-espersoncompare:
-    url:
-     - 127.0.0.1:40011
-weedfs:
-    ip: 192.168.1.203
-    uploadport: 6333
-    visitport: 6080
-redis:
-    host: 127.0.0.1
-    port: 6379
-    password: password
-    db: 1
+    #璁惧缂栧彿
+    deviceNum: 001
+    #璁惧鍨嬪彿
+    deviceType: 鍒嗘瀽璁惧
+    #璁惧搴忓垪鍙�
+    deviceSerialNum: 01
+    #涓绘帶鐗堟湰
+    masterVersion: 1
+    #web鐗堟湰
+    webVersion: 2.0
+    #閫氶亾涓暟
+    channelCount: 0
+    #纭洏涓暟
+    diskCount: 2
 database:
     driver: sqlite
     name: sqlite3
-    filepath: config/testdb
-# es 鏁版嵁 绱㈠紩 浠ュ強 ip 绔彛 閰嶇疆
+    filepath: /opt/vasystem/config/testdb.db
+cluster:
+    pwdpre: bjbasic123
+
+facedetect:
+    ip: 127.0.0.1
+    port: 4009
+dbpersoncompare:
+    ip: 127.0.0.1
+    port: 4010
+espersoncompare:
+    port: 4011
+    ips:
+    - 127.0.0.1
 es:
-    masterip: 192.168.1.182
-    httpport: 9200
+    shards: 1,2,3
     index:
         # 浜鸿劯鎶撴媿璁板綍
         videopersons:
@@ -45,5 +55,16 @@
         personaction:
             index: personaction
             type: perVideoAction
-
-
+#so閰嶇疆
+sopath:
+    ip: 192.168.1.182
+    port: 8008
+#閫氱敤閰嶇疆
+LogBasePath: /opt/vasystem/logs/
+LogLevel: 5
+MaxStreamsNum: 16
+#鎺ㄦ祦
+LibFfmpegPath: /opt/vasystem/bin/libcffmpeg.so
+VideoPublishWidth: 960
+VideoPublishHeight: 640
+VideoPublishPort: 10101
\ No newline at end of file
diff --git a/config/pro.yaml b/config/pro.yaml
index 60b8a0a..f3882e1 100644
--- a/config/pro.yaml
+++ b/config/pro.yaml
@@ -1,24 +1,70 @@
-runmode: release
-timezone: Asia/Chongqing
-dbLogMode: true
-addr: :8080
-name: albedo
-url: http://127.0.0.1:8080
-redis:
-    host: 127.0.0.1
-    port: 6379
-    password: password
-    db: 1
-db:
-# 鍙�夊�硷細mysql銆乻qlite
-    driver: mysql
-    name: db_apiserver
-    addr: 127.0.0.1:3306
-    username: root
-    password: root
-docker_db:
-    driver: mysql
-    name: db_apiserver
-    addr: 127.0.0.1:3306
-    username: root
-    password: root
+server:
+    runmode: debug
+    jwtSecret: BASIC
+    jwtExpire: 24
+    url: http://127.0.0.1:8080
+    analyServerId: DSVAD010120190703
+    networkAdapter: enp8s0
+    #璁惧缂栧彿
+    deviceNum: 001
+    #璁惧鍨嬪彿
+    deviceType: 鍒嗘瀽璁惧
+    #璁惧搴忓垪鍙�
+    deviceSerialNum: 01
+    #涓绘帶鐗堟湰
+    masterVersion: 1
+    #web鐗堟湰
+    webVersion: 2.0
+    #閫氶亾涓暟
+    channelCount: 0
+    #纭洏涓暟
+    diskCount: 2
+database:
+    driver: sqlite
+    name: sqlite3
+    filepath: /opt/vasystem/config/testdb.db
+cluster:
+    pwdpre: bjbasic123
+
+facedetect:
+    ip: 127.0.0.1
+    port: 4009
+dbpersoncompare:
+    ip: 127.0.0.1
+    port: 4010
+espersoncompare:
+    port: 4011
+    ips:
+    - 127.0.0.1
+es:
+    shards: 1,2,3
+    index:
+        # 浜鸿劯鎶撴媿璁板綍
+        videopersons:
+            index: videopersons
+            type: perVideoPicture
+        # 搴曞簱 鍒楄〃
+        dbtables:
+            index: dbtables
+            type: dbpersontables
+        # 搴曞簱浜哄憳搴�
+        dbtablepersons:
+            index: dbtablepersons
+            type: dbpersons
+        # 琛屼负鎶撴媿璁板綍*
+        personaction:
+            index: personaction
+            type: perVideoAction
+#so閰嶇疆
+sopath:
+    ip: 192.168.1.182
+    port: 8008
+#閫氱敤閰嶇疆
+LogBasePath: /data/disk1/valog/
+LogLevel: 5
+MaxStreamsNum: 16
+#鎺ㄦ祦
+LibFfmpegPath: /opt/vasystem/bin/libcffmpeg.so
+VideoPublishWidth: 960
+VideoPublishHeight: 640
+VideoPublishPort: 10101
\ No newline at end of file
diff --git a/config/so.yaml b/config/so.yaml
index e69de29..b948025 100644
--- a/config/so.yaml
+++ b/config/so.yaml
@@ -0,0 +1,3 @@
+sopath:
+  ip: 192.168.1.182
+  port: 8008
\ No newline at end of file
diff --git a/config/test.yaml b/config/test.yaml
index cd8dca9..52e4d1e 100644
--- a/config/test.yaml
+++ b/config/test.yaml
@@ -3,31 +3,57 @@
     jwtSecret: BASIC
     jwtExpire: 24
     url: http://127.0.0.1:8080
-    imageUrl: http://192.168.1.203:6080
-    publicDomain: http://192.168.1.203
+    analyServerId: DSVAD010120190703
     networkAdapter: enp8s0
-dbpersoncompare:
-    url: 127.0.0.1:40010
-espersoncompare:
-    url:
-    - 127.0.0.1:40011
-weedfs:
-    ip: 192.168.1.203
-    uploadport: 6333
-    visitport: 6080
-redis:
-    host: 127.0.0.1
-    port: 6379
-    password: password
-    db: 1
+    #璁惧缂栧彿
+    deviceNum: 001
+    #璁惧鍨嬪彿
+    deviceType: 鍒嗘瀽璁惧
+    #璁惧搴忓垪鍙�
+    deviceSerialNum: 01
+    #涓绘帶鐗堟湰
+    masterVersion: 1
+    #web鐗堟湰
+    webVersion: 2.0
+    #閫氶亾涓暟
+    channelCount: 0
+    #纭洏涓暟
+    diskCount: 2
+    #Exec root command
+    sudoPassword: 123
+    sysThresholds:
+    -
+        value: 60
+        color: '#13ce66'
+    -
+        value: 80
+        color: '#FF9C4A'
+    -
+        value: 95
+        color: '#f53d3d'
+    -
+        value: 100
+        color: '#5d0000'
+    ptzSpeed: 50
 database:
     driver: sqlite
     name: sqlite3
-    filepath: config/testdb
-# es 鏁版嵁 绱㈠紩 浠ュ強 ip 绔彛 閰嶇疆
+    filepath: /opt/vasystem/config/testdb.db
+cluster:
+    pwdpre: bjbasic123
+
+facedetect:
+    ip: 127.0.0.1
+    port: 4009
+dbpersoncompare:
+    ip: 127.0.0.1
+    port: 4010
+espersoncompare:
+    port: 4011
+    ips:
+    - 127.0.0.1
 es:
-    masterip: 192.168.1.182
-    httpport: 9200
+    shards: 1,2,3
     index:
         # 浜鸿劯鎶撴媿璁板綍
         videopersons:
@@ -45,5 +71,16 @@
         personaction:
             index: personaction
             type: perVideoAction
-
-
+#so閰嶇疆
+sopath:
+    ip: 192.168.1.182
+    port: 8008
+#閫氱敤閰嶇疆
+LogBasePath: /opt/vasystem/logs/
+LogLevel: 5
+MaxStreamsNum: 16
+#鎺ㄦ祦
+LibFfmpegPath: /opt/vasystem/bin/libcffmpeg.so
+VideoPublishWidth: 960
+VideoPublishHeight: 640
+VideoPublishPort: 10101
\ No newline at end of file
diff --git a/controllers/area.go b/controllers/area.go
index 4d5771f..59e7f97 100644
--- a/controllers/area.go
+++ b/controllers/area.go
@@ -14,13 +14,17 @@
 	Id string `json:"id"`
 	ParentId string `json:"parentId"`
 	Name string `json:"name"`
+	Alias string `json:"alias"`
 }
 
 // @Summary 鏄剧ず鏍戝舰缁撴瀯
 // @Description 鏄剧ず宸︿晶鎵�鏈夊尯鍩熷拰鎽勫儚鏈�
+// @Security ApiKeyAuth
 // @Produce json
 // @Tags menu
-// @Param parentid query int true "鍖哄煙鐨刬d"
+// @Param parentid query string true "鍖哄煙鐨刬d"
+// @Param searchType query int true "鏌ヨ绫诲瀷锛�0锛氬叏閮紝1锛氬垎鏋愭憚鍍忔満锛�2锛氱洃鎺ф憚鍍忔満锛�"
+// @Param cameraName query string false "鎽勫儚鏈哄悕绉�"
 // @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁"}"
 // @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅"}"
 // @Router /data/api-v/area/localmenu [get]
@@ -36,12 +40,15 @@
 
 // @Summary 鏄剧ずGb28181鏍戝舰缁撴瀯
 // @Description 鏄剧ずGb28181鏍戝舰缁撴瀯
+// @Security ApiKeyAuth
 // @Produce json
 // @Tags menu
-// @Param parentid query int true "鍖哄煙鐨刬d"
+// @Param parentid query string true "鍖哄煙鐨刬d"
+// @Param searchType query int true "鏌ヨ绫诲瀷锛�0锛氬叏閮紝1锛氬垎鏋愭憚鍍忔満锛�2锛氱洃鎺ф憚鍍忔満锛�"
+// @Param cameraName query string false "鎽勫儚鏈哄悕绉�"
 // @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁"}"
 // @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅"}"
-// @Router /data/api-v/area/localmenu [get]
+// @Router /data/api-v/area/gb28181Tree [get]
 func (ac AreaController) CameraGb28181Tree(c *gin.Context) {
 	parentIdStr := c.Query("parentid")
 	searchTypeStr := c.Query("searchType")
@@ -52,12 +59,52 @@
 	util.ResponseFormat(c, code.Success, arr)
 }
 
-// @Summary 娣诲姞menu鐨勫尯鍩�
-// @Description 娣诲姞鐩綍涓婂尯鍩�
+// @Security ApiKeyAuth
+// @Accept x-www-form-urlencoded
+// @Summary 鍒锋柊Gb28181骞冲彴鏍�
+// @Description 鍒锋柊Gb28181骞冲彴鏍�
 // @Produce json
 // @Tags menu
-// @Param name query string true "鍖哄煙鍚嶅瓧"
-// @Param parentId query int true "涓婁竴绾х埗id"
+// @Param id formData string false "鍥芥爣骞冲彴id"
+// @Success 200 {string} json "{"code":200, data:"",msg:"璇锋眰鎴愬姛", success:true}"
+// @Failure 200 {string} json "{"code":500, data:"",msg:"璇锋眰澶辫触", success:false}"
+// @Router /data/api-v/area/gb28181TreeRefresh [post]
+func (ac AreaController) Gb28181TreeRefresh(c *gin.Context) {
+	id := c.PostForm("id")
+
+	var api dbapi.AreaApi
+	if api.Gb28181TreeRefresh(id) {
+		util.ResponseFormat(c,code.UpdateSuccess,"鏇存柊鎴愬姛")
+	} else {
+		util.ResponseFormat(c,code.UpdateFail, "鏇存柊澶辫触")
+	}
+}
+
+// @Security ApiKeyAuth
+// @Summary 鍒犻櫎Gb28181骞冲彴
+// @Description 鍒犻櫎Gb28181骞冲彴
+// @Produce json
+// @Tags menu
+// @Success 200 {string} json "{"code":200, data:"",msg:"璇锋眰鎴愬姛", success:true}"
+// @Failure 200 {string} json "{"code":500, data:"",msg:"璇锋眰澶辫触", success:false}"
+// @Router /data/api-v/area/gb28181TreeDelete [post]
+func (ac AreaController) Gb28181TreeDelete(c *gin.Context) {
+	var api dbapi.AreaApi
+	if api.Gb28181TreeDelete() {
+		util.ResponseFormat(c,code.DelSuccess,"鍒犻櫎鎴愬姛")
+	} else {
+		util.ResponseFormat(c,code.ComError, "鍒犻櫎澶辫触")
+	}
+}
+
+// @Security ApiKeyAuth
+// @Summary 娣诲姞menu鐨勫尯鍩�
+// @Description 娣诲姞鐩綍涓婂尯鍩�
+// @Accept x-www-form-urlencoded
+// @Produce json
+// @Tags menu
+// @Param name formData string true "鍖哄煙鍚嶅瓧"
+// @Param parentId formData string true "涓婁竴绾х埗id"
 // @Success 200 {string} json "{"code":200, data:"娣诲姞鐨勫尯鍩熶俊鎭�",msg:"璇锋眰鎴愬姛", success:true}"
 // @Failure 200 {string} json "{"code":"閿欒鐮�", data:"鍑洪敊淇℃伅",msg:"璇锋眰澶辫触", success:false}"
 // @Router /data/api-v/area/add [post]
@@ -79,14 +126,16 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 淇敼鍚嶅瓧
 // @Description 淇敼鍖哄煙鍚嶅瓧
-// @Accept  json
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags menu
-// @Param id query int true "鍖哄煙id"
-// @Param name query string true "鍖哄煙鍚嶅瓧"
-// @Param parentId query int true "涓婁竴绾х埗id"
+// @Param id formData string true "鍖哄煙id"
+// @Param name formData string true "鍖哄煙鍚嶅瓧"
+// @Param parentId formData string true "涓婁竴绾х埗id"
+// @Param alias formData string false "澶囨敞鍚嶇О"
 // @Success 200 {string} json "{"code":200, data:"",msg:"璇锋眰鎴愬姛", success:true}"
 // @Failure 200 {string} json "{"code":"閿欒鐮�", data:"鍑洪敊淇℃伅",msg:"璇锋眰澶辫触", success:false}"
 // @Router /data/api-v/area/update [post]
@@ -102,10 +151,12 @@
 		util.ResponseFormat(c, code.RequestParamError, "parentId鍙傛暟閿欒")
 		return
 	}
+	alias := c.PostForm("alias")
 	var model = AreaVo{
 		Id:id,
 		ParentId:parentId,
 		Name:name,
+		Alias: alias,
 	}
 	paramBody := util.Struct2Map(model)
 	var api dbapi.AreaApi
@@ -116,11 +167,13 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 鍒犻櫎涓�涓尯鍩�
 // @Description 鐐瑰嚮鍒犻櫎鎸夐挳鏃跺垹闄や竴涓尯鍩�
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags menu
-// @Param id query int true "褰撳墠id"
+// @Param id formData string true "褰撳墠id"
 // @Success 200 {string} json "{"code":200, data:"鍒犻櫎鐨勫尯鍩熶俊鎭�",msg:"璇锋眰鎴愬姛", success:true}"
 // @Failure 200 {string} json "{"code":"閿欒鐮�", data:"鍑洪敊淇℃伅",msg:"璇锋眰澶辫触", success:false}"
 // @Router /data/api-v/area/del [post]
diff --git a/controllers/camera.go b/controllers/camera.go
index 415fece..5b3a707 100644
--- a/controllers/camera.go
+++ b/controllers/camera.go
@@ -12,6 +12,7 @@
 	"webserver/extend/code"
 	"webserver/extend/util"
     "webserver/service"
+	"webserver/cache"
 )
 
 type CameraController struct{}
@@ -19,6 +20,7 @@
 type CameraVo struct {
 	Id        string  `json:"id"`
 	Name      string  `json:"name"`
+	Alias     string  `json:"alias"` //鎽勫儚鏈虹殑鍒悕
 	Type      int     `json:"type" `
 	Addr      string  `json:"addr"`
 	Areaid    string  `json:"areaid"`
@@ -40,6 +42,7 @@
 
 // @Summary 娣诲姞鎽勫儚鏈�
 // @Description  "浼犲叆鍖哄煙鐨刬d锛坅reaid锛夊拰鎽勫儚鏈哄悕瀛�(name) 蹇呴』锛� 鍏朵粬鍙傛暟鍙互鍦ㄦ憚鍍忔満閰嶇疆鐐瑰嚮淇濆瓨杩涜娣诲姞"
+// @Security ApiKeyAuth
 // @Accept json
 // @Produce json
 // @Tags camera
@@ -56,10 +59,10 @@
 		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟閿欒")
 		return
 	}
-	cam.Id = util.PseudoUuid()
 	paramBody := util.Struct2Map(cam)
-	if api.CameraAdd(paramBody) {
-		util.ResponseFormat(c, code.Success, cam)
+	b, data := api.CameraAdd(paramBody)
+	if b {
+		util.ResponseFormat(c, code.Success, data)
 		return
 	}
 	util.ResponseFormat(c, code.ComError, err)
@@ -68,6 +71,7 @@
 
 // @Summary 鏇存柊鎽勫儚鏈�
 // @Description "鐢ㄤ簬鏇存柊鎽勫儚鏈烘搷浣�"
+// @Security ApiKeyAuth
 // @Accept json
 // @Produce json
 // @Tags camera
@@ -95,6 +99,7 @@
 
 // @Summary "鍒犻櫎鎽勫儚鏈�"
 // @Description "鏍规嵁鎽勫儚鏈篿d鍒犻櫎鎽勫儚鏈�"
+// @Security ApiKeyAuth
 // @Produce json
 // @Tags camera
 // @Param cid path string true "鎽勫儚鏈篿d example: cid0"
@@ -114,11 +119,12 @@
 
 // @Summary 鏄剧ず鎽勫儚鏈�
 // @Description "鏄剧ず鎽勫儚鏈�"
+// @Security ApiKeyAuth
 // @Produce json
 // @Tags camera
 // @Param cid path string true "鎽勫儚鏈篿d"
-// @Success 200 {string} json "{"code":200, success:true,  msg:"璇锋眰澶勭悊鎴愬姛", data:"鎽勫儚鏈轰俊鎭�"}"
-// @Failure 500 {string} json "{"code":500, success:false   msg:"",data:"閿欒淇℃伅鍐呭"}"
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/camera/show/{cid} [get]
 func (ac CameraController) CameraSel(c *gin.Context) {
 	var api dbapi.CameraApi
@@ -128,8 +134,35 @@
 		util.ResponseFormat(c, code.ComError, "鏌ヨ澶辫触")
 		return
 	}
-
-	util.ResponseFormat(c, code.Success, camera)
+	//2019-11-02鏂板闇�姹傦紝鏄剧ず姣忎釜鎽勫儚鏈虹殑澶勭悊鏈嶅姟鍣ㄤ俊鎭�,褰掑睘鐨勮妭鐐规湇鍔″櫒鍚嶇О
+	m := util.Struct2Map(camera)
+	m["runServerName"] = ""
+	if camera.RunServerId !="" {
+		localConf, e := cache.GetServerInfo()
+		if e ==nil {
+			if camera.RunServerId == localConf.ServerId {//褰掑睘鏈彴鏈嶅姟鍣�
+				m["runServerName"] = localConf.ServerName
+			} else {//灞炰簬鍏朵粬鏈嶅姟鍣�
+				var clusterApi dbapi.ClusterApi
+				b, data := clusterApi.FindCluster()
+				if b && data !=nil {
+					cb, _ := json.Marshal(data)
+					var clu ClusterDb
+					if err := json.Unmarshal(cb, &clu);err ==nil {
+						if len(clu.Nodes) >0 {
+							for _,n :=range clu.Nodes {
+								if camera.RunServerId == n.NodeId {
+									m["runServerName"] = n.NodeName
+									break
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	util.ResponseFormat(c, code.Success, m)
 
 }
 
@@ -178,6 +211,22 @@
 	fmt.Println(areaId)
 }
 
+func (cc CameraController) GetAllCamerasByServer(c *gin.Context) {
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		util.ResponseFormat(c,code.ComError,"鏈嶅姟鍣ㄦ湰鏈烘湭閰嶇疆serverId")
+		return
+	}
+	var api dbapi.CameraApi
+	cameraName := c.Query("cameraName")
+	b,d := api.GetAllCamerasByServer(localConf.ServerId, cameraName)
+	if b {
+		util.ResponseFormat(c,code.Success, d)
+	} else {
+		util.ResponseFormat(c,code.ComError, "")
+	}
+}
 
 func (cc CameraController) GetCamerasByRunType(c *gin.Context) {
 
@@ -254,4 +303,13 @@
 	}
 }
 
+func (cc CameraController) StatisticRunInfo(c *gin.Context) {
+	var api dbapi.CameraApi
+	b, d := api.StatisticRunInfo()
+	if b {
+		util.ResponseFormat(c,code.Success,d)
+	} else {
+		util.ResponseFormat(c,code.ComError,"")
+	}
+}
 
diff --git a/controllers/cameraPTZ.go b/controllers/cameraPTZ.go
index 2d32936..a96f7b0 100644
--- a/controllers/cameraPTZ.go
+++ b/controllers/cameraPTZ.go
@@ -1 +1,74 @@
 package controllers
+
+import (
+	"basic.com/dbapi.git"
+	"basic.com/gb28181api.git"
+
+	"webserver/extend/code"
+	"webserver/extend/config"
+	"webserver/extend/util"
+
+	"github.com/gin-gonic/gin"
+)
+
+type PanTiltZoomController struct {
+}
+
+type PTZInstruct struct {
+	CameraId   string `json:"cameraId"`   //鎽勫儚鏈篿d
+	CameraType int    `json:"cameraType"` //鎽勫儚鏈虹被鍨�
+	PTZType    string `json:"ptzType"`    //鎺у埗绫诲瀷 left right top ... stop
+}
+
+/*
+// @Summary 浜戝彴
+// @Description 鎽勫儚鏈轰簯鍙版帶鍒�
+// @Security ApiKeyAuth
+// @Accept json
+// @Produce json
+// @Tags camera
+// @Param ptzBody body controllers.PTZInstruct true "鎺у埗绫诲瀷锛歶p,down,left,right,zoomin,zoomout,stop"
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-v/camera/ptzControl [post]
+*/
+func (ptz PanTiltZoomController) Move(c *gin.Context) {
+	var param PTZInstruct
+	if err := c.BindJSON(&param); err != nil {
+		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+
+	ptzSpeed := config.Server.PTZSpeed
+	if ptzSpeed == 0 {
+		ptzSpeed = 50
+	}
+
+	if param.CameraType == 1 {
+		var api dbapi.SysSetApi
+		r, gb28182Config := api.Gb28181ConfigShow()
+
+		if r {
+			conf, ok := gb28182Config.(map[string]interface{})
+			if ok {
+				gb28181api.Init(conf["ServerIp"].(string), int(conf["ServerPort"].(float64)))
+			} else {
+				util.ResponseFormat(c, code.ComError, "鍥芥爣閰嶇疆璇诲彇澶辫触")
+				return
+			}
+
+		} else {
+			util.ResponseFormat(c, code.ComError, "鍥芥爣鎺ュ彛鏌ヨ澶辫触")
+			return
+		}
+
+		var gbApi gb28181api.Gb28181Api
+		if r := gbApi.SetCameraPtz(param.CameraId, param.PTZType, ptzSpeed); r {
+			util.ResponseFormat(c, code.Success, "")
+		} else {
+			util.ResponseFormat(c, code.Success, "鍥芥爣鎺ュ彛鎿嶄綔澶辫触")
+		}
+	} else {
+		util.ResponseFormat(c, code.Success, "涓嶆敮鎸佺殑鎽勫儚鏈虹被鍨�")
+	}
+}
diff --git a/controllers/cameraPolygon.go b/controllers/cameraPolygon.go
index 24922e2..0ba4708 100644
--- a/controllers/cameraPolygon.go
+++ b/controllers/cameraPolygon.go
@@ -45,7 +45,6 @@
 	util.ResponseFormat(c,code.ComError,"淇濆瓨澶辫触")
 }
 
-
 func (controller CameraPolygonController) Delete(c *gin.Context) {
 	id := c.Query("id")
 	if id == "" {
diff --git a/controllers/cameraTask.go b/controllers/cameraTask.go
index 7f6dca2..0e1bc74 100644
--- a/controllers/cameraTask.go
+++ b/controllers/cameraTask.go
@@ -86,6 +86,25 @@
 	}
 }
 
+func (ctc CameraTaskController) AddTask(c *gin.Context) {
+	cameraId := c.PostForm("cameraId")
+	taskId := c.PostForm("taskId")
+	if cameraId == "" || taskId == "" {
+		util.ResponseFormat(c,code.RequestParamError,"鍙傛暟鏈夎")
+		return
+	}
+	var api dbapi.CameraTaskApi
+	if b,data := api.AddTask(cameraId, taskId);b {
+		util.ResponseFormat(c,code.AddSuccess, data)
+	} else {
+		if data.(string) == "姝ゅ浗鏍囨憚鍍忔満宸插湪鍏跺畠鏈嶅姟鍣ㄩ厤缃换鍔★紒" {
+			util.ResponseFormat(c,code.AddTaskErr, data)
+		} else {
+			util.ResponseFormat(c,code.ComError, data)
+		}
+	}
+}
+
 func (controller CameraTaskController) CameraTaskAll(c *gin.Context) {
 	cameraId := c.Param("cameraId")
 	if cameraId == "" {
@@ -100,7 +119,6 @@
 		util.ResponseFormat(c,code.ComError,data)
 	}
 }
-
 
 func (ac CameraController) CameraTaskSave(c *gin.Context) {
 	var saveBody CameraTaskSaveArg
diff --git a/controllers/cameraTaskArgs.go b/controllers/cameraTaskArgs.go
index c8ec3b3..e28e5ec 100644
--- a/controllers/cameraTaskArgs.go
+++ b/controllers/cameraTaskArgs.go
@@ -5,14 +5,13 @@
 	"github.com/gin-gonic/gin"
 	"strconv"
 	"webserver/extend/code"
-	"webserver/extend/logger"
+	"basic.com/valib/logger.git"
 	"webserver/extend/util"
 )
 
 type CameraTaskArgsController struct {
 
 }
-
 
 func (controller CameraTaskArgsController) FindByCameraAndTask(c *gin.Context) {
 	cameraId := c.Query("cameraId")
@@ -107,7 +106,6 @@
 	RuleWithPre string `json:"rule_with_pre"`//涓庝笂涓�鏉¤褰曠殑閫昏緫杩愮畻瑙勫垯锛�&&,||锛�
 	GroupId string `json:"group_id"`//鍒嗙粍id
 }
-
 
 func (controller CameraTaskArgsController) SaveLinkRulesByGroup(c *gin.Context) {
 	var saveBody SaveLinkRulesGroupVo
diff --git a/controllers/cameraTimerule.go b/controllers/cameraTimerule.go
index 33b9883..1031d30 100644
--- a/controllers/cameraTimerule.go
+++ b/controllers/cameraTimerule.go
@@ -53,7 +53,6 @@
 	util.ResponseFormat(c,code.ComError,"淇濆瓨澶辫触")
 }
 
-
 func (controller CameraTimeruleController) Delete(c *gin.Context) {
 	id := c.Query("id")
 	if id == "" {
@@ -67,7 +66,6 @@
 	}
 	util.ResponseFormat(c, code.ComError, "鍒犻櫎澶辫触")
 }
-
 
 func (controller CameraTimeruleController) FindAll(c *gin.Context) {
 	var api dbapi.CameraApi
diff --git a/controllers/capture.go b/controllers/capture.go
index de43401..94abac1 100644
--- a/controllers/capture.go
+++ b/controllers/capture.go
@@ -1,10 +1,12 @@
 package controllers
 
 import (
-	"basic.com/dbapi.git"
+	"basic.com/valib/logger.git"
 	"fmt"
 	"github.com/gin-gonic/gin"
+	"strconv"
 	"strings"
+	"webserver/cache"
 	"webserver/extend/code"
 	"webserver/extend/config"
 	"webserver/extend/esutil"
@@ -17,6 +19,7 @@
 	TreeNodes []string `json:"treeNodes"`
 }
 
+// @Security ApiKeyAuth
 // @Summary 瀹炴椂鎶撴媿
 // @Description 瀹炴椂鎶撴媿鏁版嵁
 // @Accept  json
@@ -38,12 +41,16 @@
 		cameraIdStr = "{\"terms\":{\"cameraId\":[\"" + esCameraId + "\"]}},"
 	}
 	//璇锋眰澶�
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		util.ResponseFormat(c,code.ComError,"es config err")
+		return
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + index + "/_search"
 
-	var setApi dbapi.SysSetApi
-	_, sysconf := setApi.GetServerInfo()
-	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + sysconf.ServerId + "\"}},"
+	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + localConf.ServerId + "\"}},"
 
 	prama := "{\"query\":{\"bool\":{\"filter\":[" +
 		cameraIdStr +
@@ -52,7 +59,6 @@
 		"\"sort\":[{\"picDate\":{\"order\":\"desc\"}}]," +
 		"\"size\":\"1000\"," +
 		"\"_source\":[\"baseInfo\",\"alarmRules\",\"sex\",\"analyServerName\",\"sdkName\",\"ageDescription\",\"content\",\"id\",\"cameraAddr\",\"picMaxUrl\",\"picDate\",\"race\",\"videoUrl\",\"picSmUrl\",\"taskName\",\"personIsHub\",\"isAlarm\",\"analyServerIp\",\"cameraId\"]}"
-	fmt.Println(prama)
 	tokenRes := esutil.GetEsDataReq(url, prama, true)
 	util.ResponseFormat(c, code.Success, tokenRes)
 }
diff --git a/controllers/cluster.go b/controllers/cluster.go
index 873901e..5a780a9 100644
--- a/controllers/cluster.go
+++ b/controllers/cluster.go
@@ -40,6 +40,7 @@
 	Password string `json:"password"`
 	ClusterName string `json:"clusterName"`
 	ClusterId string `json:"clusterId"`
+	VirtualIp string `json:"virtualIp"`
 }
 
 type ClusterSearchVo struct {
@@ -53,6 +54,21 @@
 	NodeIps []string `json:"nodeIps"`
 }
 
+type ClusterDb struct {
+	ClusterId   string `json:"clusterId"`
+	ClusterName string `json:"clusterName"`
+	Nodes []NodeDb     `json:"nodes"`
+}
+type NodeDb struct {
+	Id string `json:"id"`
+	ClusterId string `json:"cluster_id"`
+	NodeName string `json:"node_name"`
+	NodeId string `json:"node_id"`
+	NodeIp string `json:"node_ip"`
+	CreateTime string `json:"create_time"`
+	IsDelete bool `json:"isDelete"`
+}
+
 
 func (cc ClusterController) Create(c *gin.Context) {
 	var clusterVo ClusterCreateVo
@@ -62,7 +78,7 @@
 		return
 	}
 	var api dbapi.ClusterApi
-	b, d := api.Create(clusterVo.ClusterName, clusterVo.Password)
+	b, d := api.Create(clusterVo.ClusterName, clusterVo.Password, clusterVo.VirtualIp)
 	if b {
 		util.ResponseFormat(c,code.Success, d)
 	} else {
@@ -76,6 +92,25 @@
 	util.ResponseFormat(c,code.Success,pwd)
 }
 
+/*
+// @Security ApiKeyAuth
+// @Summary 鏌ヨ鏈湴闆嗙兢
+// @Description 鏌ヨ鏈湴闆嗙兢
+// @Produce json
+// @Tags cluster
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-v/cluster/findCluster [get]
+*/
+func (cc ClusterController) FindCluster(c *gin.Context) {
+	var clusterApi dbapi.ClusterApi
+	b, d := clusterApi.FindCluster()
+	if b {
+		util.ResponseFormat(c,code.Success, d)
+	} else {
+		util.ResponseFormat(c,code.ComError,"闆嗙兢鏌ヨ澶辫触")
+	}
+}
 
 func (cc ClusterController) Search(c *gin.Context) {
 	var csv ClusterSearchVo
@@ -137,3 +172,51 @@
 		util.ResponseFormat(c,code.ComError,"鍔犲叆澶辫触")
 	}
 }
+
+/*
+// @Security ApiKeyAuth
+// @Summary 淇濆瓨闆嗙兢鍚嶇О
+// @Description 淇濆瓨闆嗙兢鍚嶇О
+// @Accept x-www-form-urlencoded
+// @Produce json
+// @Tags cluster
+// @Param clusterName formData string true "闆嗙兢鍚嶇О"
+// @Param virtualIp formData string false "铏氭嫙ip"
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-v/cluster/updateClusterName [post]
+*/
+func (cc ClusterController) UpdateClusterName(c *gin.Context) {
+	clusterName := c.PostForm("clusterName")
+	if clusterName == "" {
+		util.ResponseFormat(c,code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+	virtualIp := c.PostForm("virtualIp")
+	var api dbapi.ClusterApi
+	b,_ := api.UpdateClusterName(clusterName,virtualIp)
+	if b {
+		util.ResponseFormat(c,code.UpdateSuccess,"鏇存柊鎴愬姛")
+	} else {
+		util.ResponseFormat(c,code.ComError, "鏇存柊澶辫触")
+	}
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 閫�鍑洪泦缇�
+// @Description 閫�鍑洪泦缇�
+// @Produce json
+// @Tags cluster
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-v/cluster/leave [post]
+*/
+func (cc ClusterController) Leave(c *gin.Context) {
+	var api dbapi.ClusterApi
+	if b,_:= api.Leave();b {
+		util.ResponseFormat(c,code.Success,"閫�鍑烘垚鍔�")
+	} else {
+		util.ResponseFormat(c,code.ComError,"閫�鍑哄け璐�")
+	}
+}
\ No newline at end of file
diff --git a/controllers/dbtableperson.go b/controllers/dbtableperson.go
index 0cc064d..baac15e 100644
--- a/controllers/dbtableperson.go
+++ b/controllers/dbtableperson.go
@@ -2,8 +2,14 @@
 
 import (
 	"basic.com/dbapi.git"
+	"basic.com/fileServer/WeedFSClient.git"
+	"basic.com/pubsub/protomsg.git"
+	"encoding/base64"
 	"encoding/json"
+	"io/ioutil"
+	"sort"
 	"strconv"
+	"time"
 	"webserver/extend/logger"
 
 	"github.com/gin-gonic/gin"
@@ -13,19 +19,24 @@
 	"webserver/extend/esutil"
 	"webserver/extend/util"
 	"webserver/models"
+	"webserver/cache"
+	"webserver/service"
+
+	esApi "basic.com/pubsub/esutil.git"
 )
 
 type DbPersonController struct {
 }
 
+// @Security ApiKeyAuth
 // @Summary 娣诲姞搴曞簱浜哄憳
 // @Description 娣诲姞搴曞簱浜哄憳
 // @Accept  json
 // @Produce json
 // @Tags dbperson 搴曞簱浜哄憳
 // @Param obj body models.Dbtablepersons true "搴曞簱浜哄憳鏁版嵁"
-// @Success 200 {string} json "{"code":200, msg:"", success:true}"
-// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"杩斿洖閿欒淇℃伅", success:false}"
 // @Router /data/api-v/dbperson/addDbPerson [PUT]
 func (dbc DbPersonController) AddDbPerson(c *gin.Context) {
 	dbperson := new(models.Dbtablepersons)
@@ -71,6 +82,7 @@
 	return result
 }
 
+// @Security ApiKeyAuth
 // @Summary 淇敼搴曞簱浜哄憳
 // @Description 淇敼搴曞簱浜哄憳
 // @Accept  json
@@ -99,7 +111,12 @@
 }
 
 func UpdateDbPersonsOfDbTable(id string) (message string) {
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return "淇敼澶辫触"
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + config.EsInfo.EsIndex.Dbtablepersons.IndexName + "/_update_by_query?refresh"
 	jsonDSL := `
 			{
@@ -138,6 +155,222 @@
 	return message
 }
 
+// @Security ApiKeyAuth
+// @Summary 搴曞簱浜哄憳浠ュ浘鎼滃浘
+// @Description 搴曞簱浜哄憳浠ュ浘鎼滃浘
+// @Accept  json
+// @Produce json
+// @Tags dbperson 搴曞簱浜哄憳
+// @Param condition body models.EsSearch true "搴曞簱浠ュ浘鎼滃浘鍙傛暟"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/dbperson/queryDbPersonsByCompare [POST]
+func (dbc DbPersonController) QueryDbPersonsByCompare(c *gin.Context) {
+	var searchBody models.EsSearch
+	err := c.BindJSON(&searchBody)
+	if err !=nil || searchBody.PicUrl == "" || len(searchBody.DataBases) == 0{
+		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+	var faceB []byte
+	if face,ok := faceExtractedMap[searchBody.PicUrl];!ok{
+		util.ResponseFormat(c, code.RequestParamError, "璇烽噸鏂颁笂浼犲浘鐗�")
+		return
+	} else {
+		faceB = face.FaceBytes
+	}
+
+	analyServerId := ""
+	conf, e := cache.GetServerInfo()
+	if e ==nil && conf.ServerId != "" {
+		analyServerId = conf.ServerId
+	} else {
+		util.ResponseFormat(c, code.ComError, "analyServerId涓虹┖锛岄厤缃湁璇�")
+		return
+	}
+
+	arg := protomsg.CompareArgs{
+		FaceFeature: faceB,
+		CompareThreshold: searchBody.Threshold,
+	}
+	arg.TableIds = searchBody.DataBases
+	arg.AnalyServerId = analyServerId
+	compareService := service.NewFaceCompareService(arg)
+	var totalData service.CompareList
+
+	dbPersonTargets := compareService.CompareDbPersons()
+	if dbPersonTargets !=nil {
+		totalData = append(totalData,*dbPersonTargets...)
+	}
+
+	service.SetCompResultByNum(&service.CompareOnce{
+		CompareNum: compareService.CompareNum,
+		CompareData: &totalData,
+	})
+
+	m := make(map[string]interface{},3)
+	if totalData != nil && totalData.Len() > 0{
+		sort.Sort(totalData)
+		total := totalData.Len()
+
+		m["compareNum"] = compareService.CompareNum
+		m["total"] = total
+		var sCompResult protomsg.SdkCompareResult
+		if total <= searchBody.Size {
+			sCompResult.CompareResult = totalData
+		} else {
+			sCompResult.CompareResult = totalData[0:searchBody.Size]
+		}
+		resultList := FillDbPersonDataToCompareResult(&sCompResult)
+		m["totalList"] = resultList
+
+	} else {
+		m["total"] = 0
+		m["compareNum"] = compareService.CompareNum
+		m["totalList"] = []CompareResult{}
+	}
+	util.ResponseFormat(c,code.Success,m)
+}
+
+//濉厖鍚戝墠绔繑鍥炵殑鏁版嵁
+func FillDbPersonDataToCompareResult(compResult *protomsg.SdkCompareResult) []models.DbPersonsCompVo {
+
+	var resultList = make([]models.DbPersonsCompVo, len(compResult.CompareResult))
+	dbPersonM := make(map[string]ScoreIndex, 0)
+	personIds := make([]string,0)
+
+	for idx,v :=range compResult.CompareResult{
+		dbPersonM[v.Id] = ScoreIndex{
+			Index: idx,
+			CompareScore: v.CompareScore,
+		}
+		personIds = append(personIds,v.Id)
+	}
+	logger.Debug("comp len(personIds):", len(personIds))
+
+	var dbpersons []protomsg.Dbperson
+	if len(personIds) >0 {
+		var dbpApi dbapi.DbPersonApi
+		dbpersons, _ = dbpApi.Dbpersoninfosbyid(personIds)
+	}
+
+	if len(dbpersons) >0 {
+		//var dtApi dbapi.DbTableApi
+		for _,p :=range dbpersons {
+			var dbP models.DbPersonsCompVo
+
+			dbP.Id = p.Id
+			dbP.TableId = p.TableId
+			dbP.FaceFeature = p.FaceFeature
+			dbP.PersonPicUrl = p.PersonPicUrl
+			dbP.PersonName = p.PersonName
+			dbP.Age = p.Age
+			dbP.Sex = p.Sex
+			dbP.IdCard = p.IdCard
+			dbP.PhoneNum = p.PhoneNum
+			dbP.MonitorLevel = p.MonitorLevel
+			dbP.Reserved = p.Reserved
+			dbP.IsDelete = int(p.IsDelete)
+			dbP.Enable = int(p.Enable)
+			dbP.CreateTime = p.CreateTime
+			dbP.UpdateTime = p.UpdateTime
+			dbP.CreateBy = p.CreateBy
+			dbP.CompareScore = util.ParseScore(dbPersonM[p.Id].CompareScore)
+			//dbTableInfos, _ := dtApi.DbtablesById([]string{ p.TableId })
+			//if dbTableInfos !=nil{
+			//	dbP.BwType = dbTableInfos[0].BwType
+			//	dbP.TableName = dbTableInfos[0].TableName
+			//}
+			resultList[dbPersonM[p.Id].Index] = dbP
+		}
+	}
+
+	return  resultList
+}
+
+// @Security ApiKeyAuth
+// @Summary 鏇存柊搴曞簱浜鸿劯鐓х墖
+// @Description 鏇存柊搴曞簱浜鸿劯鐓х墖
+// @Accept multipart/form-data
+// @Produce json
+// @Tags dbperson 搴曞簱浜哄憳
+// @Param id formData string true "浜哄憳id"
+// @Param file formData file true "浜鸿劯鍥剧墖"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/dbperson/updateFace [POST]
+func (dbc DbPersonController) UpdateFace(c *gin.Context) {
+	file, header, err := c.Request.FormFile("file")
+	id := c.Request.FormValue("id")
+	if err != nil || id == "" {
+		util.ResponseFormat(c,code.RequestParamError,"鍙傛暟鏈夎")
+		return
+	}
+	//鏂囦欢鐨勫悕绉�
+	filename := header.Filename
+	defer file.Close()
+	// weedfs 涓婁紶
+	fileBytes, err := ioutil.ReadAll(file)
+	if err !=nil {
+		util.ResponseFormat(c,code.ComError,"鍥剧墖璇诲彇澶辫触")
+		return
+	}
+
+	//灏嗕笂浼犵殑鍥剧墖浜や汉鑴告娴嬪拰浜鸿劯鎻愬彇锛岃幏寰楃壒寰�
+	var faceBase64=""
+	faceArr, err, pI := service.GetFaceFeaFromSdk(fileBytes, time.Second*5)
+	if faceArr ==nil {
+		util.ResponseFormat(c,code.ComError,"鏈埌鎻愬彇浜鸿劯")
+		return
+	}
+	var rcFace *protomsg.Rect
+	if err ==nil && len(faceArr) >0 {
+		if len(faceArr) >1 {
+			util.ResponseFormat(c,code.ComError,"浜鸿劯澶т簬涓�寮狅紝璇锋崲涓�寮犱汉鑴稿浘鐗�")
+			return
+		}
+		for _,r := range faceArr {
+			//鎷垮埌浜鸿劯鐨勫潗鏍�
+			rcFace = r.Pos.RcFace
+
+			faceBase64 = base64.StdEncoding.EncodeToString(r.Feats)//鑾峰彇鎻愬彇鍒扮殑绗竴寮犱汉鑴哥壒寰�
+			break
+		}
+	}
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.WebPicIp == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return
+	}
+	var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
+	//鏍规嵁浜鸿劯鍧愭爣鎵e嚭浜鸿劯灏忓浘
+	t1 := time.Now()
+	cutFaceImgData := util.SubImg(*pI, int(rcFace.Left), int(rcFace.Top), int(rcFace.Right), int(rcFace.Bottom))
+	logger.Debug("SubImg鐢ㄦ椂锛�", time.Since(t1))
+	t1 = time.Now()
+	weedFilePath, e := WeedFSClient.UploadFile(weedfsUri, filename, cutFaceImgData)
+	logger.Debug("涓婁紶鍒皐eedfs鐢ㄦ椂:", time.Since(t1))
+	t1 = time.Now()
+	if e != nil {
+		util.ResponseFormat(c,code.ComError,"浜鸿劯涓婁紶澶辫触")
+		return
+	}
+	m := map[string]interface{} {
+		"faceFeature": faceBase64,
+		"personPicUrl": weedFilePath,
+	}
+	util.ResponseFormat(c,code.Success, m)
+
+	//var dbpApi dbapi.DbPersonApi
+	//b,d := dbpApi.UpdateFace(id,faceBase64,weedFilePath)
+	//if b {
+	//	util.ResponseFormat(c,code.UpdateSuccess,d)
+	//} else {
+	//	util.ResponseFormat(c,code.UpdateFail,"鏇存柊浜鸿劯澶辫触")
+	//}
+}
+
+// @Security ApiKeyAuth
 // @Summary 鍒犻櫎搴曞簱浜哄憳
 // @Description 鍒犻櫎搴撲汉鍛�
 // @Accept  x-www-form-urlencoded
@@ -162,27 +395,31 @@
 	}
 }
 
-type multiIds []string
+type DelMultiPerson []string
 
-// @Summary 鎵归噺鍒犻櫎搴曞簱浜哄憳
-// @Description 鎵归噺鍒犻櫎搴撲汉鍛�
+// @Security ApiKeyAuth
+// @Summary 鍒犻櫎搴曞簱浜哄憳
+// @Description 鍒犻櫎搴撲汉鍛�
 // @Accept  json
 // @Produce json
 // @Tags dbperson 搴曞簱浜哄憳
-// @Param uuids body controllers.multiIds true "搴曞簱浜哄憳ids"
+// @Param uuids body controllers.DelMultiPerson true "搴曞簱浜哄憳ids "
 // @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
 // @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
 // @Router /data/api-v/dbperson/deleteMoreDbPerson [POST]
 func (dbc DbPersonController) DeleteMoreDbPerson(c *gin.Context) {
-	uuids := make([]string, 0, 5)
+	var uuids DelMultiPerson
 	err := c.BindJSON(&uuids)
 	if err !=nil || len(uuids)==0{
 		util.ResponseFormat(c,code.RequestParamError,"鍙傛暟鏈夎")
 		return
 	}
+	logger.Debug("DeleteMoreDbPerson len(uuids):",len(uuids))
 	var pApi dbapi.DbPersonApi
-	paramBody := util.Struct2Map(uuids)
-	b, _ := pApi.DeleteMoreDbPerson(paramBody)
+	m := map[string]interface{}{
+		"ids": uuids,
+	}
+	b, _ := pApi.DeleteMoreDbPerson(m)
 	if b {
 		util.ResponseFormat(c, code.Success, "鍒犻櫎搴曞簱浜哄憳鎴愬姛")
 	} else {
@@ -190,6 +427,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 鏌ヨ搴曞簱浜哄憳鍒楄〃
 // @Description 鏌ヨ搴撲汉鍛樺垪琛�
 // @Accept  json
@@ -253,6 +491,59 @@
 	}
 }
 
+type JoinDbTVo struct {
+	CaptureId string 		`json:"captureId"`
+	TableIds  []string 		`json:"tableIds"`
+}
+
+// @Security ApiKeyAuth
+// @Summary 鎶撴媿浜哄憳鍔犲叆搴曞簱
+// @Description 鎶撴媿浜哄憳鍔犲叆搴曞簱
+// @Accept  json
+// @Produce json
+// @Tags dbperson 搴曞簱浜哄憳
+// @Param obj body controllers.JoinDbTVo true "搴曞簱鏁版嵁"
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/dbperson/joinDbTable [POST]
+func (dbc *DbPersonController) JoinDbTable(c *gin.Context) {
+	var reqBody JoinDbTVo
+	c.BindJSON(&reqBody)
+	if reqBody.CaptureId == "" || len(reqBody.TableIds) ==0 {
+		util.ResponseFormat(c,code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+	localConf, err := cache.GetServerInfo()
+	if err !=nil || localConf.AlarmIp == "" || localConf.AlarmPort <=0 {
+		util.ResponseFormat(c,code.ComError,"鎶ヨ璁剧疆鏈夎")
+		return
+	}
+	videopersons, e := esApi.Videopersonsinfosbyid([]string{reqBody.CaptureId}, config.EsInfo.EsIndex.VideoPersons.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)))
+	if e ==nil && videopersons !=nil && len(videopersons) == 1{
+		var personPicUrl = ""//浜鸿劯鍥剧墖
+		var feature = ""//鐗瑰緛
+		if videopersons[0].PicSmUrl !=nil && len(videopersons[0].PicSmUrl) >0 {
+			personPicUrl = videopersons[0].PicSmUrl[0]
+		}
+		fea, e2 := esApi.GetVideoPersonFaceFeatureById(reqBody.CaptureId, config.EsInfo.EsIndex.VideoPersons.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)))
+		if e2 == nil && fea !="" {
+			feature = fea
+		}
+		if personPicUrl != "" && feature != "" {
+			var dbpApi dbapi.DbPersonApi
+			b,d := dbpApi.JoinDbTable(reqBody.TableIds, feature, personPicUrl)
+			if b {
+				util.ResponseFormat(c,code.Success,d)
+				return
+			} else {
+				util.ResponseFormat(c,code.ComError,"鍔犲叆澶辫触")
+				return
+			}
+		}
+	}
+	util.ResponseFormat(c,code.ComError,"鍔犲叆澶辫触")
+}
+
 type DbtSearch struct {
 	TableId string `json:"tableId"`
 	OrderName string `json:"orderName"`
@@ -262,6 +553,63 @@
 	Size int `json:"size"`
 }
 
+type DbPersonMove struct {
+	PersonId string `json:"personId"`
+	TableIds []string `json:"tableIds"`
+}
+
+// @Security ApiKeyAuth
+// @Summary 浜哄憳绉诲姩
+// @Description 浜哄憳绉诲姩
+// @Accept  json
+// @Produce json
+// @Tags dbperson 搴曞簱浜哄憳
+// @Param obj body controllers.DbPersonMove true "绉诲姩鍙傛暟"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/dbperson/move [POST]
+func (dbc *DbPersonController) Move(c *gin.Context) {
+	var reqBody DbPersonMove
+	c.BindJSON(&reqBody)
+	if reqBody.PersonId == "" || len(reqBody.TableIds) == 0 {
+		util.ResponseFormat(c,code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+	var dbpApi dbapi.DbPersonApi
+	b,d := dbpApi.Move(reqBody.PersonId, reqBody.TableIds)
+	if b {
+		util.ResponseFormat(c,code.Success,d)
+	} else {
+		util.ResponseFormat(c,code.ComError,"")
+	}
+}
+
+// @Security ApiKeyAuth
+// @Summary 浜哄憳澶嶅埗
+// @Description 浜哄憳澶嶅埗
+// @Accept  json
+// @Produce json
+// @Tags dbperson 搴曞簱浜哄憳
+// @Param obj body controllers.DbPersonMove true "澶嶅埗鍙傛暟"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/dbperson/copy [POST]
+func (dbc *DbPersonController) Copy(c *gin.Context) {
+	var reqBody DbPersonMove
+	c.BindJSON(&reqBody)
+	if reqBody.PersonId == "" || len(reqBody.TableIds) == 0 {
+		util.ResponseFormat(c,code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+	var dbpApi dbapi.DbPersonApi
+	b,d := dbpApi.Copy(reqBody.PersonId, reqBody.TableIds)
+	if b {
+		util.ResponseFormat(c,code.Success,d)
+	} else {
+		util.ResponseFormat(c,code.ComError,"")
+	}
+}
+
 /*
 // @Summary 鏌ヨ搴曞簱浜哄憳鍒楄〃
 // @Description 鏌ヨ搴撲汉鍛樺垪琛�
diff --git a/controllers/dbtablesCon.go b/controllers/dbtablesCon.go
index fd8ddd0..917923e 100644
--- a/controllers/dbtablesCon.go
+++ b/controllers/dbtablesCon.go
@@ -18,14 +18,15 @@
 type DbTableController struct {
 }
 
+// @Security ApiKeyAuth
 // @Summary 鏄剧ず搴曞簱鍒楄〃
 // @Description 鏄剧ず鍚屾鎴栨湰鍦板簱鍒楄〃
 // @Accept  x-www-form-urlencoded
 // @Produce json
 // @Tags dbtable
 // @Param isSync path string true "鏄惁鍚屾搴�  1 鍚屾搴� 2鏈湴搴�  qita 鍏ㄩ儴搴�"
-// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
-// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"", success:false}"
 // @Router /data/api-v/dbtable/queryDbTables/{isSync} [POST]
 func (dbt DbTableController) QueryDbTables(c *gin.Context) {
 	isSync := c.Params.ByName("isSync")
@@ -33,6 +34,30 @@
 	b, data := tApi.QueryDbTables(isSync)
 	if b{
 		util.ResponseFormat(c, code.Success, data)
+	} else {
+		util.ResponseFormat(c,code.ComError,[]interface{}{})
+	}
+}
+
+// @Security ApiKeyAuth
+// @Summary 鏌ヨ鏈満鎵�鏈夊簳搴撳垪琛�
+// @Description 鏌ヨ鏈満鎵�鏈夊簳搴撳垪琛�
+// @Accept  x-www-form-urlencoded
+// @Produce json
+// @Tags dbtable
+// @Param isDelete query string true "0锛氭煡鏈垹闄わ紝1锛氭煡宸插垹闄わ紝鍏朵粬锛氭煡鎵�鏈�"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/dbtable/findAllDbTablesByCurServer [GET]
+func (dbt DbTableController) FindAllDbTablesByCurServer(c *gin.Context) {
+	var api dbapi.DbTableApi
+	isDeleteStr := c.Query("isDelete")
+	if isDeleteStr == "" {
+		isDeleteStr = "0"
+	}
+	arr,e := api.FindAllDbTablesByCurServer(isDeleteStr)
+	if e == nil {
+		util.ResponseFormat(c,code.Success, arr)
 	} else {
 		util.ResponseFormat(c,code.ComError,[]interface{}{})
 	}
@@ -47,6 +72,7 @@
 	return data
 }
 
+// @Security ApiKeyAuth
 // @Summary 淇敼搴曞簱
 // @Description 淇敼鍚屾鎴栨湰鍦板簱
 // @Accept  json
@@ -59,10 +85,11 @@
 func (dbt DbTableController) UpdateDbTables(c *gin.Context) {
 	dbtable := new(models.Dbtables)
 	err := c.BindJSON(&dbtable)
-	if err !=nil || dbtable.Id == "" || dbtable.TableName == "" {
+	if err !=nil || dbtable.Id == "" || dbtable.TableName == "" || (dbtable.Enable !=0 && dbtable.Enable !=1) {
 		util.ResponseFormat(c,code.RequestParamError,"鍙傛暟鏈夎")
 		return
 	}
+
 	paramBody := util.Struct2Map(dbtable)
 	var tApi dbapi.DbTableApi
 	b, data := tApi.UpdateDbTables(paramBody)
@@ -87,6 +114,66 @@
 	//} else {
 	//	util.ResponseFormat(c, code.ServiceInsideError, result["data"])
 	//}
+}
+
+type DbTStatusVo struct {
+	Id string `json:"id"`
+	Enable int `json:"enable"`
+}
+
+// @Security ApiKeyAuth
+// @Summary 淇敼搴曞簱鐘舵��
+// @Description 淇敼鍚屾鎴栨湰鍦板簱搴曞簱鐘舵��
+// @Accept  json
+// @Produce json
+// @Tags dbtable
+// @Param obj body controllers.DbTStatusVo true "搴曞簱鐘舵�佷慨鏀瑰弬鏁�"
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/dbtable/updateDbTableStatus [POST]
+func (dbt DbTableController) UpdateDbTableStatus(c *gin.Context) {
+	var ds DbTStatusVo
+	err := c.BindJSON(&ds)
+	if err !=nil || ds.Id == "" || (ds.Enable !=0 && ds.Enable !=1)  {
+		util.ResponseFormat(c,code.RequestParamError,"鍙傛暟鏈夎")
+		return
+	}
+
+	var dtApi dbapi.DbTableApi
+	dts, err := dtApi.DbtablesById([]string{ds.Id})
+	if err !=nil || dts == nil {
+		util.ResponseFormat(c,code.RequestParamError,"搴曞簱涓嶅瓨鍦�")
+		return
+	}
+	if ds.Enable == 1 {
+		str := dts[0].StartTime
+		etr := dts[0].EndTime
+		ct := time.Now()
+		st, _ := time.ParseInLocation("2006-01-02 15:04:05", str, time.Local)
+		b := false
+		if etr != "" {
+			et,_ := time.ParseInLocation("2006-01-02 15:04:05", etr, time.Local)
+			if et.After(ct) && st.Before(ct) {
+				b = true
+			}
+		} else {
+			if st.Before(ct) {
+				b = true
+			}
+		}
+		//b 涓簍rue鎵嶅厑璁稿紑鍚�
+		if !b {
+			util.ResponseFormat(c,code.UpdateFail,"褰撳墠涓嶅厑璁稿惎鐢�")
+			return
+		}
+	}
+
+	b,_ := dtApi.UpdateDbTableStatus(ds.Id, ds.Enable)
+	if b {
+		util.ResponseFormat(c,code.UpdateSuccess,"鏇存柊鎴愬姛")
+	} else {
+		util.ResponseFormat(c,code.ComError,"鏇存柊澶辫触")
+	}
 }
 
 func UpdateEndTime(id string) (flag bool) {
@@ -117,6 +204,7 @@
 	return flag
 }
 
+// @Security ApiKeyAuth
 // @Summary 娣诲姞搴曞簱
 // @Description 娣诲姞鍚屾鎴栨湰鍦板簱
 // @Accept  json
@@ -163,11 +251,15 @@
 		} else {
 			dbtable.Enable = 0
 		}
-	} else if st.Before(currentTime) && endTime == "" {
-		dbtable.Enable = 1
 	} else {
-		dbtable.Enable = 0
+		if st.Before(currentTime) {
+			dbtable.Enable = 1
+		} else {
+			dbtable.Enable = 0
+		}
 	}
+
+	logger.Debug("AddDbTableInfo dbtable.Enable:",dbtable.Enable,",startTime:",startTime,",endTime:",endTime,",st:",st,",curTime:",currentTime)
 
 	paramBody := util.Struct2Map(dbtable)
 	var tApi dbapi.DbTableApi
@@ -175,10 +267,11 @@
 	if b {
 		util.ResponseFormat(c,code.AddSuccess, data)
 	} else {
-		util.ResponseFormat(c,code.ComError,"鏂板澶辫触")
+		util.ResponseFormat(c,code.ComError, data)
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 鍒犻櫎搴曞簱
 // @Description 鍒犻櫎鍚屾鎴栨湰鍦板簱
 // @Accept  x-www-form-urlencoded
diff --git a/controllers/es.go b/controllers/es.go
index 091c86b..2d70aec 100644
--- a/controllers/es.go
+++ b/controllers/es.go
@@ -1,12 +1,16 @@
 package controllers
 
 import (
-	"basic.com/dbapi.git"
+	"basic.com/valib/logger.git"
+	"bytes"
+	"encoding/json"
 	"fmt"
 	"github.com/gin-gonic/gin"
 	"math/rand"
+	"os/exec"
 	"strconv"
 	"strings"
+	"webserver/cache"
 	"webserver/extend/code"
 	"webserver/extend/config"
 	"webserver/extend/esutil"
@@ -17,6 +21,13 @@
 
 type EsController struct{}
 
+type EsManagementController struct{}
+
+type EsClusterInfo struct {
+	Ip string `json:"ip"`
+}
+
+// @Security ApiKeyAuth
 // @Summary 姣斿鏁版嵁鏌ヨ
 // @Description  姣斿鏁版嵁鏌ヨ
 // @Accept  json
@@ -103,16 +114,19 @@
 	esSize := strconv.Itoa(webSize)
 	//浣跨敤es搴曞眰鏈哄埗澶勭悊鍒嗛〉
 	//璇锋眰澶�
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 != nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return nil
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + index + "/_search?search_type=dfs_query_then_fetch"
 
-	var setApi dbapi.SysSetApi
-	_, sysconf := setApi.GetServerInfo()
-	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + sysconf.ServerId + "\"}},"
+	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + localConf.ServerId + "\"}},"
 
 	//璇锋眰浣�
 	prama := "{\"from\":\"" + esFrom + "\",\"size\":\"" + esSize + "\"," +
-		//	prama := "{\"size\":\"0\"," +
+	//	prama := "{\"size\":\"0\"," +
 		"\"query\":{\"bool\":{" + queryStr +
 		"\"filter\":[" +
 		cameraIdStr +
@@ -149,3 +163,380 @@
 	}
 	return dataSource
 }
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鏌ヨES闆嗙兢淇℃伅-鍏ュ彛
+// @Description  鏌ヨES闆嗙兢淇℃伅-鍏ュ彛
+// @Accept  json
+// @Produce json
+// @Tags es
+// @Param obj body controllers.EsClusterInfo true "鏌ヨ闆嗙兢鍙傛暟"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/es/getEsClusterInfo [POST]
+*/
+func (em *EsManagementController) GetEsClusterInfo(c *gin.Context) {
+	var body EsClusterInfo
+	c.BindJSON(&body)
+	ip := body.Ip
+	serverIp := ""
+	if ip != "" {
+		serverIp = ip
+	} else {
+		localConf, err2 := cache.GetServerInfo()
+		if err2 != nil || localConf.ServerIp == "" {
+			logger.Debug("localConfig is wrong!!!")
+			util.ResponseFormat(c, code.QueryClusterInfoErr, err2)
+			return
+		}
+		serverIp = localConf.ServerIp
+	}
+	nodeInfos, err := getEsClusterInfors(serverIp)
+	if err != nil {
+		util.ResponseFormat(c, code.QueryClusterInfoErr, err)
+		return
+	}
+	util.ResponseFormat(c, code.Success, nodeInfos)
+}
+
+//鏌ヨES闆嗙兢淇℃伅-涓氬姟閫昏緫
+func getEsClusterInfors(ip string) ([]map[string]interface{}, error) {
+	str := "curl " + ip + ":9200/_cat/nodes?v"
+	cmd := exec.Command("sh", "-c", str)
+	var out bytes.Buffer
+	cmd.Stdout = &out
+	err := cmd.Run()
+	if err != nil {
+		return nil, err
+	}
+	infos := strings.Split(string(out.String()), "\n")
+	totalNodes := len(infos) - 1
+	var nodeInfos []map[string]interface{}
+	for i := 1; i < totalNodes; i++ {
+		nodeInfo := make(map[string]interface{})
+		context := strings.Fields(infos[i])
+		nodeIp := context[0]
+		Type := context[7]
+		var nodeType string
+		if Type == "mdi" {
+			nodeType = "涓昏妭鐐�"
+		}
+		if Type == "di" {
+			nodeType = "浠庤妭鐐�"
+		}
+		nodeInfo["ip"] = nodeIp
+		nodeInfo["nodeType"] = nodeType
+		url := "http://" + nodeIp + ":9200"
+		buf := esutil.HttpGet(url)
+		var info interface{}
+		json.Unmarshal(buf, &info)
+		tmpInfo := info.(map[string]interface{})
+		tmpName := tmpInfo["name"].(string)
+		versinInfo := tmpInfo["version"].(map[string]interface{})
+		buildDate := versinInfo["build_date"].(string)
+		nodeInfo["name"] = tmpName
+		nodeInfo["buildDate"] = buildDate
+		nodeInfos = append(nodeInfos, nodeInfo)
+	}
+	return nodeInfos, err
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鍒涘缓鑺傜偣
+// @Description  鍒涘缓鑺傜偣
+// @Accept  json
+// @Produce json
+// @Tags es
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/es/createNode [POST]
+*/
+func (em *EsManagementController) CreateNode(c *gin.Context) {
+	msg := "鍒涘缓鑺傜偣澶辫触锛岃鑱旂郴绠$悊鍛�"
+	str := "sh /opt/script/create_first_node.sh"
+	cmd := exec.Command("sh", "-c", str)
+	var out bytes.Buffer
+	cmd.Stdout = &out
+	err := cmd.Run()
+	if err != nil {
+
+	}
+	infos := strings.Split(string(out.String()), "\n")[0]
+	if infos == "鏈嶅姟鍚姩鎴愬姛" {
+		msg = "鍒涘缓鑺傜偣鎴愬姛"
+		util.ResponseFormat(c, code.Success, msg)
+		return
+	}
+	util.ResponseFormat(c, code.CreateFirstNodeErr, msg)
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鍔犲叆闆嗙兢
+// @Description  鍔犲叆闆嗙兢
+// @Accept  json
+// @Produce json
+// @Tags es
+// @Param obj body controllers.AddCluster true "鍔犲叆闆嗙兢鍙傛暟"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/es/addCluster [POST]
+*/
+func (em *EsManagementController) AddCluster(c *gin.Context) {
+	var ac AddCluster
+	err := c.BindJSON(&ac)
+	if err != nil {
+		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+	str := "sh /opt/script/add_cluster.sh " + ac.Option + ""
+	if ac.Option == "1" {
+		info, err := updateUnicastHosts(ac.Ip)
+		if err != nil || info == false {
+			util.ResponseFormat(c, code.QueryClusterInfoErr, err)
+			return
+		}
+		if info == true {
+			info := runScript(str)
+			if info == "杩愯澶辫触" {
+				util.ResponseFormat(c, code.AddClusterInfoErr, info)
+				return
+			}
+		}
+	}
+	if ac.Option == "2" {
+		info, err := updateUnicastHosts(ac.Ip)
+		if err != nil || info == false {
+			util.ResponseFormat(c, code.QueryClusterInfoErr, err)
+			return
+		}
+		if info == true {
+			info := runScript(str)
+			if info == "杩愯澶辫触" {
+				util.ResponseFormat(c, code.AddClusterInfoErr, info)
+				return
+			}
+		}
+	} else {
+		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+	util.ResponseFormat(c, code.Success, "鍔犲叆鎴愬姛")
+}
+
+//鑴氭湰灏佽
+func runScript(str string) string {
+
+	cmd := exec.Command("sh", "-c", str)
+	var out bytes.Buffer
+	cmd.Stdout = &out
+	err := cmd.Run()
+	if err != nil {
+		return "杩愯澶辫触"
+	}
+	return out.String()
+}
+
+type AddCluster struct {
+	Ip     string `json:"ip"`   //闆嗙兢IP
+	Option string `json:option` //鑺傜偣绫诲瀷
+}
+
+//鏇存柊缁勬挱鍒楄〃
+func updateUnicastHosts(host string) (bool, error) {
+	nodeInfos, err := getEsClusterInfors(host)
+	if err != nil {
+		return false, err
+	}
+	var hosts []string
+	for _, val := range nodeInfos {
+		nodeType := val["nodeType"].(string)
+		if nodeType == "涓昏妭鐐�" {
+			ip := val["ip"].(string)
+			hosts = append(hosts, ip)
+		}
+	}
+	msg := false
+	for i, val := range hosts {
+		val = val + ":9300"
+		hosts[i] = val
+	}
+	verificationHosts := "[\"" + strings.Replace(strings.Trim(fmt.Sprint(hosts), "[]"), " ", "\",\"", -1) + "\"]"
+	for i, val := range hosts {
+		val = "\\\"" + val + "\\\""
+		hosts[i] = val
+	}
+	oldUnicastHost := "\\[\\\"0.0.0.0:9300\\\"\\]"
+	newUnicastHost := strings.Replace(strings.Trim(fmt.Sprint(hosts), ""), " ", ",", -1)
+	str := "sed -ie 's/discovery.zen.ping.unicast.hosts: " + oldUnicastHost + "/discovery.zen.ping.unicast.hosts: " + newUnicastHost + "/g' /opt/elasticsearch/config/elasticsearch.yml"
+	fmt.Println(str)
+	cmd := exec.Command("sh", "-c", str)
+	var out bytes.Buffer
+	cmd.Stdout = &out
+	err1 := cmd.Run()
+	if err1 != nil {
+		return false, err
+	}
+	res := getUnicastHosts()
+	fmt.Println("res:          ", res)
+	res1 := "discovery.zen.ping.unicast.hosts: " + verificationHosts + ""
+	fmt.Println("res1:         ", res1)
+	if res == res1 {
+		msg = true
+	}
+	return msg, err
+}
+
+/*
+//淇敼elasticsearch.yml鏄犲皠鏂囦欢
+// @Security ApiKeyAuth
+// @Summary 淇敼es闆嗙兢Ip
+// @Description  淇敼es闆嗙兢Ip
+// @Accept  json
+// @Produce json
+// @Tags es
+// @Param obj body controllers.Hosts true "淇敼es闆嗙兢Ip鍙傛暟"
+// @Success 200 {string} json "{"code":200, msg:"", success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Router /data/api-v/es/updateEsHosts [POST]
+*/
+func (em *EsManagementController) UpdateEsHosts(c *gin.Context) {
+	flag := "淇敼鎴愬姛"
+	var hosts Hosts
+	c.BindJSON(&hosts)
+	nodeInfos, err := getEsClusterInfors(hosts.OldIp)
+	var nodeType string
+	if err != nil {
+		logger.Fatal(err)
+		util.ResponseFormat(c, code.QueryClusterInfoErr, err)
+	}
+	newMasterHosts := make([]string, 0)
+	allHosts := make([]string, 0)
+	for _, val := range nodeInfos {
+		ip := val["ip"].(string)
+		tmpType := val["nodeType"].(string)
+		if ip == hosts.OldIp {
+			nodeType = tmpType
+		}
+		if tmpType == "涓昏妭鐐�" {
+			newMasterHosts = append(newMasterHosts, ip)
+		}
+		if ip != hosts.OldIp {
+			allHosts = append(allHosts, ip)
+		}
+	}
+
+	if nodeType == "涓昏妭鐐�" {
+		str1 := "sed -ie 's/network.host: " + hosts.OldIp + "/network.host: " + hosts.NewIp + "/g' /opt/elasticsearch/config/elasticsearch.yml"
+		msg1 := runScript(str1)
+		if msg1 == "杩愯澶辫触" {
+			flag = "淇敼閰嶇疆鏂囦欢澶辫触"
+		}
+		for i, host := range newMasterHosts {
+			if host == hosts.OldIp {
+				newMasterHosts[i] = hosts.NewIp
+			}
+		}
+		for i, val := range newMasterHosts {
+			val = "\\\"" + val + ":9300\\\""
+			newMasterHosts[i] = val
+		}
+		newUnicastHost := strings.Replace(strings.Trim(fmt.Sprint(newMasterHosts), ""), " ", ",", -1)
+
+		tmpStr := "cat /opt/elasticsearch/config/elasticsearch.yml | grep discovery.zen.ping.unicast.hosts:"
+		rs := runScript(tmpStr)
+		ts := strings.Split(rs, "\n")[0]
+		ots := strings.Split(ts, " ")[1]
+		outs := strings.Replace(ots, "\"", "\\\"", -1)
+		oldUnicastHost := "\\" + strings.Replace(outs, "]", "\\]", -1)
+		str2 := "sed -ie 's/discovery.zen.ping.unicast.hosts: " + oldUnicastHost + "/discovery.zen.ping.unicast.hosts: " + newUnicastHost + "/g' /opt/elasticsearch/config/elasticsearch.yml"
+		msg2 := runScript(str2)
+		if msg2 == "杩愯澶辫触" {
+			flag = "淇敼閰嶇疆鏂囦欢澶辫触"
+		}
+		for _, host := range allHosts {
+			str3 := "sshpass -p \"123\" ssh basic@" + host + " \"cd /opt/elasticsearch/config  ; " + str2 + " ; cat elasticsearch.yml\""
+			msg := runScript(str3)
+			if msg == "杩愯澶辫触" {
+				flag = "淇敼閰嶇疆鏂囦欢澶辫触"
+			}
+		}
+	} else {
+		str1 := "sed -ie 's/network.host: " + hosts.OldIp + "/network.host: " + hosts.NewIp + "/g' /opt/elasticsearch/config/elasticsearch.yml"
+		msg1 := runScript(str1)
+		if msg1 == "杩愯澶辫触" {
+			flag = "淇敼閰嶇疆鏂囦欢澶辫触"
+		}
+	}
+	if flag == "淇敼閰嶇疆鏂囦欢澶辫触" {
+		util.ResponseFormat(c, code.UpdateFail, flag)
+	}
+	util.ResponseFormat(c, code.Success, flag)
+
+}
+
+type Hosts struct {
+	NewIp string `json:newIp`
+	OldIp string `json:oldIp`
+}
+
+func forwardCommand() {
+
+}
+
+//func AddEsCluster(hosts []string) (string){
+//	msg := "鍔犲叆澶辫触"
+//	for i,val := range hosts{
+//		val =val+":9300"
+//		hosts[i] = val
+//	}
+//	verificationHosts := "[\""+strings.Replace(strings.Trim(fmt.Sprint(hosts), "[]"), " ", "\",\"", -1)+"\"]"
+//	for i,val := range hosts{
+//		val ="\\\""+val+"\\\""
+//		hosts[i] = val
+//	}
+//	oldUnicastHost := "\\[\\\"0.0.0.0:9300\\\"\\]"
+//	newUnicastHost := strings.Replace(strings.Trim(fmt.Sprint(hosts), ""), " ", ",", -1)
+//	str := "sed -ie 's/discovery.zen.ping.unicast.hosts: "+oldUnicastHost+"/discovery.zen.ping.unicast.hosts: "+newUnicastHost+"/g' /opt/elasticsearch/config/elasticsearch.yml"
+//	fmt.Println(str)
+//	cmd := exec.Command("sh","-c",str)
+//	var out bytes.Buffer
+//	cmd.Stdout = &out
+//	err := cmd.Run()
+//	if err != nil {
+//
+//	}
+//	res := getUnicastHosts()
+//	fmt.Println("res:          ",res)
+//	res1 := "discovery.zen.ping.unicast.hosts: "+verificationHosts+""
+//	fmt.Println("res1:         ",res1)
+//	if res == res1{
+//		msg = "鍔犲叆鎴愬姛"
+//	}
+//	str2 := "echo \"node.master: true\" >> /opt/elasticsearch/config/elasticsearch.yml"
+//	cmd2 := exec.Command("sh","-c",str2)
+//	var out2 bytes.Buffer
+//	cmd2.Stdout = &out2
+//	err2 := cmd2.Run()
+//	if err2 != nil {
+//		msg = "鍔犲叆澶辫触"
+//	}
+//	return msg
+//
+//}
+
+func getUnicastHosts() string {
+	str := "cat /opt/elasticsearch/config/elasticsearch.yml | grep discovery.zen.ping.unicast.hosts:"
+	cmd := exec.Command("sh", "-c", str)
+	var out bytes.Buffer
+	cmd.Stdout = &out
+	err := cmd.Run()
+	if err != nil {
+
+	}
+	infos := strings.Split(string(out.String()), "\n")[0]
+	return infos
+
+}
diff --git a/controllers/esSearch.go b/controllers/esSearch.go
index c9e5ec6..1d4dcdb 100644
--- a/controllers/esSearch.go
+++ b/controllers/esSearch.go
@@ -1,21 +1,23 @@
-	package controllers
+package controllers
 
 import (
 	"basic.com/dbapi.git"
+	"basic.com/valib/logger.git"
 	"fmt"
+	"github.com/gin-gonic/gin"
 	"strconv"
 	"strings"
-	"webserver/extend/logger"
-
-	"github.com/gin-gonic/gin"
+	"webserver/cache"
 	"webserver/extend/code"
 	"webserver/extend/config"
 	"webserver/extend/esutil"
 	"webserver/extend/util"
+	"webserver/models"
 )
 
 type EsSearchController struct{}
 
+// @Security ApiKeyAuth
 // @Summary 妫�绱�
 // @Description 淇℃伅妫�绱㈠拰姣斿妫�绱�
 // @Accept  json
@@ -26,16 +28,23 @@
 // @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
 // @Router /data/api-v/es/esSearch [POST]
 func (sc *EsSearchController) PostEsSearch(c *gin.Context) {
-	searchBody := make(map[string]interface{}, 0)
+	//searchBody := make(map[string]interface{}, 0)
+	//c.BindJSON(&searchBody)
+	//data := findEsData(searchBody)
 
-	c.BindJSON(&searchBody)
+	var arg models.EsSearch
+	err := c.BindJSON(&arg)
+	if err !=nil || arg.Page <=0 && arg.Size<=0 {
+		util.ResponseFormat(c,code.RequestParamError,"鍙傛暟鏈夎")
+		return
+	}
+	data := findEsData(&arg)
 
-	data := findEsData(searchBody)
 	util.ResponseFormat(c, code.Success, data)
 }
 
 //鑾峰彇鐩戞帶绛夌骇
-func getAlarmLevel(alarmlevel []interface{}) []string {
+func getAlarmLevel(alarmlevel []int32) []string {
 	d := dbapi.DicApi{}
 	res, data := d.FindByType("ALARMLEVEL")
 	if data == nil {
@@ -43,7 +52,7 @@
 	}
 	logger.Debug(res)
 	// logger.Debug(data)
-	alarmLevel := make(map[int]string)
+	alarmLevel := make(map[int32]string)
 	tmp := data.(map[string]interface{})
 	for _, value := range tmp["ALARMLEVEL"].([]interface{}) {
 		// logger.Debug(value.(map[string]interface{})["value"],"		",value.(map[string]interface{})["name"])
@@ -53,24 +62,23 @@
 		if err != nil {
 			logger.Debug(err)
 		}
-		alarmLevel[vl] = name
+		alarmLevel[int32(vl)] = name
 	}
 	alarmLevelRes := make([]string, len(alarmlevel))
 	for i, v := range alarmlevel {
-		value := int(v.(float64))
-		if value < 0 {
+		if v < 0 {
 			alarmLevelRes[i] = "鎾ら槻"
 		} else {
-			alarmLevelRes[i] = alarmLevel[value]
+			alarmLevelRes[i] = alarmLevel[v]
 		}
 	}
 	return alarmLevelRes
 }
 
-func findEsData(searchBody map[string]interface{}) map[string]interface{} {
-	webPage := int(searchBody["page"].(float64))
+func findEsData(searchBody *models.EsSearch) map[string]interface{} {
+	webPage := searchBody.Page
 
-	webSize := int(searchBody["size"].(float64))
+	webSize := searchBody.Size
 	from := strconv.Itoa((webPage - 1) * webSize)
 	//esFrom := strconv.Itoa(from)
 	//esSize := strconv.Itoa(webSize)
@@ -78,39 +86,50 @@
 	//璇锋眰绱㈠紩
 	index := config.EsInfo.EsIndex.VideoPersons.IndexName + "," + config.EsInfo.EsIndex.Personaction.IndexName
 	queryStr := ""
-	queryBody := searchBody["inputValue"].(string)
+	queryBody := searchBody.InputValue
 	//妫�绱㈡
 	if queryBody != "" {
-		queryStr = "\"must\":[{\"multi_match\":{\"query\":\"" + queryBody + "\",\"fields\":[\"baseInfo.sex\",\"baseInfo.phoneNum.raw^1.5\",\"baseInfo.personName.raw^1.5\",\"alarmRules.alarmLevel^1.5\",\"alarmRules.linkInfo^1.5\",\"ageDescription^1.5\",\"taskName^1.5\",\"baseInfo.tableName^1.5\",\"sex^2.0\",\"race^2.0\",\"content^1.0\",\"baseInfo.idCard^1.8\",\"cameraAddr^1.0\"]," +
+		queryStr = "\"must\":[{\"multi_match\":{\"query\":\"" + queryBody + "\",\"fields\":[\"baseInfo.sex\",\"baseInfo.phoneNum.raw^1.5\",\"baseInfo.personName.raw^1.5\",\"alarmRules.alarmLevel^1.5\",\"alarmRules.linkInfo^3.0\",\"ageDescription^1.5\",\"taskName^1.5\",\"baseInfo.tableName^1.0\",\"sex^2.0\",\"race^2.0\",\"content^1.0\",\"baseInfo.idCard^1.8\",\"cameraAddr^2.0\"]," +
 			"\"type\":\"cross_fields\",\"operator\":\"OR\",\"slop\":0,\"prefix_length\":0,\"max_expansions\":50,\"zero_terms_query\":\"NONE\",\"auto_generate_synonyms_phrase_query\":true,\"fuzzy_transpositions\":true,\"boost\":1}}],"
 	}
 
-	searchTime := searchBody["searchTime"].([]interface{})
-	if searchBody["searchTime"] == nil || len(searchTime) < 2 {
+	searchTime := searchBody.SearchTime
+	if searchTime == nil || len(searchTime) < 2 {
 		info := make(map[string]interface{}, 0)
 		info["err"] = "璇疯緭鍏ユ椂闂磋寖鍥�"
 		return info
 	}
 
-	gteDate := searchTime[0].(string)
-	lteDate := searchTime[1].(string)
+	gteDate := searchTime[0]
+	lteDate := searchTime[1]
+
+	//鍒ゆ柇浜哄憳ID
+	personIdStr := ""
+	//personId := searchBody.Id
+	personId := []string{}
+	if personId != nil && len(personId) > 0 {
+		esPersonId := strings.Replace(strings.Trim(fmt.Sprint(personId), "[]"), " ", "\",\"", -1)
+		personIdStr = "{\"terms\":{\"id\":[\"" + esPersonId + "\"]}},"
+	}
+
 	//鍒ゆ柇浠诲姟ID
 	taskIdStr := ""
-	taskId := searchBody["tasks"].([]interface{})
+	taskId := searchBody.Tasks
 	if taskId != nil && len(taskId) > 0 {
 		esTaskId := strings.Replace(strings.Trim(fmt.Sprint(taskId), "[]"), " ", "\",\"", -1)
 		taskIdStr = "{\"terms\":{\"taskId\":[\"" + esTaskId + "\"]}},"
 	}
+
 	//鍒ゆ柇鎽勫儚鏈篒D
 	cameraIdStr := ""
-	cameraId := searchBody["treeNodes"].([]interface{})
+	cameraId := searchBody.TreeNodes
 	if cameraId != nil && len(cameraId) > 0 {
 		esCameraId := strings.Replace(strings.Trim(fmt.Sprint(cameraId), "[]"), " ", "\",\"", -1)
 		cameraIdStr = "{\"terms\":{\"cameraId\":[\"" + esCameraId + "\"]}},"
 	}
 
 	//鍒ゆ柇搴撹〃ID
-	tableId := searchBody["tabs"].([]interface{})
+	tableId := searchBody.Tabs
 	esTableId := ""
 	esTableIdStr := ""
 	if tableId != nil && len(tableId) > 0 {
@@ -120,12 +139,12 @@
 	}
 	//鍒ゆ柇鏀惰棌鐘舵��
 	isCollectStr := ""
-	isCollect := searchBody["collection"].(string)
+	isCollect := searchBody.Collection
 	if isCollect != "" {
 		isCollectStr = "{\"term\":{\"isCollect\":\"" + isCollect + "\"}},"
 	}
 	//鍒ゆ柇甯冮槻绛夌骇id
-	alarmLevelId := searchBody["alarmlevel"].([]interface{})
+	alarmLevelId := searchBody.AlarmLevel
 	alarmLevelStr := ""
 	if len(alarmLevelId) > 0 {
 		alarmLevelTypes := strings.Replace(strings.Trim(fmt.Sprint(getAlarmLevel(alarmLevelId)), "[]"), " ", "\",\"", -1)
@@ -134,11 +153,15 @@
 
 	//浣跨敤es搴曞眰鏈哄埗澶勭悊鍒嗛〉
 	//璇锋眰澶�
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return nil
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + index + "/_search?search_type=dfs_query_then_fetch"
-	var setApi dbapi.SysSetApi
-	_, sysconf := setApi.GetServerInfo()
-	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + sysconf.ServerId + "\"}},"
+
+	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + localConf.ServerId + "\"}},"
 
 	//璇锋眰浣�
 	prama := "{\"from\":\"" + from + "\"," +
@@ -147,13 +170,14 @@
 		"\"filter\":[" +
 		cameraIdStr +
 		alarmLevelStr +
+		personIdStr +
 		taskIdStr +
 		isCollectStr +
 		esTableIdStr +
 		analyServerFilterStr +
 		"{\"range\":{\"picDate\":{\"from\":\"" + gteDate + "\",\"to\":\"" + lteDate + "\",\"include_lower\":true,\"include_upper\":true,\"boost\":1}}}]}}," +
 		"\"sort\":[{\"_score\":{\"order\":\"desc\"}},{\"picDate\":{\"order\":\"desc\"}}]," +
-		"\"_source\":[\"baseInfo\",\"alarmRules\",\"sex\",\"analyServerName\",\"sdkName\",\"ageDescription\",\"content\",\"id\",\"cameraAddr\",\"picMaxUrl\",\"picDate\",\"race\",\"videoUrl\",\"picSmUrl\",\"taskName\",\"personIsHub\",\"isAlarm\",\"analyServerIp\",\"cameraId\",\"linkId\"]" +
+		"\"_source\":[\"baseInfo\",\"alarmRules\",\"sex\",\"analyServerName\",\"sdkName\",\"ageDescription\",\"content\",\"id\",\"cameraAddr\",\"picMaxUrl\",\"picDate\",\"race\",\"videoUrl\",\"picSmUrl\",\"taskName\",\"isAlarm\",\"analyServerIp\",\"cameraId\",\"linkTag\",\"linkTagInfo\"]" +
 		"}"
 	//logger.Debug("findEsData.param:",prama)
 	//鏁版嵁瑙f瀽
@@ -166,45 +190,35 @@
 	for _, masterInfoValues := range data.([]interface{}) {
 		masterInfo := masterInfoValues.(map[string]interface{})
 		sources := make(map[string]interface{}, 0)
-		sources["activeObject"] = masterInfo
-		source := make([]map[string]interface{}, 0)
-		source = append(source, masterInfo)
-		linkId := ""
-		if masterInfo["linkId"] != nil {
-			linkId = masterInfo["linkId"].(string)
-		}
-		id := masterInfo["id"].(string)
-		if linkId != "" {
-			linkInfo := GetLinkInfo(linkId, id)
-			for _, slaveInfoValues := range linkInfo {
-				slaveInfo := slaveInfoValues
-				source = append(source, slaveInfo)
-			}
 
+		if masterInfo["linkTagInfo"] != nil {
+			linkTagInfo := masterInfo["linkTagInfo"].([]interface{})
+			delete(masterInfo, "linkTagInfo")
+			if len(linkTagInfo) >0 {
+				slaveList := make([]interface{}, 0)
+				slaveList = append(slaveList, masterInfo)
+				slaveList = append(slaveList, linkTagInfo...)
+				sources["list"] = slaveList
+			} else {
+				sources["list"] = []interface{}{
+					masterInfo,
+				}
+			}
+		} else {
+			if _,ok := masterInfo["linkTagInfo"];ok {
+				delete(masterInfo, "linkTagInfo")
+			}
+			sources["list"] = []interface{}{
+				masterInfo,
+			}
 		}
-		sources["list"] = source
+
+		sources["activeObject"] = masterInfo
+
 		tmpDate["datalist"] = append(tmpDate["datalist"], sources)
 	}
 	tmpAllDate["datalist"] = tmpDate["datalist"]
 	return tmpAllDate
-}
-
-func GetLinkInfo(linkId string, id string) []map[string]interface{} {
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
-		"/" + config.EsInfo.EsIndex.VideoPersons.IndexName + "," + config.EsInfo.EsIndex.Personaction.IndexName + "/_search?search_type=dfs_query_then_fetch"
-	jsonDSL := "{\"query\":{\"bool\":{\"filter\":[{\"term\":{\"linkId.keyword\":\"" + linkId + "\"}}],\"must_not\":[{\"term\":{\"id\":\"" + id + "\"}}]}},\"size\":100}"
-
-	buf, err := esutil.EsReq("POST", url, []byte(jsonDSL))
-	if err != nil {
-		logger.Debug(err)
-	}
-
-	sources, err := esutil.Sourcelist(buf)
-	if err != nil {
-		logger.Debug(err)
-	}
-	return sources
-
 }
 
 //sdkTYype瀛楀吀"\"_source\":[\"BaseName\",\"Gender\",\"Race\",\"content\",\"idcard\",\"picAddress\",\"picDate\",\"sdkType\",\"Age\",\"personId\",\"personIsHub\",\"personPicUrl\",\"picLocalUrl\",\"picSmUrl\",\"videoIp\",\"videoNum\",\"cameraId\",\"ageDescription\",\"likePer\"]" +
diff --git a/controllers/eventPush.go b/controllers/eventPush.go
index 551912c..4580206 100644
--- a/controllers/eventPush.go
+++ b/controllers/eventPush.go
@@ -47,15 +47,16 @@
 	Enable bool   `json:"enable"`
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 浜嬩欢鎺ㄩ�佷繚瀛�
 // @Description 浜嬩欢鎺ㄩ�佷繚瀛�
+// @Accept json
+// @Produce json
 // @Tags 浜嬩欢鎺ㄩ��
 // @Param SaveArgs body controllers.EventPushVo true "鏃堕棿鎺ㄩ�佷繚瀛樺弬鏁�"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/eventPush/save [post]
-*/
 func (epc EventPushController) Save(c *gin.Context) {
 	var saveBody EventPushVo
 	if err := c.BindJSON(&saveBody); err != nil {
@@ -72,9 +73,10 @@
 	}
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 鏍规嵁浜嬩欢鎺ㄩ�佷富棰樼殑涓�绾у拰浜岀骇閫夐」鑾峰彇鏈�鍚庝笅鎷夎彍鍗曞垪琛�
 // @Description  鏍规嵁浜嬩欢鎺ㄩ�佷富棰樼殑涓�绾у拰浜岀骇閫夐」鑾峰彇鏈�鍚庝笅鎷夎彍鍗曞垪琛�
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags 浜嬩欢鎺ㄩ��
 // @Param topic query string true "涓�绾т富棰橀�夐」,渚嬪锛歝amera(鎽勫儚鏈�)"
@@ -82,7 +84,6 @@
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/eventPush/findByEventTopic [get]
-*/
 func (epc EventPushController) FindByEventTopic(c *gin.Context) {
 	topic := c.Query("topic")
 	childType := c.Query("type")
@@ -99,16 +100,16 @@
 	}
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 鏌ュ叏閮�
 // @Description  鏌ュ叏閮�
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags 浜嬩欢鎺ㄩ��
 // @Param name query string false "浜嬩欢鍚嶇О"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/eventPush/findAll [get]
-*/
 func (controller EventPushController) FindAll(c *gin.Context) {
 	name := c.Query("name")
 	var api dbapi.EventPushApi
@@ -120,16 +121,16 @@
 	}
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 浜嬩欢鎺ㄩ�佺紪杈�
 // @Description  浜嬩欢鎺ㄩ�佺紪杈�
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags 浜嬩欢鎺ㄩ��
 // @Param id query string true "id"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/eventPush/getById [get]
-*/
 func (controller EventPushController) GetById(c *gin.Context) {
 	id := c.Query("id")
 	if id == "" {
@@ -150,16 +151,16 @@
 	Enable bool   `json:"enable"`
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 鏀瑰彉enable鐘舵��
 // @Description  鏀瑰彉enable鐘舵��
+// @Accept json
 // @Produce json
 // @Tags 浜嬩欢鎺ㄩ��
 // @Param statusBody body controllers.ChangeStatusVo true "鍙傛暟缁撴瀯"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/eventPush/changeStatus [post]
-*/
 func (controller EventPushController) ChangeStatus(c *gin.Context) {
 	var statusBody ChangeStatusVo
 	err := c.BindJSON(&statusBody)
@@ -176,17 +177,16 @@
 	}
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 鏍规嵁id鍒犻櫎
 // @Description  鏍规嵁id鍒犻櫎
 // @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags 浜嬩欢鎺ㄩ��
-// @Param id query string true "id"
+// @Param id formData string true "id"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/eventPush/delete [post]
-*/
 func (controller EventPushController) Delete(c *gin.Context) {
 	id := c.PostForm("id")
 	if id == "" {
diff --git a/controllers/fileController.go b/controllers/fileController.go
index 696584d..dc54ec3 100644
--- a/controllers/fileController.go
+++ b/controllers/fileController.go
@@ -6,11 +6,14 @@
 	"basic.com/pubsub/protomsg.git"
 	"bytes"
 	"encoding/base64"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/satori/go.uuid"
+	"gocv.io/x/gocv"
 	"image"
+	"image/color"
 	"image/jpeg"
 	"io/ioutil"
 	"log"
@@ -22,10 +25,11 @@
 	"strings"
 	"sync"
 	"time"
+	"webserver/cache"
 	"webserver/extend/code"
 	"webserver/extend/config"
 	"webserver/extend/esutil"
-	"webserver/extend/logger"
+	"basic.com/valib/logger.git"
 	"webserver/extend/util"
 	"webserver/models"
 	"webserver/service"
@@ -46,9 +50,10 @@
 
 //var weedfsUri = "http://192.168.1.182:9500/submit"
 
-// @Summary 鍗曞紶鍥剧墖涓婁紶锛屾坊鍔犲簳搴撲汉鍛�
-// @Description  鍗曞紶鍥剧墖涓婁紶锛屾坊鍔犲簳搴撹繑鍥炴暟鎹汉鍛�
-// @Accept  mpfd
+// @Security ApiKeyAuth
+// @Summary 渚濇嵁鍥剧墖娣诲姞搴曞簱浜哄憳
+// @Description  渚濇嵁鍥剧墖娣诲姞搴曞簱杩斿洖鏁版嵁浜哄憳
+// @Accept  multipart/form-data
 // @Produce json
 // @Tags dbperson 搴曞簱浜哄憳
 // @Param file formData file true "搴曞簱浜哄憳鍥剧墖"
@@ -106,8 +111,10 @@
 }
 var faceExtractedMap = make(map[string]FaceExtract,0)
 
+// @Security ApiKeyAuth
 // @Summary 浜鸿劯鎻愬彇
 // @Description  浜鸿劯鎻愬彇
+// @Accept multipart/form-data
 // @Produce json
 // @Tags 浠ュ浘鎼滃浘
 // @Param file formData file true "浜哄憳鍥剧墖"
@@ -120,7 +127,13 @@
 		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
 		return
 	}
-	var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.WebPicIp == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return
+	}
+	var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
+	logger.Debug("weedfsUri:",weedfsUri)
 	resultMap :=make(map[string]interface{},0)
 	//灏嗕笂浼犵殑鍥剧墖浜や汉鑴告娴嬪拰浜鸿劯鎻愬彇锛岃幏寰楃壒寰�
 	fileBytes, _ := ioutil.ReadAll(file)
@@ -141,13 +154,31 @@
 			}
 		}
 		//2.澶у浘鐢绘,鏍囪瘑浜鸿劯浣嶇疆
-		originFilePath, _ := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", fileBytes)
+		drawedB, _ := drawPolygonOnImg(pI, &faceArr)
+
+		originFilePath, _ := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", *drawedB)
 		resultMap["uploadImage"] = originFilePath
 		resultMap["smImage"] = urlArr
 		util.ResponseFormat(c,code.Success, resultMap)
 	} else {
 		util.ResponseFormat(c,code.ComError,"鏈彁鍙栧埌浜鸿劯")
 	}
+}
+
+func drawPolygonOnImg(i *protomsg.Image,faceArr *[]*protomsg.ResultFaceDetect) (*[]byte,error) {
+	rook, _ := gocv.NewMatFromBytes(int(i.Height), int(i.Width), gocv.MatTypeCV8UC3, i.Data)
+	defer rook.Close()
+	//yellow := color.RGBA{255, 255, 0, 0}
+	red := color.RGBA{255, 0, 0, 0}
+	for _,faceResult := range *faceArr {
+		left := int(faceResult.Pos.RcFace.Left)
+		top := int(faceResult.Pos.RcFace.Top)
+		right := int(faceResult.Pos.RcFace.Right)
+		bottom := int(faceResult.Pos.RcFace.Bottom)
+		gocv.Rectangle(&rook, image.Rect(left,top,right,bottom), red, 1)
+	}
+	fData,err := gocv.IMEncode(".jpg", rook)
+	return &fData,err
 }
 
 type CompareResult struct {
@@ -168,6 +199,7 @@
 	BaseInfo []DbPersonVo `json:"baseInfo"`
 	VideoUrl string `json:"videoUrl"`
 	SdkName string `json:"sdkName"`
+	AlarmRules []AlarmRuleVo `json:"alarmRules"`
 }
 type DbPersonVo struct {
 	BwType string `json:"bwType"`
@@ -187,6 +219,15 @@
 type ScoreIndex struct {
 	CompareScore float32
 	Index int
+}
+
+type AlarmRuleVo struct {
+	GroupId      string `json:"groupId"`
+	AlarmLevel   string `json:"alarmLevel"`
+	RuleText     string `json:"ruleText"`
+	DefenceState bool `json:"defenceState"`
+	IsLink 		 bool `json:"isLink"`
+	LinkInfo 	 string `json:"linkInfo"`
 }
 
 //濉厖鍚戝墠绔繑鍥炵殑鏁版嵁
@@ -248,11 +289,17 @@
 		}
 	}
 	if len(captureIds) >0 {
-		videopersons, _ := esApi.Videopersonsinfosbyid(captureIds, config.EsInfo.EsIndex.VideoPersons.IndexName, config.EsInfo.Masterip, config.EsInfo.Httpport)
+		localConf, err2 := cache.GetServerInfo()
+		if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+			logger.Debug("localConfig is wrong!!!")
+			return nil
+		}
+		logger.Debug("captureIds:",strings.Join(captureIds,","))
+		videopersons, _ := esApi.Videopersonsinfosbyid(captureIds, config.EsInfo.EsIndex.VideoPersons.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)))
 		logger.Debug("comp videoPersons.len:",len(videopersons))
 		for _,vp :=range videopersons {
 			isAlarmInt, _ := strconv.Atoi(vp.IsAlarm)
-			bi := make([]DbPersonVo,0)
+			var bi []DbPersonVo
 			for _,p :=range vp.BaseInfo {
 				bi = append(bi, DbPersonVo{
 					PersonId: p.PersonId,
@@ -264,9 +311,22 @@
 					PhoneNum: p.PhoneNum,
 					Sex: p.Sex,
 					TableId: p.TableId,
-					BwType: strconv.Itoa(int(p.BwType)),
+					BwType: p.BwType,
 					TableName: p.TableName,
 				})
+			}
+			var alarmRules []AlarmRuleVo
+			if vp.AlarmRules !=nil && len(vp.AlarmRules) >0 {
+				for _,ar :=range vp.AlarmRules {
+					alarmRules = append(alarmRules, AlarmRuleVo{
+						GroupId: ar.GroupId,
+						AlarmLevel: ar.AlarmLevel,
+						RuleText: ar.RuleText,
+						DefenceState: ar.DefenceState,
+						IsLink: ar.IsLink,
+						LinkInfo: ar.LinkInfo,
+					})
+				}
 			}
 			vpE := CompareResult{
 				Id: vp.Id,
@@ -285,6 +345,7 @@
 				VideoUrl: vp.VideoUrl,
 				BaseInfo: bi,
 				SdkName: "浜鸿劯",
+				AlarmRules: alarmRules,
 			}
 			resultList[captureM[vp.Id].Index] = vpE
 		}
@@ -305,6 +366,37 @@
 	return level
 }
 
+func GetFeaFromOneFaceImg(fileBytes []byte) (faceB []byte,oriImg string,smImgs []string, err error){
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.WebPicIp == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return nil,"",nil,errors.New("localConf err")
+	}
+	var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
+	logger.Debug("weedfsUri:",weedfsUri)
+	faceArr, err, pI := service.GetFaceFeaFromSdk(fileBytes, time.Second*60)
+	if err ==nil && len(faceArr) ==1 {
+		rcFace := faceArr[0].Pos.RcFace
+		cutFaceImgData := util.SubImg(*pI, int(rcFace.Left), int(rcFace.Top), int(rcFace.Right), int(rcFace.Bottom))
+		weedFilePath, e := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", cutFaceImgData)
+		if e == nil{
+			faceExtractedMap[weedFilePath] = FaceExtract{
+				Url:weedFilePath,
+				FaceBytes:faceArr[0].Feats,
+			}
+			smImgs = append(smImgs, weedFilePath)
+		}
+		//2.澶у浘鐢绘,鏍囪瘑浜鸿劯浣嶇疆
+		drawedB, _ := drawPolygonOnImg(pI, &faceArr)
+
+		originFilePath, _ := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", *drawedB)
+		return faceArr[0].Feats,originFilePath,smImgs,nil
+	} else {
+		return nil,"",nil,errors.New("no face")
+	}
+}
+
+// @Security ApiKeyAuth
 // @Summary 浠ュ浘鎼滃浘
 // @Description  浠ュ浘鎼滃浘
 // @Accept json
@@ -314,49 +406,70 @@
 // @Success 200 {string} json "{"code":200, msg:"", data:"", success:true}"
 // @Failure 500 {string} json "{"code":500, msg:"", data:"", success:false}"
 // @Router /data/api-v/dbperson/searchByPhoto [POST]
-func (controller FileController) SearchByPhoto(c *gin.Context) {
+func (fc FileController) SearchByPhoto(c *gin.Context) {
 	var searchBody models.EsSearch
 	err := c.BindJSON(&searchBody)
 	if err !=nil{
 		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
 		return
 	}
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		util.ResponseFormat(c,code.ComError,"localConf wrong")
+		return
+	}
 	var faceB []byte
-	if searchBody.CaptureId != "" {//鍋氭煡鎵炬浜�,鎼滄墍鏈夋姄鎷嶅拰搴曞簱
-		searchBase64Fea, err := esApi.GetVideoPersonFaceFeatureById(searchBody.CaptureId, config.EsInfo.EsIndex.VideoPersons.IndexName, config.EsInfo.Masterip, config.EsInfo.Httpport)
-		if err !=nil {
-			util.ResponseFormat(c, code.ComError, "鎶撴媿鏁版嵁涓嶅瓨鍦紝璇锋鏌�")
-			return
-		}
-		if searchBase64Fea !=""{
-			decodeF, err := base64.StdEncoding.DecodeString(searchBase64Fea)
-			if err !=nil {
-				util.ResponseFormat(c, code.ComError, "鏈潯鎶撴�曠壒寰佷笉鏄痓ase64锛岃妫�鏌�")
+	logger.Debug("compTargetId:",searchBody.CompTargetId,",compTargetType:",searchBody.CompTargetType)
+	if searchBody.CompTargetId != "" {//鍋氭煡鎵炬浜�,鎸夋姄鎷嶇殑浜鸿劯鎴栬�呭簳搴撶殑浜鸿劯浠ュ浘鎼滃浘
+		if searchBody.CompTargetType == 0 {//鏈紶浜鸿劯鏄簳搴撲汉鑴�
+			var dbpApi dbapi.DbPersonApi
+			dbPersons, e := dbpApi.Dbpersoninfosbyid([]string{searchBody.CompTargetId})
+			if e ==nil && dbPersons !=nil && len(dbPersons) ==1 {
+				searchBase64Fea := dbPersons[0].FaceFeature
+				if searchBase64Fea != "" {
+					decodeF, err := base64.StdEncoding.DecodeString(dbPersons[0].FaceFeature)
+					if err !=nil {
+						util.ResponseFormat(c, code.ComError, "鏈潯搴曞簱浜哄憳鐗瑰緛涓嶆槸base64锛岃妫�鏌�")
+						return
+					}
+					faceB = decodeF
+				} else {
+					util.ResponseFormat(c, code.ComError, "鏈潯搴曞簱浜哄憳鐗瑰緛涓虹┖锛岃妫�鏌�")
+					return
+				}
+			} else {
+				util.ResponseFormat(c, code.ComError, "搴曞簱浜哄憳鏌ヨ澶辫触锛岃妫�鏌�")
 				return
 			}
-			faceB = decodeF
+		} else {
+			searchBase64Fea, err := esApi.GetVideoPersonFaceFeatureById(searchBody.CompTargetId, config.EsInfo.EsIndex.VideoPersons.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)))
+			if err !=nil {
+				util.ResponseFormat(c, code.ComError, "鎶撴媿鏁版嵁涓嶅瓨鍦紝璇锋鏌�")
+				return
+			}
+
+			if searchBase64Fea !=""{
+				decodeF, err := base64.StdEncoding.DecodeString(searchBase64Fea)
+				if err !=nil {
+					util.ResponseFormat(c, code.ComError, "鏈潯鎶撴�曠壒寰佷笉鏄痓ase64锛岃妫�鏌�")
+					return
+				}
+				faceB = decodeF
+			}
 		}
+
 	} else {//鍋氫互鍥炬悳鍥�
 		if searchBody.PicUrl == "" || len(searchBody.DataBases) == 0 {
-			util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
+			util.ResponseFormat(c, code.RequestParamError, "浠ュ浘鎼滃浘PicUrl涓嶈兘涓虹┖")
 			return
 		}
 		if face,ok := faceExtractedMap[searchBody.PicUrl];!ok{
-			util.ResponseFormat(c, code.RequestParamError, "璇烽噸鏂颁笂浼犲浘鐗�")
+			util.ResponseFormat(c, code.RequestParamError, "浜鸿劯鐗瑰緛鏈娴嬶紝璇烽噸鏂颁笂浼犲浘鐗�")
 			return
 		} else {
 			faceB = face.FaceBytes
 		}
-	}
-
-	var sysSetApi dbapi.SysSetApi
-	analyServerId := ""
-	flag, sysconf := sysSetApi.GetServerInfo()
-	if flag {
-		analyServerId = sysconf.ServerId
-	} else {
-		util.ResponseFormat(c, code.ComError, "analyServerId涓虹┖锛岄厤缃湁璇�")
-		return
 	}
 
 	if faceB == nil {
@@ -389,7 +502,7 @@
 	arg.SearchTime = searchBody.SearchTime
 	arg.InputValue = searchBody.InputValue
 	arg.Collection = searchBody.Collection
-	arg.AnalyServerId = analyServerId
+	arg.AnalyServerId = localConf.ServerId
 
 	logger.Debug("arg.TableIds:", arg.TableIds, ",alarmLevel:",arg.AlarmLevel,",treeNodes:",arg.TreeNodes,",searchTime:",arg.SearchTime,
 		",inputValue:",arg.InputValue,",tasks:",arg.Tasks,",compThreshold:",arg.CompareThreshold)
@@ -441,76 +554,136 @@
 	util.ResponseFormat(c,code.Success,m)
 }
 
-func GetCompareDataTwice(co *service.CompareOnce,arg *models.EsSearch) map[string]interface{} {
-	//camIds := arg.TreeNodes
-	//tabIds := arg.Tabs
-	//taskIds := arg.Tasks
-	//alarmLevels := arg.AlarmLevel
-	//timeArr := arg.SearchTime
-	//input := arg.InputValue
-	//resultList := make([]CompareResult,0)
-	//for _,each :=range *co.CompareData {
-	//	if each.Id !=""{
-	//		n :=0
-	//		if len(camIds) == 0 || isInArr(each.CameraId,camIds) {
-	//			n++
-	//		}
-	//		if len(tabIds) == 0 {
-	//			n++
-	//		}
-	//		if len(taskIds) == 0 || isInArr(each.TaskId, taskIds) {
-	//			n++
-	//		}
-	//		//鍒ゆ柇鎶ヨ绛夌骇
-	//		if len(alarmLevels) == 0 {
-	//
-	//		}
-	//		n++
-	//		//鍒ゆ柇鏃堕棿
-	//		if len(timeArr) == 0 {
-	//
-	//		}
-	//		n++
-	//		if input == ""{
-	//
-	//		}
-	//		n++
-	//		if n == 6 {
-	//			resultList = append(resultList,cr)
-	//		}
-	//	} else {
-	//		resultList = append(resultList,cr)
-	//	}
-	//}
+type PersonId struct {
+	Id string `json:"id"`
+}
 
-	//logger.Debug("GetCompareDataTwice.data:",resultList)
-	//service.SortByScore(resultList)
-	from := (arg.Page-1)*arg.Size
-	to := from + arg.Size
-	var sCompResult protomsg.SdkCompareResult
-	total := len(*co.CompareData)
-	if total <= to {
-		sCompResult.CompareResult = (*co.CompareData)[from:total]
-	} else {
-		sCompResult.CompareResult = (*co.CompareData)[from:to]
-	}
-	resultList := FillDataToCompareResult(&sCompResult)
-
+func GetCompareDataTwice(co *service.CompareOnce,searchBody *models.EsSearch) map[string]interface{} {
 	m := make(map[string]interface{},0)
-	m["total"] = total
-	m["compareNum"] = arg.CompareNum
-	m["totalList"] = resultList
-	//if from < len(resultList) {
-	//	if to <= len(resultList) {
-	//		m["totalList"] = resultList[from:to]
-	//	} else {
-	//		lte := len(resultList)
-	//		m["totalList"] = resultList[from:lte]
-	//	}
+
+	from := (searchBody.Page-1)*searchBody.Size
+	to := from + searchBody.Size
+
+	var hasCompEsPerson = false
+	if searchBody.DataBases !=nil {
+		for idx,tableId :=range searchBody.DataBases {
+			if tableId == "esData" {
+				hasCompEsPerson = true
+				searchBody.DataBases = append(searchBody.DataBases[:idx], searchBody.DataBases[idx+1:]...)
+				break
+			}
+		}
+	}
+	if hasCompEsPerson {//浜屾妫�绱S姣斿缁撴灉
+		arg := protomsg.CompareArgs{
+			CompareThreshold: searchBody.Threshold,
+		}
+		localConf, err := cache.GetServerInfo()
+		if err ==nil && localConf.AlarmIp != "" && localConf.ServerId != "" {
+			arg.Source = true // 鏍囪瘑鏉ユ簮鏄痺eb
+			arg.AlarmLevel = searchBody.AlarmLevel
+			arg.Tasks = searchBody.Tasks
+			arg.TreeNodes = searchBody.TreeNodes
+			arg.Tabs = searchBody.Tabs
+			arg.SearchTime = searchBody.SearchTime
+			arg.InputValue = searchBody.InputValue
+			arg.Collection = searchBody.Collection
+			arg.AnalyServerId = localConf.ServerId
+			alarmLevelTypes := strings.Replace(strings.Trim(fmt.Sprint(getAlarmLevel(searchBody.AlarmLevel)), "[]"), " ", "\",\"", -1)
+			captureIds := esApi.GetAllLocalVideopersonsId(arg, config.EsInfo.EsIndex.VideoPersons.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)), alarmLevelTypes)
+			logger.Debug("searchPhoto first Result.len:",len(*co.CompareData),"twice len(captureIds):",len(captureIds))
+			if captureIds !=nil {
+				var aResult protomsg.SdkCompareResult
+				aList := getTwiceSearchResult(co, &captureIds, searchBody)
+				aTotal := aList.Len()
+				if aTotal <= to {
+					aResult.CompareResult = (*aList)[from:aTotal]
+				} else {
+					aResult.CompareResult = (*aList)[from:to]
+				}
+				out := FillDataToCompareResult(&aResult)
+				m["total"] = aTotal
+				m["compareNum"] = searchBody.CompareNum
+				m["totalList"] = out
+				return m
+			} else {
+				m["total"] = 0
+				m["compareNum"] = searchBody.CompareNum
+				m["totalList"] = []interface{}{}
+				return m
+			}
+		}
+	} else {//搴曞簱鏁版嵁鐨勪簩娆℃绱�
+		var dbpApi dbapi.DbPersonApi
+		personIds, _ := dbpApi.FindLikePersonIds(searchBody.DataBases, searchBody.InputValue)
+		logger.Debug("searchPhoto first Result.len:",len(*co.CompareData),"personIds:",personIds)
+		if personIds !=nil {
+			var pIds []PersonId
+			b, _ := json.Marshal(personIds)
+			json.Unmarshal(b, &pIds)
+			if len(pIds) >0 {
+				var personIdArr []string
+				for _,pid :=range pIds{
+					personIdArr = append(personIdArr, pid.Id)
+				}
+				var aResult protomsg.SdkCompareResult
+				aList := getTwiceSearchResult(co, &personIdArr, searchBody)
+				aTotal := aList.Len()
+				if aTotal <= to {
+					aResult.CompareResult = (*aList)[from:aTotal]
+				} else {
+					aResult.CompareResult = (*aList)[from:to]
+				}
+				out := FillDataToCompareResult(&aResult)
+				m["total"] = aTotal
+				m["compareNum"] = searchBody.CompareNum
+				m["totalList"] = out
+				return m
+			}
+
+		} else {
+			m["total"] = 0
+			m["compareNum"] = searchBody.CompareNum
+			m["totalList"] = []interface{}{}
+			return m
+		}
+	}
+
+
+	//var sCompResult protomsg.SdkCompareResult
+	//total := len(*co.CompareData)
+	//if total <= to {
+	//	sCompResult.CompareResult = (*co.CompareData)[from:total]
 	//} else {
-	//	m["totalList"] = []CompareResult{}
+	//	sCompResult.CompareResult = (*co.CompareData)[from:to]
 	//}
+	//resultList := FillDataToCompareResult(&sCompResult)
+
+
+	m["total"] = 0
+	m["compareNum"] = searchBody.CompareNum
+	m["totalList"] = []interface{}{}
+
 	return m
+}
+
+func getTwiceSearchResult(co *service.CompareOnce, scopeIds *[]string, searchBody *models.EsSearch) *service.CompareList{
+	m := make(map[string]string)
+	for _,capId :=range *scopeIds {
+		m[capId] = capId
+	}
+	var totalData service.CompareList
+	for _,each :=range *co.CompareData {
+		if _,ok :=m[each.Id];ok && each.CompareScore >= searchBody.Threshold {
+			totalData = append(totalData, each)
+		}
+	}
+
+	if totalData != nil && totalData.Len() > 0{
+		sort.Sort(totalData)
+	}
+
+	return &totalData
 }
 
 func isInArr(id string,arr []string) bool {
@@ -523,13 +696,20 @@
 }
 
 
+// @Description 浜哄憳鐓х墖涓婁紶骞惰幏鍙栫壒寰佸��
+// @Router /data/api-v/dbperson/fileUploadTest [POST]
 func (controller FileController) UploadPersonTest(c *gin.Context) {
 	file, _, err := c.Request.FormFile("file") //image杩欎釜鏄痷plaodify鍙傛暟瀹氫箟涓殑   'fileObjName':'image'
 	if err != nil {
 		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
 		return
 	}
-	var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.WebPicIp == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return
+	}
+	var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
 
 	//灏嗕笂浼犵殑鍥剧墖浜や汉鑴告娴嬪拰浜鸿劯鎻愬彇锛岃幏寰楃壒寰�
 	fileBytes, _ := ioutil.ReadAll(file)
@@ -588,7 +768,12 @@
 			break
 		}
 	}
-	var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.WebPicIp == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return "",nil,err2
+	}
+	var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
 	//鏍规嵁浜鸿劯鍧愭爣鎵e嚭浜鸿劯灏忓浘
 	t1 := time.Now()
 	cutFaceImgData := util.SubImg(*pI, int(rcFace.Left), int(rcFace.Top), int(rcFace.Right), int(rcFace.Bottom))
@@ -598,7 +783,7 @@
 	logger.Debug("涓婁紶鍒皐eedfs鐢ㄦ椂:", time.Since(t1))
 	t1 = time.Now()
 	if e != nil {
-		fmt.Println(e.Error())
+		logger.Debug("WeedFSClient.UploadFile err:", e)
 		return "", nil, e
 	}
 
@@ -620,15 +805,16 @@
 
 /**涓婁紶鏂规硶**/
 
+// @Security ApiKeyAuth
 // @Summary 鎵归噺娣诲姞搴曞簱浜哄憳
 // @Description  渚濇嵁鍥剧墖鎵归噺娣诲姞搴曞簱浜哄憳
-// @Accept  mpfd
+// @Accept  multipart/form-data
 // @Produce json
 // @Tags dbperson 搴曞簱浜哄憳
 // @Param files formData file[] true "澶氫釜搴曞簱浜哄憳鍥剧墖"
 // @Param tableId formData string false "搴曞簱id,鏈塱d 鍒欏姞鍏ュ簳搴擄紝鏃犲垯鍙笂浼犲浘鐗�"
-// @Success 200 {string} json "{"code":200, msg:"", success:true,data:{}}"
-// @Failure 500 {string} json "{"code":500,  msg:"", success:false,data:null}"
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true,data:{}}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false,data:null}"
 // @Router /data/api-v/dbperson/moreFileUpload [POST]
 func (fc FileController) MoreFileUpload(c *gin.Context) {
 	//寰楀埌涓婁紶鐨勬枃浠�
@@ -642,8 +828,10 @@
 	}
 	extNames := make([]string, 0)
 	addResult := make(map[string]interface{}, 0)
-	successList := make([]string, 0)
+	successList := make([]string,0)
 	failList := make([]string,0)
+	noFaceList := make([]string,0)
+	multiFaceList := make([]string,0)
 	tAllStart := time.Now()
 	var wg sync.WaitGroup
 	var lock sync.Mutex
@@ -653,8 +841,15 @@
 			defer wg.Done()
 			tIStart := time.Now()
 			filename := head.Filename
+			fileExt := path.Ext(filename)
+			fileExt = strings.ToLower(fileExt)
+			if fileExt !=".jpg" && fileExt != ".jpeg" && fileExt != ".png" {
+				lock.Lock()
+				failList = append(failList, filename)
+				lock.Unlock()
+				return
+			}
 			file, err := head.Open()
-			fmt.Println(file, err, filename)
 			if err != nil {
 				lock.Lock()
 				failList = append(failList, filename)
@@ -664,7 +859,13 @@
 			field, _, err1 := uploadFileReturnAddr(file, filename, tableId)
 			lock.Lock()
 			if err1 != nil || field == "" {
-				failList = append(failList, filename)
+				if err1 !=nil && err1.Error() == "NotFeatureFindError" {
+					noFaceList = append(noFaceList, filename)
+				} else if err1 !=nil && err1.Error() == "TooManyFaces" {
+					multiFaceList = append(multiFaceList, filename)
+				} else {
+					failList = append(failList, filename)
+				}
 			} else {
 				successList = append(successList, filename)
 			}
@@ -676,6 +877,8 @@
 	logger.Debug("鍒�",len(fileHeaders),"寮犱汉鑴哥敤鏃讹細", time.Since(tAllStart))
 	addResult["successList"] = successList
 	addResult["failList"] = failList
+	addResult["noFaceList"] = noFaceList
+	addResult["multiFaceList"] = multiFaceList
 	addResult["fields"] = extNames
 
 	if len(successList)>0 {
@@ -693,9 +896,10 @@
 	IdCard string `json:"idCard"`
 }
 
+// @Security ApiKeyAuth
 // @Summary 涓婁紶鍥剧墖 骞跺垏鍥�
 // @Description  涓婁紶鍥剧墖 骞跺垏鍥�
-// @Accept  mpfd
+// @Accept  multipart/form-data
 // @Produce json
 // @Tags dbperson 搴曞簱浜哄憳
 // @Param file formData file true "搴曞簱浜哄憳鍥剧墖"
@@ -724,7 +928,12 @@
 		util.ResponseFormat(c, code.UploadFileError, err2.Error())
 		return
 	}
-	var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.WebPicIp == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return
+	}
+	var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
 	{
 		uri := weedfsUri
 		fileInfo, e := esutil.PostFormBufferData(uri, filename, "file", uploadData)
@@ -768,3 +977,9 @@
 	result["smImage"] = smUrl
 	util.ResponseFormat(c, code.Success, result)
 }
+
+/**涓嬭浇鏂规硶**/
+func Filedown(c *gin.Context) {
+	//鏆傛椂娌℃湁鎻愪緵鏂规硶
+
+}
diff --git a/controllers/initForData.go b/controllers/initForData.go
index fc0c9d4..1bd75ab 100644
--- a/controllers/initForData.go
+++ b/controllers/initForData.go
@@ -1,10 +1,12 @@
 package controllers
 
 import (
-	"basic.com/dbapi.git"
+	"basic.com/valib/logger.git"
 	"fmt"
 	"github.com/gin-gonic/gin"
+	"strconv"
 	"strings"
+	"webserver/cache"
 	"webserver/extend/code"
 	"webserver/extend/config"
 	"webserver/extend/esutil"
@@ -14,32 +16,40 @@
 type InitForData struct {
 }
 
+// @Security ApiKeyAuth
 // @Summary 鎶撴媿瀹炴椂鍥炬暟鎹垵濮嬪寲
 // @Description 瀹炴椂鑾峰彇鏁版嵁
 // @Accept  json
 // @Produce json
 // @Tags realTime
+// @Param obj body controllers.RealTimeArg false "鎶撴媿瀹炴椂鍥惧垵濮嬪寲鍙傛暟"
 // @Success 200 {string} json "{"code":200, msg:"", success:true}"
 // @Failure 500 {string} json "{"code":500,  msg:"", success:false}"
 // @Router /data/api-v/realTime/initForCaptureData [POST]
+//瀹炴椂鎶撴媿鏁版嵁鍒濆鍖�
 func (rc *RealTimeController) InitForCaptureData(c *gin.Context) {
-	searchBody := make(map[string]interface{}, 0)
+	//searchBody := make(map[string]interface{}, 0)
+	var searchBody RealTimeArg
 	c.BindJSON(&searchBody)
 	index := config.EsInfo.EsIndex.VideoPersons.IndexName + "," + config.EsInfo.EsIndex.Personaction.IndexName
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		util.ResponseFormat(c,code.ComError,"localConf wrong")
+		return
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + index + "/_search"
 	cameraIdStr := ""
-	if searchBody["treeNodes"] !=nil {
-		cameraId := searchBody["treeNodes"].([]interface{})
+	if searchBody.TreeNodes !=nil {
+		cameraId := searchBody.TreeNodes
 		if cameraId != nil && len(cameraId) > 0 {
 			esCameraId := strings.Replace(strings.Trim(fmt.Sprint(cameraId), "[]"), " ", "\",\"", -1)
 			cameraIdStr = "{\"terms\":{\"cameraId\":[\"" + esCameraId + "\"]}},"
 		}
 	}
 
-	var setApi dbapi.SysSetApi
-	_, sysconf := setApi.GetServerInfo()
-	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + sysconf.ServerId + "\"}}"
+	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + localConf.ServerId + "\"}}"
 
 	prama := "{\"query\":{\"bool\":{\"filter\":[{\"term\":{\"isAlarm\":\"1\"}}," +
 		cameraIdStr +
@@ -57,6 +67,7 @@
 	Tasks []string `json:"tasks"`
 }
 
+// @Security ApiKeyAuth
 // @Summary 瀹炴椂浠诲姟鐩戞帶鏁版嵁鍒濆鍖�
 // @Description 瀹炴椂鐩戞帶姣斿鏁版嵁
 // @Accept  json
@@ -85,11 +96,16 @@
 		taskIdStr = "{\"terms\":{\"taskId\":[\"" + esTaskId + "\"]}},"
 	}
 	//璇锋眰澶�
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		util.ResponseFormat(c,code.ComError,"localConf wrong")
+		return
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + index + "/_search"
-	var setApi dbapi.SysSetApi
-	_, sysconf := setApi.GetServerInfo()
-	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + sysconf.ServerId + "\"}}"
+
+	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + localConf.ServerId + "\"}}"
 
 	prama := "{\"query\":{\"bool\":{\"filter\":[" +
 		cameraIdStr +
diff --git a/controllers/monitoring.go b/controllers/monitoring.go
index 8cd1125..ccb3519 100644
--- a/controllers/monitoring.go
+++ b/controllers/monitoring.go
@@ -1,9 +1,11 @@
 package controllers
 
 import (
-	"basic.com/dbapi.git"
+	"basic.com/valib/logger.git"
 	"fmt"
+	"strconv"
 	"strings"
+	"webserver/cache"
 
 	"github.com/gin-gonic/gin"
 	"webserver/extend/code"
@@ -12,6 +14,7 @@
 	"webserver/extend/util"
 )
 
+// @Security ApiKeyAuth
 // @Summary 瀹炴椂鐩戞帶
 // @Description 瀹炴椂鐩戞帶姣斿鏁版嵁
 // @Accept  json
@@ -41,12 +44,16 @@
 		taskIdStr = "{\"terms\":{\"taskId\":[\"" + esTaskId + "\"]}},"
 	}
 	//璇锋眰澶�
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		util.ResponseFormat(c,code.ComError,"localConf wrong")
+		return
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + index + "/_search"
 
-	var setApi dbapi.SysSetApi
-	_, sysconf := setApi.GetServerInfo()
-	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + sysconf.ServerId + "\"}},"
+	analyServerFilterStr := "{\"term\":{\"analyServerId\":\"" + localConf.ServerId + "\"}},"
 
 	prama := "{\"query\":{\"bool\":{\"filter\":[" +
 		cameraIdStr +
@@ -59,7 +66,7 @@
 	fmt.Println(prama)
 	fmt.Println(url)
 	tokenRes := esutil.GetEsDataReq(url, prama, true)
-	/*    for _, value := range tokenRes["datalist"].([]interface{}) {
+	/*	for _, value := range tokenRes["datalist"].([]interface{}) {
 		if value.(map[string]interface{})["personId"] != nil {
 			info := getDBPersonInfo(value.(map[string]interface{})["personId"].(string))
 			for key, val := range info {
diff --git a/controllers/pollConfig.go b/controllers/pollConfig.go
index b5ad9b1..9362d88 100644
--- a/controllers/pollConfig.go
+++ b/controllers/pollConfig.go
@@ -13,21 +13,20 @@
 
 type PollConfig struct {
 	ServerId   string `json:"server_id"`   //鏈嶅姟鍣╥d
-	PollPeriod int    `json:"poll_period"` //杞鍛ㄦ湡
-	Delay      int    `json:"delay"`       //寤舵椂鏃堕棿
+	PollPeriod int32    `json:"poll_period"` //杞鍛ㄦ湡
+	Delay      int32    `json:"delay"`       //寤舵椂鏃堕棿
 	Enable     bool   `json:"enable"`      //鏄惁鍚敤杞
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 淇濆瓨杞鍛ㄦ湡
 // @Description 淇濆瓨杞鍛ㄦ湡
 // @Produce json
 // @Tags 杞閰嶇疆
-// @Param period query int true "杞鍛ㄦ湡"
+// @Param period formData int true "杞鍛ㄦ湡"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/pollConfig/savePollPeriod [post]
-*/
 func (controller PollConfigController) SavePollPeriod(c *gin.Context) {
 	periodStr := c.PostForm("period")
 	period, err := strconv.Atoi(periodStr)
@@ -44,16 +43,15 @@
 	}
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 淇濆瓨杞寤舵椂
 // @Description 淇濆瓨杞寤舵椂
 // @Produce json
 // @Tags 杞閰嶇疆
-// @Param delay query int true "杞寤舵椂鏃堕棿"
+// @Param delay formData int true "杞寤舵椂鏃堕棿"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/pollConfig/savePollDelay [post]
-*/
 func (controller PollConfigController) SavePollDelay(c *gin.Context) {
 	delayStr := c.PostForm("delay")
 	delay, err := strconv.Atoi(delayStr)
@@ -70,7 +68,7 @@
 	}
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 鑾峰彇鏈満杞閰嶇疆
 // @Description 鑾峰彇鏈満杞閰嶇疆
 // @Produce json
@@ -78,7 +76,6 @@
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/pollConfig/getPollConfig [get]
-*/
 func (controller PollConfigController) GetPollConfig(c *gin.Context) {
 	var api dbapi.SysSetApi
 	b, data := api.GetPollConfig()
@@ -93,16 +90,16 @@
 	Enable bool `json:"enable"`
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 鍒囨崲杞寮�鍏�
 // @Description 鍒囨崲杞寮�鍏�
+// @Accept json
 // @Produce json
 // @Tags 杞閰嶇疆
 // @Param argBody body controllers.PollEnableVo true "寮�鍏冲弬鏁�"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/pollConfig/updateEnable [post]
-*/
 func (controller PollConfigController) UpdateEnable(c *gin.Context) {
 	var argBody PollEnableVo
 	if err := c.BindJSON(&argBody); err != nil {
diff --git a/controllers/sdk.go b/controllers/sdk.go
index b3965c5..dda196f 100644
--- a/controllers/sdk.go
+++ b/controllers/sdk.go
@@ -2,9 +2,13 @@
 
 import (
 	"basic.com/dbapi.git"
+	uuid "github.com/satori/go.uuid"
 	"webserver/extend/code"
+	"webserver/extend/config"
+	"basic.com/valib/logger.git"
 	"webserver/extend/util"
 	"github.com/gin-gonic/gin"
+	"webserver/service"
 )
 
 type SdkController struct {
@@ -37,8 +41,10 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 绠楁硶淇濆瓨
 // @Description 绠楁硶淇濆瓨
+// @Accept json
 // @Produce json
 // @Tags sdk
 // @Param reqMap body controllers.SdkVo true "浜鸿劯妫�娴�"
@@ -64,6 +70,7 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 鏌ユ壘鎵�鏈夌畻娉�
 // @Description 鏌ユ壘鎵�鏈夌畻娉�
 // @Produce json
@@ -82,6 +89,7 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 鏍规嵁id鑾峰彇绠楁硶淇℃伅
 // @Description 鏍规嵁id鑾峰彇绠楁硶淇℃伅
 // @Produce json
@@ -128,6 +136,7 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 鏍规嵁taskId鑾峰彇绠楁硶淇℃伅
 // @Description 鏍规嵁taskId鑾峰彇绠楁硶淇℃伅
 // @Produce json
@@ -150,4 +159,44 @@
 	} else {
 		util.ResponseFormat(c,code.ComError,sdks)
 	}
+}
+
+func (sc SdkController) SdkDownLoad(c *gin.Context) {
+	path,exist := c.GetQuery("path")
+	if !exist {
+		util.ResponseFormat(c,code.ComError,"涓嬭浇鐨勭畻娉曞弬鏁版湁璇�")
+	}
+	logger.Info(path)
+	flag := c.Query("needUpdateMiddle")
+	// 涓嬭浇绠楁硶锛堟湁鏃跺�欎篃闇�瑕佹妸涓棿浠朵竴璧蜂笅杞戒笅鏉ワ級
+	if flag == "true" {
+		// 涓嬭浇骞舵洿鏂颁腑闂翠欢,甯︿笂MD5鏍¢獙
+		flag1,err := service.DownSo("http://"+config.SoPath.Ip+":"+config.SoPath.Port+"/"+"middleware.so")
+		logger.Debug("涓棿浠惰矾寰勶細","http://"+config.SoPath.Ip+":"+config.SoPath.Port+"/"+"middleware.so")
+		if err != nil {
+			logger.Info(err)
+		}
+		if !flag1 {
+			util.ResponseFormat(c,code.ComError,"璇烽噸鏂颁笅杞界畻娉�")
+		}
+	}
+	// 涓嬭浇绠楁硶锛屾牎楠岋紝骞跺啓鍏ュ埌鐩爣鐩綍涓�
+	flag2,err2 := service.DownSo(path)
+	if err2 != nil {
+		logger.Info(err2)
+	}
+	if !flag2 {
+		util.ResponseFormat(c,code.ComError,"璇烽噸鏂颁笅杞界畻娉�")
+	}
+	// 灏嗙畻娉曞拰so鍚嶇О瀛樺埌瑙勫垯绉佹湁鐨勬敞鍐岃〃
+	var soApi dbapi.SoApi
+	param := make(map[string]interface{})
+	param["id"] = uuid.NewV4().String()
+	sdkId := uuid.NewV4().String()
+	param["sdkId"] = sdkId
+	param["soName"] = service.GetFileNameFromUrl(path,true)
+	flag3,_ := soApi.Add(param)
+	if flag3 {
+		util.ResponseFormat(c,code.Success,"涓嬭浇绠楁硶鎴愬姛锛�")
+	}
 }
\ No newline at end of file
diff --git a/controllers/sysMenu.go b/controllers/sysMenu.go
index 1010498..d0fc177 100644
--- a/controllers/sysMenu.go
+++ b/controllers/sysMenu.go
@@ -1,9 +1,10 @@
 package controllers
 
 import (
+	"basic.com/dbapi.git"
 	"github.com/gin-gonic/gin"
 	"webserver/extend/code"
-	"webserver/extend/logger"
+	"basic.com/valib/logger.git"
 	"webserver/extend/util"
 	"webserver/middlewares/auth"
 )
@@ -12,26 +13,49 @@
 
 }
 
-/*
+// @Security ApiKeyAuth
 // @Summary 褰撳墠鐢ㄦ埛鐨勭郴缁熻彍鍗�
 // @Description 褰撳墠鐢ㄦ埛鐨勭郴缁熻彍鍗�
-// @Accept json
 // @Produce json
 // @Tags 绯荤粺鑿滃崟
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}"
 // @Router /data/api-v/sysmenus/me [get]
-*/
 func (controller SysMenuController) Me(c *gin.Context) {
 	module := c.Param("module")
 	logger.Debug("me.module:",module)
 	authDriver := auth.GenerateAuthDriver()
-	user := (*authDriver).User(c)
-	logger.Debug("current:",user)
-	if user !=nil {
-		menus := user.(map[string]interface{})["permissions"]
+	userM := (*authDriver).User(c)
+	if userM !=nil {
+		menus := userM["permissions"]
 		util.ResponseFormat(c,code.Success,menus)
 	} else {
 		util.ResponseFormat(c,code.NotLogin,"")
 	}
+}
+
+// @Security ApiKeyAuth
+// @Summary 鏌ユ壘褰撳墠鐢ㄦ埛鍙鐨勭郴缁熻彍鍗�
+// @Description 鏌ユ壘褰撳墠鐢ㄦ埛鍙鐨勭郴缁熻彍鍗�
+// @Produce json
+// @Tags 绯荤粺鑿滃崟
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}"
+// @Router /data/api-v/sysmenus/tree [get]
+func (smc SysMenuController) MenuTree(c *gin.Context) {
+	authDriver := auth.GenerateAuthDriver()
+	userM := (*authDriver).User(c)
+	logger.Debug("current:",userM)
+	if userM != nil {
+		userId := userM["id"].(string)
+		var api dbapi.SysMenuApi
+		b,d := api.MenuTree(userId)
+		if b {
+			util.ResponseFormat(c,code.Success,d)
+		} else {
+			util.ResponseFormat(c,code.ComError,"")
+		}
+	} else {
+		util.ResponseFormat(c,code.NotLogin,"璇风櫥褰�")
+	}
 }
\ No newline at end of file
diff --git a/controllers/sysRole.go b/controllers/sysRole.go
index 2d32936..d20d373 100644
--- a/controllers/sysRole.go
+++ b/controllers/sysRole.go
@@ -1 +1,31 @@
 package controllers
+
+import (
+	"basic.com/dbapi.git"
+	"github.com/gin-gonic/gin"
+	"webserver/extend/code"
+	"webserver/extend/util"
+)
+
+type RoleController struct {
+
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鏌ユ壘瑙掕壊鍒楄〃
+// @Description 鏌ユ壘瑙掕壊鍒楄〃
+// @Tags 绯荤粺瑙掕壊
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-v/role/findAll [get]
+*/
+func (rc RoleController) FindAll(c *gin.Context) {
+	var api dbapi.SysRoleApi
+	b,d := api.FindAll()
+	if b {
+		util.ResponseFormat(c,code.Success,d)
+	} else {
+		util.ResponseFormat(c,code.ComError,"")
+	}
+}
diff --git a/controllers/syssetcont.go b/controllers/syssetcont.go
index fe25b70..0ebeb4e 100644
--- a/controllers/syssetcont.go
+++ b/controllers/syssetcont.go
@@ -3,6 +3,7 @@
 import (
 	"basic.com/dbapi.git"
 	"github.com/gin-gonic/gin"
+	"regexp"
 	"webserver/extend/code"
 	"webserver/extend/config"
 	"webserver/extend/util"
@@ -42,6 +43,7 @@
 	UpdateTime string `json:"UpdateTime"`
 }
 
+// @Security ApiKeyAuth
 // @Summary 鍩虹璁剧疆鏌ヨ
 // @Description 鍩虹璁剧疆鏌ヨ
 // @Accept  json
@@ -60,6 +62,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 鎶ヨ璁剧疆淇敼
 // @Description 鎶ヨ璁剧疆淇敼
 // @Accept  json
@@ -86,6 +89,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 鎶ヨ鏃堕暱淇敼
 // @Description 鎶ヨ鏃堕暱淇敼
 // @Accept  json
@@ -108,6 +112,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 瑙嗛鎴彇鏃堕暱淇敼
 // @Description 瑙嗛鎴彇鏃堕暱淇℃伅
 // @Accept  x-www-form-urlencoded
@@ -133,6 +138,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 鑾峰彇鍒嗘瀽璁惧淇℃伅
 // @Description  鍒嗘瀽璁惧淇℃伅
 // @Accept  json
@@ -160,6 +166,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // saveDevInfo  dev_id dev_name
 // @Summary 淇濆瓨瑙嗛鍒嗘瀽璁惧淇℃伅
 // @Description 鍒嗘瀽璁惧淇℃伅
@@ -184,7 +191,7 @@
 	}
 }
 
-
+// @Security ApiKeyAuth
 // @Summary GB28181璁剧疆鏌ヨ
 // @Description GB28181璁剧疆淇℃伅鏌ヨ
 // @Accept  json
@@ -203,6 +210,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary GB28181璁剧疆淇℃伅淇敼
 // @Description GB28181璁剧疆淇敼
 // @Accept  json
@@ -228,3 +236,187 @@
 		util.ResponseFormat(c,code.ComError,"鏇存柊澶辫触")
 	}
 }
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鑾峰彇鏃堕棿閰嶇疆
+// @Description  绯荤粺鏃堕棿閰嶇疆淇℃伅
+// @Accept  json
+// @Produce json
+// @Tags sysset
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/clockInfo [GET]
+*/
+func (sset SysSetController) GetClockinfo(c *gin.Context) {
+	resData := make(map[string]interface{}, 0)
+	resData["time_zone"], resData["local_time"] = sys.TimeZone()
+	resData["ntp"], resData["ntp_server"], resData["interval"] = sys.NTPConfig()
+
+	util.ResponseFormat(c, code.Success, resData)
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 娴嬭瘯鍚屾鏃堕棿
+// @Description 娴嬭瘯鍚屾鏃堕棿鏈嶅姟鍣ㄦ槸鍚﹀彲鐢�
+// @Produce json
+// @Tags sysset
+// @Param server query string true "鏃堕棿鏈嶅姟鍣╥p"
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/ntpTest [GET]
+*/
+func (sset SysSetController) TestNTPServer(c *gin.Context) {
+	ntpServer := c.Query("server")
+
+	if root := sys.CheckRootPermissions(); !root {
+		util.ResponseFormat(c, code.ServiceInsideError, "鏈嶅姟鍣ㄦ病鏈変慨鏀规椂闂寸殑鏉冮檺")
+		return
+	}
+
+	isConn := sys.RunNTPDate(ntpServer)
+	if !isConn {
+		util.ResponseFormat(c, code.RequestParamError, "NTP鏈嶅姟鍣ㄤ笉鍙敤")
+		return
+	}
+
+	util.ResponseFormat(c, code.Success, "")
+
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 璁剧疆绯荤粺鏃堕棿
+// @Description 鏍℃绯荤粺鏃堕棿
+// @Accept  json
+// @Produce json
+// @Tags sysset
+// @Param config body controllers.SysClockConfigVo true "鏍℃椂淇℃伅"
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/updateClock [POST]
+*/
+func (sset SysSetController) SetSysClock(c *gin.Context) {
+	var args SysClockConfigVo
+	err := c.BindJSON(&args)
+	if err != nil {
+		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟鏈夎")
+		return
+	}
+
+	if args.TimeZone != "CST" && args.TimeZone != "UTC" {
+		if r := sys.SetTimeZone(args.TimeZone); !r {
+			util.ResponseFormat(c, code.RequestParamError, "鏃跺尯鍙傛暟閿欒")
+			return
+		}
+	}
+
+	if !args.NTP {
+		if r := sys.SetLocalTime(args.NewTime); !r {
+			util.ResponseFormat(c, code.RequestParamError, "鎸囧畾鐨勬椂闂村弬鏁伴敊璇�")
+			return
+		}
+	} else {
+		if r := sys.EnableNTPCron(args.NTPServer, args.Interval); !r {
+			util.ResponseFormat(c, code.RequestParamError, "鎸囧畾鐨勬湇鍔″櫒鍦板潃閿欒")
+			return
+		}
+	}
+
+	util.ResponseFormat(c, code.UpdateSuccess, "閰嶇疆鎴愬姛")
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鏌ヨ绯荤粺杩愯淇℃伅
+// @Description 鑾峰彇褰撳墠绯荤粺鐨勮繍琛岀姸鎬侊紝CPU, GPU, 鍐呭瓨绛�
+// @Produce json
+// @Tags sysset
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/sysinfo [GET]
+*/
+func (sset SysSetController) GetSysInfo(c *gin.Context) {
+	info := sys.GetSysInfo()
+	util.ResponseFormat(c, code.UpdateSuccess, info)
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鏌ヨ绯荤粺鐘舵�侀槇鍊艰缃�
+// @Description 鑾峰彇褰撳墠绯荤粺鐨勮繍琛岀姸鎬侊紝CPU, GPU, 鍐呭瓨鐨勯槇鍊奸厤缃�
+// @Produce json
+// @Tags sysset
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/sysThresholds [GET]
+*/
+func (sset SysSetController) GetSysThresholds(c *gin.Context) {
+	util.ResponseFormat(c, code.UpdateSuccess, config.Server.SysThresholds)
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 閲嶅惎绯荤粺
+// @Description 閲嶅惎鎿嶄綔绯荤粺
+// @Produce json
+// @Tags sysset
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/reboot [GET]
+*/
+func (sset SysSetController) RebootOS(c *gin.Context) {
+	if isOk, msg := sys.Reboot(); !isOk {
+		util.ResponseFormat(c, code.UpdateFail, msg)
+		return
+	}
+
+	util.ResponseFormat(c, code.Success, "姝e湪閲嶅惎")
+}
+
+/*
+// @Summary 鑾峰彇瀹氭椂閲嶅惎
+// @Description 鑾峰彇瀹氭椂閲嶅惎浠诲姟鐨勯厤缃鍒�
+// @Produce json
+// @Tags sysset
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/rebootTask [GET]
+*/
+func (sset SysSetController) GetRebootTask(c *gin.Context) {
+	_, msg := sys.ReadRebootTaskInCrontab()
+	util.ResponseFormat(c, code.Success, msg)
+}
+
+/*
+// @Summary 璁剧疆瀹氭椂閲嶅惎
+// @Description 璁剧疆瀹氭椂閲嶅惎浠诲姟鐨勯厤缃鍒�
+// @Accept x-www-form-urlencoded
+// @Produce json
+// @Tags sysset
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
+// @Router /data/api-v/sysset/rebootTask [POST]
+*/
+func (sset SysSetController) SetRebootTask(c *gin.Context) {
+	task := c.PostForm("task")
+	if len(task) < 1 {
+		sys.CleanRebootTask()
+		util.ResponseFormat(c, code.Success, "閰嶇疆鎴愬姛")
+		return
+	}
+
+	regEx := `^([0-9*]+\s){4}[0-9*]+$`
+	if r, _ := regexp.MatchString(regEx, task); !r {
+		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟閿欒")
+		return
+	}
+
+	if r := sys.UpdateRebootTask(task); !r {
+		util.ResponseFormat(c, code.UpdateFail, "閰嶇疆澶辫触")
+		return
+	}
+
+	util.ResponseFormat(c, code.Success, "閰嶇疆鎴愬姛")
+}
diff --git a/controllers/taglist.go b/controllers/taglist.go
index b601422..2f3c5d9 100644
--- a/controllers/taglist.go
+++ b/controllers/taglist.go
@@ -2,25 +2,32 @@
 
 import (
 	"basic.com/dbapi.git"
+	"basic.com/valib/logger.git"
+	"encoding/json"
+	"fmt"
+	"strconv"
+	"webserver/cache"
 	"webserver/extend/code"
+	"webserver/extend/config"
+	"webserver/extend/esutil"
 	"webserver/extend/util"
 
 	"github.com/gin-gonic/gin"
 )
 
-// @Summary 搴曞簱鏍囩鍒楄〃
+// @Security ApiKeyAuth
+// @Summary 鏍囩鍒楄〃
 // @Description 杩斿洖搴曞簱鏍囩
 // @Accept  json
 // @Produce json
 // @Tags es
 // @Success 200 {string} json "{"code":200, msg:"", success:true}"
 // @Failure 500 {string} json "{"code":500, msg:"", success:false}"
-// @Router /data/api-v/es/taskList [POST]
+// @Router /data/api-v/es/tagList [POST]
 func (sc *EsSearchController) PostEsTagList(c *gin.Context) {
 
 	var dtApi dbapi.DbTableApi
-	var dbpApi dbapi.DbPersonApi
-	dts, err := dtApi.FindAllDbTablesByCurServer()
+	dts, err := dtApi.FindAllDbTablesByCurServer("-1")
 	if err == nil {
 		if dts !=nil {
 			sources := make([]map[string]interface{}, 0)
@@ -30,9 +37,10 @@
 				tokenRes["title"] = dt.TableName
 				tokenRes["value"] = dt.Id
 				tokenRes["status"] = dt.IsDelete
+				tokenRes["bwType"] = dt.BwType //0锛氱櫧鍚嶅崟锛�1锛氶粦鍚嶅崟
+				tokenRes["analyServerId"] = dt.AnalyServerId //涓虹┖鏄悓姝ュ簱锛屼笉涓虹┖鏄湰鍦板簱
 				if dt.IsDelete == 1 {
-					personTotal,_ := dbpApi.GetPersonTotal(dt.Id)
-					if personTotal == 0 {
+					if GetTotalFromDb(dt.Id) == false {
 						continue
 					}
 				}
@@ -44,3 +52,39 @@
 	}
 	util.ResponseFormat(c,code.ComError,"鏌ヨ搴曞簱鏍囩澶辫触")
 }
+
+//鍒ゆ柇搴曞簱鏄惁鏈夋暟鎹�
+func GetTotalFromDb(id string) (flag bool) {
+	flag = false
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		return false
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
+		"/" + config.EsInfo.EsIndex.VideoPersons.IndexName + "/_search"
+	prama := "{\"query\":{\"bool\":{\"filter\":[{\"term\":{\"baseInfo.tableId\":\"" + id + "\"}}]}},\"size\":0}"
+	buf, err := esutil.EsReq("POST", url, []byte(prama))
+	if err != nil {
+		fmt.Println("http request info is err!")
+		return
+	}
+	var info interface{}
+	json.Unmarshal(buf, &info)
+	out, ok := info.(map[string]interface{})
+	if !ok {
+		fmt.Println("http response interface can not change map[string]interface{}")
+		return
+	}
+	middle, ok := out["hits"].(map[string]interface{})
+	if !ok {
+		fmt.Println("first hits change error!")
+		return
+	}
+
+	total := int(middle["total"].(float64))
+	if total > 0 {
+		flag = true
+	}
+	return flag
+}
\ No newline at end of file
diff --git a/controllers/task.go b/controllers/task.go
index 999f82e..4a5a246 100644
--- a/controllers/task.go
+++ b/controllers/task.go
@@ -2,9 +2,13 @@
 
 import (
 	"basic.com/dbapi.git"
+	"basic.com/pubsub/esutil.git"
 	"basic.com/pubsub/protomsg.git"
 	"encoding/json"
+	"strconv"
 	"time"
+	"webserver/cache"
+	"webserver/extend/config"
 
 	"github.com/gin-gonic/gin"
 	"webserver/extend/code"
@@ -35,6 +39,7 @@
 )
 
 /*
+// @Security ApiKeyAuth
 // @Summary 鏌ユ壘鎵�鏈変换鍔★紝鍖呭惈浠诲姟淇℃伅鍜屽搴旂殑绠楁硶淇℃伅
 // @Description 鏌ユ壘鎵�鏈変换鍔�
 // @Produce json
@@ -68,6 +73,66 @@
 }
 
 /*
+// @Security ApiKeyAuth
+// @Summary 妫�绱㈤〉闈㈣幏鍙栨墍鏈変换鍔″垪琛紙鍖呭惈宸插垹闄ょ殑浠诲姟锛�
+// @Description 妫�绱㈤〉闈㈣幏鍙栨墍鏈変换鍔″垪琛紙鍖呭惈宸插垹闄ょ殑浠诲姟锛�
+// @Produce json
+// @Tags task
+// @Success 200 {string} json "{"code":200, msg:"璇锋眰澶勭悊鎴愬姛",data:"",success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"璇锋眰澶辫触",data:"",success:false}"
+// @Router /data/api-v/task/aggregateTaskList [GET]
+*/
+func (tc TaskController) AggregateTaskList(c *gin.Context) {
+	// 鏄剧ず鎵�鏈変换鍔�: 鑾峰彇淇℃伅
+	var taskApi dbapi.TaskApi
+
+	taskInfos := taskApi.FindAll()
+	m := make(map[string]string)
+	var arr []protomsg.TaskSdkInfo
+	for _,ti :=range taskInfos{
+		if ti.Task.Taskid != FaceExtract_VirtualTaskId{
+			arr = append(arr,ti)
+			m[ti.Task.Taskid] = ti.Task.Taskid
+		}
+	}
+	var tasks []TaskSdkVo
+	dataBytes, err := json.Marshal(arr)
+	if err !=nil {
+		util.ResponseFormat(c,code.ComError,[]TaskSdkVo{})
+	} else {
+		if err := json.Unmarshal(dataBytes, &tasks);err !=nil {
+			util.ResponseFormat(c,code.ComError,[]TaskSdkVo{})
+		} else {
+			//澶勭悊宸茶鍒犻櫎鐨勪换鍔�
+			localConf, _ := cache.GetServerInfo()
+			if localConf.AlarmIp != "" && localConf.ServerId != "" && localConf.AlarmPort>0 {
+				indexName := config.EsInfo.EsIndex.VideoPersons.IndexName + "," + config.EsInfo.EsIndex.Personaction.IndexName
+				esTaskM, e := esutil.AggregateTaskList(localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)), indexName, localConf.ServerId)
+				if e==nil && esTaskM !=nil {
+					for _,tM :=range esTaskM {
+						if _,ok := m[tM["taskId"].(string)];!ok {//琛ㄧず姝や换鍔″凡琚垹闄�
+							taskId := tM["taskId"].(string)
+							m[taskId] = taskId
+							tasks = append(tasks, TaskSdkVo{
+								Task:TaskVo{
+									Taskid:	taskId,
+									Taskname: tM["taskName"].(string),
+									DelFlag: true,
+								},
+								Sdks:[]SdkVo{},
+							})
+						}
+					}
+				}
+			}
+
+			util.ResponseFormat(c,code.Success,tasks)
+		}
+	}
+}
+
+/*
+// @Security ApiKeyAuth
 // @Summary 娣诲姞浠诲姟
 // @Description 鏌ユ壘鎵�鏈変换鍔�
 // @Accept json
@@ -106,8 +171,10 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 缁欎换鍔℃坊鍔犵畻娉�
 // @Description 浠诲姟娣诲姞绠楁硶
+// @Accept json
 // @Produce json
 // @Tags task
 // @Param taskSdkAdd body controllers.TaskSdkAdd true "浠诲姟id"
@@ -133,12 +200,13 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 浠诲姟鍒犻櫎绠楁硶
 // @Description 鏍规嵁taskid鍜宻dkid鍒犻櫎
 // @Produce json
 // @Tags task
-// @Param taskId path string true "浠诲姟id"
-// @Param sdkId path string true "绠楁硶id"
+// @Param taskId query string true "浠诲姟id"
+// @Param sdkId query string true "绠楁硶id"
 // @Success 200 {string} json "{"code":200, msg:"璇锋眰澶勭悊鎴愬姛",data:"",success:true}"
 // @Failure 500 {string} json "{"code":500, msg:"璇锋眰澶辫触",data:"",success:false}"
 // @Router /data/api-v/task/delTaskSdk [GET]
@@ -160,12 +228,14 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 鏇存柊浠诲姟鍚嶇О
 // @Description 鏇存柊浠诲姟鍚嶇О
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags task
-// @Param taskId query string true "taskId"
-// @Param taskName query string true "taskName"
+// @Param taskId formData string true "taskId"
+// @Param taskName formData string true "taskName"
 // @Success 200 {string} json "{"code":200, msg:"",data:"",success:true}"
 // @Failure 500 {string} json "{"code":500, msg:"",data:"",success:false}"
 // @Router /data/api-v/task/updateTaskName [POST]
@@ -192,8 +262,10 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 鏇存柊浠诲姟鐘舵��
 // @Description 锛堢畻娉曚笉鍙�,鍙洿鏂颁换鍔$姸鎬侊級
+// @Accept json
 // @Produce json
 // @Tags task
 // @Param taskStatus body controllers.TaskStatusVo true "鍙傛暟"
@@ -218,13 +290,13 @@
 	}
 }
 
-
 /*
+// @Security ApiKeyAuth
 // @Summary 鍒犻櫎浠诲姟
 // @Description 鏍规嵁浠诲姟id鍒犻櫎浠诲姟
 // @Produce json
 // @Tags task
-// @Param taskId path string true "浠诲姟id"
+// @Param taskId query string true "浠诲姟id"
 // @Success 200 {string} json "{"code":200, msg:"璇锋眰澶勭悊鎴愬姛",data:"",success:true}"
 // @Failure 500 {string} json "{"code":500, msg:"璇锋眰澶辫触",data:"",success:false}"
 // @Router /data/api-v/task/delete [GET]
@@ -259,6 +331,7 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 淇濆瓨绠楁硶瑙勫垯
 // @Description 淇濆瓨绠楁硶瑙勫垯
 // @Accept json
@@ -287,11 +360,14 @@
 }
 
 /*
+// @Security ApiKeyAuth
 // @Summary 鍒犻櫎绠楁硶瑙勫垯
 // @Description 鍒犻櫎绠楁硶瑙勫垯
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags 绠楁硶瑙勫垯
-// @Param id query string true "id"
+// @Param taskId formData string true "taskId"
+// @Param sdkId formData string true "sdkId"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/task/deleteTaskSdkRule [post]
@@ -311,14 +387,14 @@
 	}
 }
 
-
 /*
+// @Security ApiKeyAuth
 // @Summary 鏌ヨ绠楁硶瑙勫垯
 // @Description 鏌ヨ绠楁硶瑙勫垯
 // @Produce json
 // @Tags 绠楁硶瑙勫垯
-// @Param taskId path string true "浠诲姟id"
-// @Param sdkId path string true "绠楁硶id"
+// @Param taskId query string true "浠诲姟id"
+// @Param sdkId query string true "绠楁硶id"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
 // @Router /data/api-v/task/getRulesByTaskSdk [get]
@@ -338,3 +414,23 @@
 		util.ResponseFormat(c,code.ComError,"鏌ヨ澶辫触")
 	}
 }
+
+/*
+// @Security ApiKeyAuth
+// @Summary 缁熻姣忎釜浠诲姟鐨勬憚鍍忔満鏁伴噺
+// @Description 缁熻姣忎釜浠诲姟鐨勬憚鍍忔満鏁伴噺
+// @Produce json
+// @Tags task
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-v/task/statisticTaskCamera [get]
+*/
+func (tc TaskController) StatisticTaskCamera(c *gin.Context) {
+	var taskApi dbapi.TaskApi
+	b,d := taskApi.StatisticTaskCamera()
+	if b {
+		util.ResponseFormat(c,code.Success, d)
+	} else {
+		util.ResponseFormat(c,code.ComError, "")
+	}
+}
diff --git a/controllers/tasklist.go b/controllers/tasklist.go
index 820e9d9..13653a6 100644
--- a/controllers/tasklist.go
+++ b/controllers/tasklist.go
@@ -1,7 +1,10 @@
 package controllers
 
 import (
+	"basic.com/valib/logger.git"
 	"fmt"
+	"strconv"
+	"webserver/cache"
 
 	"github.com/gin-gonic/gin"
 	"webserver/extend/code"
@@ -10,18 +13,23 @@
 	"webserver/extend/util"
 )
 
-//浠诲姟鍒楄〃
+// @Security ApiKeyAuth
 // @Summary 浠诲姟鍒楄〃
 // @Description 杩斿洖浠诲姟鍒楄〃
 // @Accept  json
 // @Produce json
 // @Tags es
-// @Success 200 {string} json "{"code":200, msg:"", success:true}"
-// @Failure 500 {string} json "{"code":500, msg:"", success:false}"
+// @Success 200 {string} json "{"code":200, msg:"鐩綍缁撴瀯鏁版嵁", success:true}"
+// @Failure 500 {string} json "{"code":500,  msg:"杩斿洖閿欒淇℃伅", success:false}"
 // @Router /data/api-v/es/tagList [POST]
 func (sc *EsSearchController) PostEsTaskList(c *gin.Context) {
-
-	url := "http://" + config.EsInfo.Masterip + ":" + config.EsInfo.Httpport +
+	localConf, err2 := cache.GetServerInfo()
+	if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
+		logger.Debug("localConfig is wrong!!!")
+		util.ResponseFormat(c,code.ComError,"localConf wrong")
+		return
+	}
+	url := "http://" + localConf.AlarmIp + ":" + strconv.Itoa(int(localConf.AlarmPort)) +
 		"/" + config.EsInfo.EsIndex.VideoPersons.IndexName + "," + config.EsInfo.EsIndex.Personaction.IndexName + "/_search"
 
 	prama := "{\"size\":0,\"aggs\":{\"taskId_list\":{\"terms\":{\"field\":\"taskId\"}}}}"
diff --git a/controllers/user.go b/controllers/user.go
index d12deff..4ce48d1 100644
--- a/controllers/user.go
+++ b/controllers/user.go
@@ -21,15 +21,15 @@
 
 // @Summary 鐢ㄦ埛鐧诲綍
 // @Description 鐢ㄦ埛鐧诲綍
-// @Accept json
+// @Accept x-www-form-urlencoded
 // @Produce json
 // @Tags 鐢ㄦ埛
-// @Param username query string true "鐢ㄦ埛鍚�"
-// @Param password query string true "瀵嗙爜"
+// @Param username formData string true "鐢ㄦ埛鍚�"
+// @Param password formData string true "瀵嗙爜"
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}"
-// @Router /data/api-v/sys/login [post]
-func (controller UserController) Login(c *gin.Context) {
+// @Router /data/api-u/sys/login [post]
+func (uc UserController) Login(c *gin.Context) {
 	userName := c.PostForm("username")
 	password := c.PostForm("password")
 	if userName == "" || password == "" {
@@ -41,7 +41,16 @@
 	if flag {
 		authDriver := auth.GenerateAuthDriver()
 		loginedM := util.Struct2Map(data)
-		tokenStr := (*authDriver).Login(c.Request, c.Writer, loginedM)
+		tokenM := make(map[string]interface{},2)
+		tokenM["id"] = loginedM["id"]
+		tokenM["username"] = loginedM["username"]
+		tokenM["permissions"] = loginedM["permissions"]
+		tokenStr := (*authDriver).Login(c.Request, c.Writer, tokenM)
+
+
+		userId := loginedM["id"].(string)
+		auth.RemoveOutUser(userId)
+
 		c.JSON(200,map[string]interface{}{
 			"userInfo":loginedM,
 			"access_token":tokenStr,
@@ -55,6 +64,7 @@
 	}
 }
 
+// @Security ApiKeyAuth
 // @Summary 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅
 // @Description 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅
 // @Accept json
@@ -62,8 +72,8 @@
 // @Tags 鐢ㄦ埛
 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
 // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}"
-// @Router /data/api-v/users/current [get]
-func (controller UserController) Current(c *gin.Context) {
+// @Router /data/api-u/users/current [get]
+func (uc UserController) Current(c *gin.Context) {
 	authDriver := auth.GenerateAuthDriver()
 	user := (*authDriver).User(c)
 	if user !=nil {
@@ -84,4 +94,92 @@
 */
 func (controller UserController) Logout(c *gin.Context){
 	c.JSON(http.StatusOK,"閫�鍑烘垚鍔�")
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鏌ユ壘鎵�鏈夌敤鎴�
+// @Description 鏌ユ壘鎵�鏈夌敤鎴�
+// @Accept json
+// @Produce json
+// @Tags 鐢ㄦ埛
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-u/users/findAllUser [get]
+*/
+func (uc UserController) FindAllUser(c *gin.Context) {
+	authDriver := auth.GenerateAuthDriver()
+	userM := (*authDriver).User(c)
+	userId := userM["id"].(string)
+	var api dbapi.UserApi
+	b,d := api.FindAllUser(userId)
+	if b {
+		util.ResponseFormat(c,code.Success,d)
+	} else {
+		util.ResponseFormat(c,code.ComError,"")
+	}
+}
+
+type UserEditVo struct {
+	Id string `json:"id"`
+	UserName string `json:"username"`
+	NewPwd string `json:"newPwd"`
+	MenuIds []string `json:"menuIds"`
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 缂栬緫姝ょ敤鎴凤紝杩斿洖姝ょ敤鎴风殑鏉冮檺鑿滃崟
+// @Description 缂栬緫姝ょ敤鎴凤紝杩斿洖姝ょ敤鎴风殑鏉冮檺鑿滃崟
+// @Accept x-www-form-urlencoded
+// @Produce json
+// @Tags 鐢ㄦ埛
+// @Param userId formData string true "鐢ㄦ埛id"
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-u/users/findById [post]
+*/
+func (uc UserController) FindById(c *gin.Context) {
+	userId := c.PostForm("userId")
+	if userId == "" {
+		util.ResponseFormat(c,code.RequestParamError,"鍙傛暟鏈夎")
+		return
+	}
+	var api dbapi.UserApi
+	b, d := api.FindById(userId)
+	if b {
+		util.ResponseFormat(c,code.Success,d)
+	} else {
+		util.ResponseFormat(c,code.ComError,"")
+	}
+}
+
+/*
+// @Security ApiKeyAuth
+// @Summary 鏇存柊鐢ㄦ埛鍚嶏紝瀵嗙爜鍜岃彍鍗曟潈闄�
+// @Description 鏇存柊鐢ㄦ埛鍚嶏紝瀵嗙爜鍜岃彍鍗曟潈闄�
+// @Accept json
+// @Produce json
+// @Tags 鐢ㄦ埛
+// @Param userVo body controllers.UserEditVo true "鐢ㄦ埛鍙婃潈闄愪俊鎭�"
+// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
+// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
+// @Router /data/api-v/user/saveAuth [post]
+*/
+func (uc UserController) SaveAuth(c *gin.Context) {
+	var userEditVo UserEditVo
+	err := c.BindJSON(&userEditVo)
+	if err !=nil || userEditVo.Id =="" || userEditVo.UserName == "" {
+		util.ResponseFormat(c,code.RequestParamError,"")
+		return
+	}
+	paramBody := util.Struct2Map(userEditVo)
+	var api dbapi.UserApi
+	b, d := api.SaveAuth(paramBody)
+	if b {
+		auth.SetOutUser(userEditVo.Id)
+		util.ResponseFormat(c,code.UpdateSuccess,d)
+	} else {
+		util.ResponseFormat(c,code.UpdateFail,"淇濆瓨澶辫触")
+	}
 }
\ No newline at end of file
diff --git a/extend/code/code.go b/extend/code/code.go
index 93a4341..c985159 100644
--- a/extend/code/code.go
+++ b/extend/code/code.go
@@ -14,6 +14,7 @@
 	Success = &Code{http.StatusOK, true, "璇锋眰澶勭悊鎴愬姛"}
 	AddSuccess = &Code{http.StatusOK,true,"娣诲姞鎴愬姛"}
 	UpdateSuccess = &Code{http.StatusOK,true,"鏇存柊鎴愬姛"}
+	UpdateFail    = &Code{http.StatusBadRequest, false, "鏇存柊澶辫触"}
 	DelSuccess = &Code{http.StatusOK,true,"鍒犻櫎鎴愬姛"}
 	// RequestParamError 璇锋眰鍙傛暟閿欒
 	RequestParamError = &Code{http.StatusBadRequest, false, "璇锋眰鍙傛暟鏈夎"}
@@ -57,5 +58,9 @@
 	TaskStoped = &Code{http.StatusOK, false, "姝や换鍔′负鍋滅敤鐘舵�侊紝璇峰湪浠诲姟绠$悊涓紑鍚紒"}
 
 	ComError = &Code{http.StatusInternalServerError, false, ""}
-	ClusterNodesEmpty = &Code{http.StatusOK, true, "闆嗙兢鑺傜偣涓虹┖"}
+	ClusterNodesEmpty   = &Code{http.StatusOK, true, "闆嗙兢鑺傜偣涓虹┖"}
+	AddTaskErr          = &Code{http.StatusInternalServerError, false, "姝ゅ浗鏍囨憚鍍忔満宸插湪鍏跺畠鏈嶅姟鍣ㄩ厤缃换鍔★紒"}
+	CreateFirstNodeErr  = &Code{http.StatusInternalServerError, false, "鍒涘缓鑺傜偣澶辫触锛�"}
+	QueryClusterInfoErr = &Code{http.StatusInternalServerError, false, "鏌ヨ澶辫触锛岃纭鎮ㄧ殑ip鏄纭殑锛�"}
+	AddClusterInfoErr   = &Code{http.StatusInternalServerError, false, "鍔犲叆鑺傜偣澶辫触锛�"}
 )
diff --git a/extend/config/config.go b/extend/config/config.go
index 20e52bc..2ab67ab 100644
--- a/extend/config/config.go
+++ b/extend/config/config.go
@@ -6,46 +6,37 @@
 	"github.com/spf13/viper"
 )
 
+type threshold struct {
+	Value int    `mapstructure: "value"`
+	Color string `mapstructure: "color"`
+}
 type server struct {
-	Runmode   string `mapstructure: "runmode"`
-	JwtSecret string `mapstructure: "jwtSecret"`
-	JwtExpire string `mapstructure: "jwtExpire"`
-	Url       string `mapstructure: "url"`
-	ImageUrl  string `mapstructure: "imageUrl"`
-	PublicDomain string `mapstructure: "publicDomain"`
+	Runmode        string `mapstructure: "runmode"`
+	JwtSecret      string `mapstructure: "jwtSecret"`
+	JwtExpire      string `mapstructure: "jwtExpire"`
+	Url            string `mapstructure: "url"`
+	AnalyServerId  string `mapstructure: "analyServerId"`
 	NetworkAdapter string `mapstructure: "networkAdapter"`
+
+	DeviceNum       string `mapstructure: "deviceNum"`       //璁惧缂栧彿
+	DeviceType      string `mapstructure: "deviceType"`      //璁惧鍨嬪彿
+	DeviceSerialNum string `mapstructure: "deviceSerialNum"` //璁惧搴忓垪鍙�
+	MasterVersion   string `mapstructure: "masterVersion"`   //涓绘帶鐗堟湰
+	WebVersion      string `mapstructure: "webVersion"`      //web鐗堟湰
+	ChannelCount    string `mapstructure: "channelCount"`    //閫氶亾涓暟
+	DiskCount       string `mapstructure: "diskCount"`       //纭洏涓暟
+
+	SudoPassword  string      `mapstructure: "sudoPassword"` //绯荤粺瀵嗙爜
+	SysThresholds []threshold `mapstructure: "sysThresholds"`
+	PTZSpeed      int         `mapstructure: "ptzSpeed"` // 浜戝彴绉诲姩閫熷害
 }
 
 var Server = &server{}
 
-type weedfs struct {
-	Ip string `mapstructure: "ip"`
-	UploadPort int `mapstructure: "uploadport"`
-	VisitPort int `mapstructure: "visitport"`
-}
-
-var WeedFs = &weedfs{}
-
-type redis struct {
-	Host     string `mapstructure:"host"`
-	Port     int    `mapstructure:"port"`
-	Password string `mapstructure:"password`
-	DBNum    int    `mapstructure:"db"`
-}
-
-var RedisConf = &redis{}
-
-type database struct {
-	Drive    string `mapstructure:"drive"`
-	Name     string `mapstructure:"name"`
-	FilePath string `mapstructure:"filepath"`
-}
-
 // wp add es 绱㈠紩 浠ュ強 IP port
 type esinfo struct {
-	Masterip string      `mapstructure:"masterip"`
-	Httpport string      `mapstructure:"httpport"`
-	EsIndex  esindexlist `mapstructure:"index"`
+	Shards  string      `mapstructure:"shards"`
+	EsIndex esindexlist `mapstructure:"index"`
 }
 
 type esindexlist struct {
@@ -54,28 +45,40 @@
 	Dbtablepersons index `mapstructure:"dbtablepersons"`
 	Personaction   index `mapstructure:"personaction"`
 }
-
 type index struct {
 	IndexName string `mapstructure:"index"`
 	IndexType string `mapstructure:"type"`
 }
 
+type sopath struct {
+	Ip   string `mapstructure:"ip"`
+	Port string `mapstructure:"port"`
+}
+
+var SoPath = &sopath{}
+
 var EsInfo = &esinfo{}
 
-var DBconf = &database{}
+type facedetect struct {
+	Ip   string `mapstructure:"Ip"`
+	Port int    `mapstructure:"port"`
+}
 
 type dbpersoncompare struct {
-	Url string `mapstructure:"url"`
+	Ip   string `mapstructure:"ip"`
+	Port int    `mapstructure:"port"`
 }
 
 type espersoncompare struct {
-	Url []string `mapstructure:"url"`
+	Port int      `mapstructure:"port"`
+	Ips  []string `mapstructure:"ips"`
 }
 
 var DbPersonCompInfo = &dbpersoncompare{}
 
 var EsCompServerInfo = &espersoncompare{}
 
+var FaceDetectSet = &facedetect{}
 
 // Init is an exported method that takes the environment starts the viper
 // (external lib) and returns the configuration struct.
@@ -83,17 +86,15 @@
 	var err error
 	viper.SetConfigType("yaml")
 	viper.SetConfigName(env)
-	viper.AddConfigPath("../config/")
-	viper.AddConfigPath("config/")
+	viper.AddConfigPath("/opt/vasystem/config/")
 	err = viper.ReadInConfig()
 	if err != nil {
 		log.Fatal("error on parsing configuration file")
 	}
 	viper.UnmarshalKey("es", EsInfo)
 	viper.UnmarshalKey("server", Server)
-	viper.UnmarshalKey("redis", RedisConf)
-	viper.UnmarshalKey("database", DBconf)
-	viper.UnmarshalKey("weedfs", WeedFs)
-	viper.UnmarshalKey("dbpersoncompare",DbPersonCompInfo)
+	viper.UnmarshalKey("sopath", SoPath)
+	viper.UnmarshalKey("facedetect", FaceDetectSet)
+	viper.UnmarshalKey("dbpersoncompare", DbPersonCompInfo)
 	viper.UnmarshalKey("espersoncompare", EsCompServerInfo)
 }
diff --git a/extend/esutil/EsClient.go b/extend/esutil/EsClient.go
index bd8a28f..586911f 100644
--- a/extend/esutil/EsClient.go
+++ b/extend/esutil/EsClient.go
@@ -303,3 +303,17 @@
 	}
 	return sources, nil
 }
+
+func HttpGet(str string) ([]byte){
+	resp, err :=   http.Get(str)
+	if err != nil {
+		// handle error
+	}
+
+	defer resp.Body.Close()
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		// handle error
+	}
+	return body
+}
diff --git a/extend/sys/sysinfo.go b/extend/sys/sysinfo.go
index 96e89f9..208be3e 100644
--- a/extend/sys/sysinfo.go
+++ b/extend/sys/sysinfo.go
@@ -1 +1,59 @@
 package sys
+
+import (
+	"sort"
+	"time"
+	"webserver/extend/util"
+
+	"basic.com/valib/gogpu.git"
+
+	"github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/disk"
+	"github.com/shirou/gopsutil/mem"
+)
+
+type SummaryInfo struct {
+	Cpu  []float64             `json:"cpu" example:"cpu浣跨敤鐜�"`
+	Gpu  []gogpu.GpuUnitInfo   `json:"gpu" example:"gpu浣跨敤鐜�"`
+	Mem  mem.VirtualMemoryStat `json:"mem" example:"鍐呭瓨浣跨敤鐜�"`
+	Disk disk.UsageStat        `json:"disk" example:"纾佺洏绌洪棿"`
+}
+
+const Interval time.Duration = time.Second * 60
+
+var Stat = &SummaryInfo{}
+
+func GatherStat() {
+	for range time.Tick(Interval) {
+		// Cpu
+		if cpuUsedPercent, err := cpu.Percent(time.Second, true); err == nil {
+			Stat.Cpu = Stat.Cpu[0:0]
+			for _, v := range cpuUsedPercent {
+				Stat.Cpu = append(Stat.Cpu, v)
+			}
+		}
+
+		// Memory
+		if meminfo, err := mem.VirtualMemory(); err == nil {
+			Stat.Mem = *meminfo
+		}
+
+		// Disk
+		if disk, err := disk.Usage("/"); err == nil {
+			Stat.Disk = *disk
+		}
+
+		// Gpu
+		if gpuInfo, err := gogpu.Info(); err == nil {
+			sort.Sort(gogpu.GPURank(gpuInfo.Info))
+			Stat.Gpu = Stat.Gpu[0:0]
+			for _, v := range gpuInfo.Info {
+				Stat.Gpu = append(Stat.Gpu, v)
+			}
+		}
+	}
+}
+
+func GetSysInfo() map[string]interface{} {
+	return util.Struct2Map(Stat)
+}
diff --git a/extend/sys/system.go b/extend/sys/system.go
index 96e89f9..647917d 100644
--- a/extend/sys/system.go
+++ b/extend/sys/system.go
@@ -1 +1,236 @@
 package sys
+
+import (
+	"errors"
+	"os"
+	"os/exec"
+	"strconv"
+	"webserver/extend/config"
+	"webserver/extend/util"
+
+	"fmt"
+	"net"
+	"strings"
+	"time"
+)
+
+func execRootCommand(cmd string) ([]byte, error) {
+	pwd := config.Server.SudoPassword
+	cmdStr := fmt.Sprintf("echo %s | sudo -S %s", pwd, cmd)
+
+	return exec.Command("/bin/sh", "-c", cmdStr).Output()
+}
+
+// 妫�鏌� root鏉冮檺
+func CheckRootPermissions() bool {
+	showRootCMD := exec.Command("/bin/sh", "-c", "ls /root/")
+	if _, err := showRootCMD.Output(); err != nil {
+		return false
+	}
+
+	return true
+}
+
+// 鑾峰彇鏈満缃戝崱IP
+func GetLocalIP(networkName string) (ipv4 string, mask string, err error) {
+	interfaces, err := net.Interfaces()
+	if err != nil {
+		return "", "", err
+	}
+
+	for _, i := range interfaces {
+		byName, err := net.InterfaceByName(i.Name)
+		if err != nil {
+			return "", "", err
+		}
+		addresses, err := byName.Addrs()
+		for _, v := range addresses {
+			if ipnet, ok := v.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
+				if ipnet.IP.To4() != nil {
+					if byName.Name == networkName {
+						maskStr := ipnet.Mask.String()
+						mask64, _ := strconv.ParseUint(maskStr, 16, 32)
+						return ipnet.IP.String(), util.IpIntToString(int(mask64)), nil
+					}
+				}
+			}
+		}
+	}
+	return "", "", errors.New("ipv4 not found")
+}
+
+// 鑾峰彇鏈満缃戝叧ip
+func GetDefaultRoute(networkName string) (route string, err error) {
+	cmdStr := fmt.Sprintf("ip route show | grep -P \"^default.*%s\" | awk '{printf $3}'", networkName)
+	cmd := exec.Command("/bin/sh", "-c", cmdStr)
+	b, err := cmd.Output()
+	if err != nil {
+		return "", err
+	}
+
+	return string(b), nil
+}
+
+func GetDnsServer() (dns string, err error) {
+	cmd := exec.Command("/bin/sh", "-c", "cat /etc/resolv.conf | grep nameserver | head -1 |awk '{printf $2}'")
+	b, err := cmd.Output()
+	if err != nil {
+		return "", err
+	}
+
+	return string(b), nil
+}
+
+// 閰嶇疆鏈嶅姟鍣ㄧ綉缁�
+func SetNetworkConfig(ipv4, netmask, gateway, dns string) (bool, string) {
+	networkConfigScript := "/opt/vasystem/bin/netconfig"
+	ifname := config.Server.NetworkAdapter
+	localIPv4, localNetMask, _ := GetLocalIP(ifname)
+	localGW, _ := GetDefaultRoute(ifname)
+	localDNS, _ := GetDnsServer()
+
+	if localIPv4 == ipv4 && localNetMask == netmask && localGW == gateway && localDNS == dns {
+		return true, ""
+	}
+
+	// 妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�
+	if _, err := os.Stat(networkConfigScript); err != nil {
+		return false, "network Config Script not exist"
+	}
+	// # netconfig enp59s0f0 192.168.1.2 255.255.255.0 192.168.1.1 192.168.100.1
+	cmdStr := fmt.Sprintf("%s %s %s %s %s %s", networkConfigScript, ifname, ipv4, netmask, gateway, dns)
+	stdout, err := execRootCommand(cmdStr)
+
+	return err == nil, string(stdout)
+}
+
+// 閰嶇疆鏃跺尯
+func TimeZone() (string, int64) {
+	cmd := exec.Command("/bin/sh", "-c", "echo -n $TZ")
+	tz, _ := cmd.Output()
+	if tzstr := string(tz); tzstr != "" {
+		return tzstr, time.Now().Unix()
+	}
+
+	zone, _ := time.Now().Zone()
+	return zone, time.Now().Unix()
+}
+
+func NTPConfig() (bool, string, string) {
+	status, server, interval := false, "", ""
+
+	cron, _ := execRootCommand("crontab -l | grep ntpdate | tr -d '\n'")
+	if task := string(cron); task != "" {
+		status = true
+		slice := strings.Split(task, " ")
+		interval, server = slice[0][2:], slice[len(slice)-1]
+	}
+
+	return status, server, interval
+}
+
+// 璁剧疆鏃跺尯
+func SetTimeZone(tz string) bool {
+	if _, err := time.LoadLocation(tz); err != nil {
+		return false
+	}
+
+	// set env
+	envCMD := exec.Command("/bin/sh", "-c", "TZ=%s", tz)
+	envCMD.Run()
+	// change permanent to the file '.profile'
+
+	cleanTZ := exec.Command("/bin/sh", "-c", "sed -i '/^TZ=.*$/d' ~/.profile")
+	cleanTZ.Run()
+
+	TZ := "TZ='" + tz + "'; export TZ"
+	appendTZCMD := fmt.Sprintf("echo \"%s\" >> ~/.profile;", TZ)
+	appendTZ := exec.Command("/bin/sh", "-c", appendTZCMD)
+	appendTZ.Run()
+
+	return true
+}
+
+// 閰嶇疆绯荤粺鏃堕棿
+func SetLocalTime(newTime string) bool {
+	const TimeLayout = "2006-01-02 15:04:05"
+	_, err := time.Parse(TimeLayout, newTime)
+	if err != nil {
+		return false
+	}
+
+	dateCMD := fmt.Sprintf("date -s \"%s\"", newTime)
+	execRootCommand(dateCMD)
+	stopNTPCron()
+
+	return true
+}
+
+const NTPCRONTABFILE = "/tmp/.webServer.crontab"
+
+func EnableNTPCron(server string, interval int) bool {
+	stopNTPCron()
+
+	if ip := net.ParseIP(server); ip == nil {
+		return false
+	}
+
+	update := fmt.Sprintf("echo \"*/%d * * * * /usr/sbin/ntpdate %s\" >> %s", interval, server, NTPCRONTABFILE)
+	execRootCommand(update)
+
+	addNTPTask := fmt.Sprintf("crontab %s", NTPCRONTABFILE)
+	execRootCommand(addNTPTask)
+
+	return true
+}
+
+func stopNTPCron() {
+	update := fmt.Sprintf("crontab -l | grep -v /usr/sbin/ntpdate > %s", NTPCRONTABFILE)
+	execRootCommand(update)
+
+	cleanNTPTask := fmt.Sprintf("crontab %s", NTPCRONTABFILE)
+	execRootCommand(cleanNTPTask)
+}
+
+func RunNTPDate(server string) bool {
+	if ip := net.ParseIP(server); ip == nil {
+		return false
+	}
+
+	ntpdate := fmt.Sprintf("/usr/sbin/ntpdate %s", server)
+	_, err := execRootCommand(ntpdate)
+
+	return err == nil
+}
+
+func Reboot() (bool, string) {
+	stdout, err := execRootCommand("reboot")
+
+	return err == nil, string(stdout)
+}
+
+// * * * * * /bin/echo "$(date) Perform basic-reboot-task" >> /tmp/webserver.crontab.log;/sbin/reboot & >> /tmp/webserver.crontab.log
+func ReadRebootTaskInCrontab() (bool, string) {
+	stdout, err := execRootCommand("crontab -l | grep basic-reboot-task | sed -z -r 's/([^0-9* ]+)(.+)//g'")
+	return err == nil, string(stdout)
+}
+
+func CleanRebootTask() {
+	update := fmt.Sprintf("crontab -l | grep -v basic-reboot-task > %s", NTPCRONTABFILE)
+	execRootCommand(update)
+
+	crontab := fmt.Sprintf("crontab %s", NTPCRONTABFILE)
+	execRootCommand(crontab)
+}
+
+func UpdateRebootTask(task string) bool {
+	CleanRebootTask()
+
+	tasks := fmt.Sprintf("%s /bin/echo \"$(date) Perform basic-reboot-task\" >> /tmp/webserver.crontab.log;/sbin/reboot & >> /tmp/webserver.crontab.log", task)
+	update := fmt.Sprintf("echo '%s' >> %s", tasks, NTPCRONTABFILE)
+	execRootCommand(update)
+	addNTPTask := fmt.Sprintf("crontab %s", NTPCRONTABFILE)
+	_, err := execRootCommand(addNTPTask)
+
+	return err == nil
+}
diff --git a/main.go b/main.go
index a86ba4c..528706c 100644
--- a/main.go
+++ b/main.go
@@ -1,57 +1,69 @@
 package main
 
 import (
-	"basic.com/dbapi.git"
 	"flag"
-	"github.com/golang/glog"
-	"github.com/robfig/cron"
 	"strconv"
+	"webserver/cache"
 	"webserver/extend/config"
-	"webserver/extend/logger"
+	"webserver/extend/sys"
 	"webserver/router"
-	"webserver/service"
+
+	"basic.com/dbapi.git"
+	"basic.com/valib/logger.git"
+	"github.com/spf13/viper"
 )
 
-var envirment = flag.String("e", "dev", "")
+var envirment = flag.String("e", "pro", "")
 var dbIp = flag.String("dbIp", "127.0.0.1", "default dbIp=127.0.0.1")
 var dbPort = flag.String("dbPort", "8001", "default dbPort=8001")
+var surveyPort = flag.Int("surveyPort", 40007, "survey port") //蹇冭烦
+var pubPort = flag.Int("pubPort", 50007, "pubsub port")       //鏁版嵁鏇存柊
+var initchan = make(chan bool)
 
 func init() {
-	var logFile = "./logger/webserver.log"
-	var logSaveDays = 15
-
-	// 鏃ュ織鍒濆鍖�
-	logger.Config(logFile, logger.DebugLevel)
-	logger.SetSaveDays(logSaveDays)
-	logger.Info("loginit success !")
 	flag.Parse()
-	service.InitService()
 
 	p, err := strconv.Atoi(*dbPort)
 	if err != nil {
 		p = 8001
 	}
-	//*dbIp = "192.168.1.123"
-	//*dbIp = "192.168.1.182"
 	dbapi.Init(*dbIp, p)
-
-	flag.Usage = func() {
-		glog.Exit("flag parse usage !")
-	}
-
-	flag.Lookup("alsologtostderr").Value.Set("true")
-	flag.Lookup("log_dir").Value.Set("./log")
 	config.Init(*envirment)
+
+	var logFile = "./logger/"
+	if viper.GetString("LogBasePath") != "" {
+		logFile = viper.GetString("LogBasePath")
+	}
+	logFile = logFile + "/webserver.log"
+	var logSaveDays = 15
+
+	// 鏃ュ織鍒濆鍖�
+	if viper.IsSet("LogLevel") &&
+		viper.GetInt("LogLevel") >= logger.PanicLevel &&
+		viper.GetInt("LogLevel") <= logger.DebugLevel {
+		logger.Config(logFile, viper.GetInt("LogLevel"))
+	} else {
+		logger.Config(logFile, logger.DebugLevel)
+	}
+	logger.SetSaveDays(logSaveDays)
+	logger.Info("loginit success !")
 }
+
+// @title Swagger API
+// @version 2.0
+// @description analysis webserver
+// @securityDefinitions.apikey ApiKeyAuth
+// @in header
+// @name Authorization
+// @BasePath /
 func main() {
-	c := cron.New()
-	c.AddFunc("@ daily", func() {
-		res := service.InitEnableStatus()
-		logger.Debug(res)
-	})
-	c.Start()
+	flag.Parse()
+	go cache.Init(initchan, *dbIp, *surveyPort, *pubPort)
+	logger.Debug("heartBeat with db done!", <-initchan)
+
+	// 缁熻绯荤粺杩愯鐘舵��
+	go sys.GatherStat()
+
 	r := router.NewRouter()
 	r.Run("0.0.0.0:7100")
-
-	//defer new(gorun.SimpleFaceDetect).FaceDetactClose()
 }
diff --git a/middlewares/auth/auth.go b/middlewares/auth/auth.go
index 8a23438..d897b00 100644
--- a/middlewares/auth/auth.go
+++ b/middlewares/auth/auth.go
@@ -4,8 +4,9 @@
 	"github.com/gin-gonic/gin"
 	"net/http"
 	"strings"
-	"webserver/extend/config"
-	"webserver/extend/logger"
+	"sync"
+	"webserver/extend/code"
+	"webserver/extend/util"
 )
 
 const (
@@ -14,7 +15,7 @@
 
 type Auth interface {
 	Check(c *gin.Context)bool
-	User(c *gin.Context)interface{}
+	User(c *gin.Context)map[string]interface{}
 	Login(http *http.Request,w http.ResponseWriter,user map[string]interface{})interface{}
 	Logout(http *http.Request,w http.ResponseWriter) bool
 }
@@ -25,40 +26,54 @@
 	return &authDriver
 }
 
+var outUserM = make(map[string]string,0)
+var lock sync.RWMutex
+
+func SetOutUser(userId string) {
+	lock.Lock()
+	defer lock.Unlock()
+	outUserM[userId] = userId
+}
+
+func OutUser(userId string) bool {
+	lock.Lock()
+	defer lock.Unlock()
+	if _,ok := outUserM[userId];ok{
+		return true
+	}
+	return false
+}
+
+func RemoveOutUser(userId string) {
+	lock.Lock()
+	defer lock.Unlock()
+	if _,ok := outUserM[userId];ok{
+		delete(outUserM,userId)
+	}
+}
+
 func AuthHandler() gin.HandlerFunc {
 	return func(c *gin.Context) {
 		urlPath := c.Request.URL.Path
 
-		if strings.Contains(urlPath,"/data/api-v") && !strings.Contains(urlPath,"login"){
-			//jwtDriver :=NewJwtAuthDriver()
-			//if !jwtDriver.Check(c) {
-			//	util.ResponseFormat(c,code.TokenNotFound,"灏氭湭鐧诲綍锛岃鐧诲綍")
-			//	c.Abort()
-			//}
+		if strings.Contains(urlPath,"/data/api-") && !strings.Contains(urlPath,"login"){
+			jwtDriver :=NewJwtAuthDriver()
+			if !jwtDriver.Check(c) {
+				util.ResponseFormat(c,code.TokenNotFound,"灏氭湭鐧诲綍锛岃鐧诲綍")
+				c.Abort()
+			}
+			userM := (*jwtDriver).User(c)
+			if userM == nil {
+				util.ResponseFormat(c,code.TokenNotFound,"灏氭湭鐧诲綍锛岃鐧诲綍")
+				c.Abort()
+				return
+			}
+			userId := userM["id"].(string)
+			if OutUser(userId) {
+				util.ResponseFormat(c,code.TokenNotFound,"灏氭湭鐧诲綍锛岃鐧诲綍")
+				c.Abort()
+			}
 			c.Next()
-		} else if strings.Contains(urlPath,"/httpImage") {
-			domain := config.Server.PublicDomain
-			//domainReg := regexp.MustCompile(``+domain+``)
-			//if domainReg.MatchString(host) {//鍩熷悕璁块棶
-			//   imgUrl = domain
-			//}
-
-			urlPath = strings.Replace(urlPath, "/httpImage", "", -1)
-			if strings.Contains(urlPath,domain) {
-				urlPath = strings.Replace(urlPath,"/"+domain,"",-1)
-			}
-			logger.Debug("urlPath:",urlPath)
-			idx := strings.LastIndex(urlPath, ":")
-			tmpPath := ""
-			if idx >-1 {//璺緞涓寘鍚湁绔彛,鍙栫鍙d互鍚庤矾寰�
-				tmpPath = urlPath[idx:]
-			} else {
-				tmpPath = ":6080"+tmpPath
-			}
-			c.Header("Access-Control-Allow-Origin","*")
-			logger.Debug("domain+tmpPath:",domain+tmpPath)
-			c.Redirect(http.StatusMovedPermanently, domain+tmpPath)
-			return
 		} else {
 			c.Next()
 		}
@@ -66,5 +81,5 @@
 }
 
 func GetCurUser(c *gin.Context)map[string]interface{}{
-	return (*GenerateAuthDriver()).User(c).(map[string]interface{})
+	return (*GenerateAuthDriver()).User(c)
 }
\ No newline at end of file
diff --git a/middlewares/auth/jwt.go b/middlewares/auth/jwt.go
index 0187b2f..37b4fc3 100644
--- a/middlewares/auth/jwt.go
+++ b/middlewares/auth/jwt.go
@@ -50,12 +50,12 @@
 	return authJwtToken.Valid
 }
 
-func (jwtAuth *jwtAuthManager) User(c *gin.Context) interface{} {
+func (jwtAuth *jwtAuthManager) User(c *gin.Context) map[string]interface{} {
 	var jwtToken *jwtLib.Token
 	if jwtUser, exist := c.Get("User"); !exist {
 		tokenStr := strings.Replace(c.Request.Header.Get("Authorization"), "Bearer ", "", -1)
 		if tokenStr == "" {
-			return map[interface{}]interface{}{}
+			return nil
 		}
 		var err error
 		jwtToken, err = jwtLib.Parse(tokenStr, func(token *jwtLib.Token) (interface{}, error) {
diff --git a/models/dbtablepersons.go b/models/dbtablepersons.go
index d8473c6..6f06246 100644
--- a/models/dbtablepersons.go
+++ b/models/dbtablepersons.go
@@ -12,4 +12,10 @@
 	PhoneNum     string `json:"phoneNum,omitempty" example:"鎵嬫満鍙风爜"`
 	MonitorLevel string `json:"monitorLevel,omitempty" example:"绛夌骇"`
 	PicDesc      string `json:"picDesc,omitempty" example:"鐓х墖鏍囪瘑"`
+	Reserved	 string `json:"reserved,omitempty" example:"鍏朵粬"`
 }
+
+type DbPersonsCompVo struct {
+	Dbtablepersons
+	CompareScore float32 `json:"compareScore"`
+}
\ No newline at end of file
diff --git a/models/esSearch.go b/models/esSearch.go
index b90d70b..9fd6d22 100644
--- a/models/esSearch.go
+++ b/models/esSearch.go
@@ -14,7 +14,9 @@
 	IsAggs     bool     `json:"isAggs"`//
 	InputValue string   `json:"inputValue"`//杈撳叆妗�
 	Collection string   `json:"collection"`//
-	AlarmLevel []string `json:"alarmLevel"`//甯冮槻绛夌骇
+	AlarmLevel []int32  `json:"alarmLevel"`//甯冮槻绛夌骇
 	CompareNum string   `json:"compareNum"`//姣斿缂栧彿
-	CaptureId string    `json:"captureId"`//鎶撴媿id
+
+	CompTargetId string `json:"compTargetId"`//鏌ユ壘姝や汉id锛堟棦鍙兘鏌ユ壘鎶撴媿浜猴紝涔熷彲鑳芥煡鎵惧簳搴撲汉锛�
+	CompTargetType int 	`json:"compTargetType"`//鏌ユ壘姝や汉鐨勭被鍨嬶紝0:搴曞簱锛�1:鎶撴媿
 }
diff --git a/router/router.go b/router/router.go
index 2f08d50..71be55e 100644
--- a/router/router.go
+++ b/router/router.go
@@ -1,13 +1,14 @@
 package router
 
 import (
-	"github.com/gin-gonic/gin"
-	"github.com/swaggo/gin-swagger"
-	"github.com/swaggo/gin-swagger/swaggerFiles"
-	"github.com/szuecs/gin-glog"
 	"time"
 	"webserver/controllers"
 	"webserver/middlewares/auth"
+
+	"github.com/gin-gonic/gin"
+	ginSwagger "github.com/swaggo/gin-swagger"
+	"github.com/swaggo/gin-swagger/swaggerFiles"
+	ginglog "github.com/szuecs/gin-glog"
 
 	_ "webserver/docs"
 )
@@ -16,7 +17,7 @@
 	r := gin.Default()
 	r.Use(ginglog.Logger(3 * time.Second))
 
-	r.Use(auth.AuthHandler())//auth杩囨护鍣�
+	r.Use(auth.AuthHandler()) //auth杩囨护鍣�
 
 	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
 
@@ -28,6 +29,7 @@
 	ssController := new(controllers.SysSetController)
 	sdkController := new(controllers.SdkController)
 	esSearchController := new(controllers.EsSearchController)
+	esManagementController := new(controllers.EsManagementController)
 	realTimeController := new(controllers.RealTimeController)
 	cameraTimeRuleController := new(controllers.CameraTimeruleController)
 	polygonController := new(controllers.CameraPolygonController)
@@ -38,23 +40,32 @@
 	eventPushController := new(controllers.EventPushController)
 	pollConfigController := new(controllers.PollConfigController)
 	fileController := new(controllers.FileController)
-	sysMenuController :=new(controllers.SysMenuController)
-	clusterController :=new(controllers.ClusterController)
+	sysMenuController := new(controllers.SysMenuController)
+	clusterController := new(controllers.ClusterController)
+	sysRoleController := new(controllers.RoleController)
+	ptzController := new(controllers.PanTiltZoomController)
 
-
-	sysApi := r.Group(  "/data/api-u/sys")
+	sysApi := r.Group("/data/api-u/sys")
 	{
-		sysApi.POST("/login",userController.Login)
-		sysApi.GET("/logout",userController.Logout)
-		sysApi.POST("refresh_token",userController.RefreshToken)
+		sysApi.POST("/login", userController.Login)
+		sysApi.GET("/logout", userController.Logout)
+		sysApi.POST("refresh_token", userController.RefreshToken)
 	}
 	sysMenuApi := r.Group("/data/api-u/sysmenus")
 	{
-		sysMenuApi.GET("/me",sysMenuController.Me)
+		sysMenuApi.GET("/me", sysMenuController.Me)
+		sysMenuApi.GET("/tree", sysMenuController.MenuTree)
+	}
+	roleApi := r.Group("/data/api-v/role")
+	{
+		roleApi.GET("/findAll", sysRoleController.FindAll)
 	}
 	userApi := r.Group("/data/api-u/users")
 	{
-		userApi.GET("/current",userController.Current)
+		userApi.GET("/current", userController.Current)
+		userApi.GET("/findAllUser", userController.FindAllUser)
+		userApi.POST("/findById", userController.FindById)
+		userApi.POST("/saveAuth", userController.SaveAuth)
 	}
 
 	urlPrefix := "/data/api-v" // wp 娣诲姞 璺緞 鍓嶇紑
@@ -63,10 +74,12 @@
 	area := r.Group(urlPrefix + "/area")
 	{
 		area.GET("/localmenu", areaController.CameraTree)
-		area.GET("/gb28181Tree",areaController.CameraGb28181Tree)
+		area.GET("/gb28181Tree", areaController.CameraGb28181Tree)
 		area.POST("/add", areaController.AreaAdd)
 		area.POST("/del", areaController.AreaDelete)
 		area.POST("/update", areaController.AreaUpdate)
+		area.POST("/gb28181TreeRefresh", areaController.Gb28181TreeRefresh)
+		area.POST("/gb28181TreeDelete", areaController.Gb28181TreeDelete)
 	}
 
 	//鎽勫儚鏈虹鐞�
@@ -76,7 +89,7 @@
 		camera.PUT("/update", cameraController.CameraUpdate)
 		camera.DELETE("/del/:cid", cameraController.CameraDel)
 		camera.GET("/show/:cid", cameraController.CameraSel)
-		camera.GET("/updateSnapshotUrl/:cid",cameraController.UpdateSnapshotUrl)
+		camera.GET("/updateSnapshotUrl/:cid", cameraController.UpdateSnapshotUrl)
 
 		camera.POST("/alltask", cameraTaskController.FindTasksByCameraIds)
 		camera.GET("/task/:cameraId", cameraTaskController.CameraTaskAll)
@@ -87,6 +100,10 @@
 		camera.GET("/getCamerasByRunType", cameraController.GetCamerasByRunType)
 		camera.POST("/updateRunEnable", cameraController.UpdateRunEnable)
 		camera.POST("/changeRunType", cameraController.ChangeRunType)
+		camera.GET("/getAllCamerasByServer", cameraController.GetAllCamerasByServer)
+
+		camera.POST("/ptzControl", ptzController.Move)
+		camera.GET("/statisticRunInfo", cameraController.StatisticRunInfo)
 	}
 
 	cameraTaskArgsApi := r.Group(urlPrefix + "/cameraTaskArgs")
@@ -94,7 +111,7 @@
 		cameraTaskArgsApi.GET("/deleteByGroup", cameraTaskArgsController.DeleteByGroup)
 		cameraTaskArgsApi.POST("/getLinkRulesByCameraIds", cameraTaskArgsController.GetLinkRulesByCameraIds)
 		cameraTaskArgsApi.POST("/saveLinkRulesByGroup", cameraTaskArgsController.SaveLinkRulesByGroup)
-		cameraTaskArgsApi.POST("/updateDefenceStateByGroup",cameraTaskArgsController.UpdateDefenceStateByGroup)
+		cameraTaskArgsApi.POST("/updateDefenceStateByGroup", cameraTaskArgsController.UpdateDefenceStateByGroup)
 	}
 
 	cameraTaskApi := r.Group(urlPrefix + "/cameraTask")
@@ -102,6 +119,7 @@
 		cameraTaskApi.POST("/saveIsDataTrans", cameraTaskController.SaveIsDataTrans)
 		cameraTaskApi.POST("/saveAlarmLevelByGroup", cameraTaskController.SaveAlarmLevelByGroup)
 		cameraTaskApi.POST("/updateCameraTaskStatus", cameraTaskController.UpdateCameraTaskStatus)
+		cameraTaskApi.POST("/addTask", cameraTaskController.AddTask)
 	}
 
 	polygon := r.Group(urlPrefix + "/polygon")
@@ -117,6 +135,7 @@
 	task := r.Group(urlPrefix + "/task")
 	{
 		task.GET("/findAll", taskController.FindAll)
+		task.GET("/aggregateTaskList", taskController.AggregateTaskList)
 		task.POST("/addTask", taskController.AddTask)
 		task.POST("/updateTaskStatus", taskController.UpdateTaskStatus)
 		task.GET("/delete", taskController.DeleteTask)
@@ -126,15 +145,21 @@
 		task.GET("/getRulesByTaskSdk", taskController.GetRulesByTaskSdk)
 		task.POST("/deleteTaskSdkRule", taskController.DeleteTaskSdkRule)
 		task.POST("/saveTaskSdkRule", taskController.SaveTaskSdkRule)
+
+		task.GET("/statisticTaskCamera", taskController.StatisticTaskCamera)
 	}
 
-	// 妫�绱� 鏌ヨ
+	// 妫�绱� 鏌ヨ 鑺傜偣鎿嶄綔
 	es := r.Group(urlPrefix + "/es")
 	{
 		es.POST("/tagList", esSearchController.PostEsTagList)
 		es.POST("/taskList", esSearchController.PostEsTaskList)
 		es.POST("/esSearch", esSearchController.PostEsSearch)
 		es.POST("/queryEsCompareData", controllers.PostEsCompareData)
+		es.POST("/getEsClusterInfo", esManagementController.GetEsClusterInfo)
+		es.POST("/addCluster", esManagementController.AddCluster)
+		es.POST("/createNode", esManagementController.CreateNode)
+		es.POST("/updateEsHosts", esManagementController.UpdateEsHosts)
 	}
 
 	//瀹炴椂琚皟鏁版嵁
@@ -152,21 +177,28 @@
 		vdbtable.POST("/updateDbTables", tableController.UpdateDbTables)
 		vdbtable.POST("/deleteDBtablesById/:id", tableController.DeleteDbTables)
 		vdbtable.PUT("/addDbTableInfo", tableController.AddDbTableInfo)
+		vdbtable.POST("/updateDbTableStatus", tableController.UpdateDbTableStatus)
+		vdbtable.GET("/findAllDbTablesByCurServer", tableController.FindAllDbTablesByCurServer)
 	}
 
 	// 搴曞簱浜哄憳 鎿嶄綔
 	vdbperson := r.Group(urlPrefix + "/dbperson")
 	{
 		vdbperson.POST("/queryDbPersonsByTbId", dbPersonCont.QueryDbPersonsByTbId)
-		//vdbperson.POST("/queryDbPersonsByCampare", dbPersonCont.QueryDbPersonsByCampare)
+		vdbperson.POST("/queryDbPersonsByCompare", dbPersonCont.QueryDbPersonsByCompare)
 		vdbperson.POST("/updateDbPerson", dbPersonCont.UpdateDbPerson)
 		vdbperson.POST("/deleteDbPersonById/:uuid", dbPersonCont.DeleteDbPerson)
 		vdbperson.POST("/deleteMoreDbPerson", dbPersonCont.DeleteMoreDbPerson)
 		vdbperson.PUT("/addDbPerson", dbPersonCont.AddDbPerson)
 
 		vdbperson.POST("/fileUploadTest", fileController.UploadPersonTest)
-		vdbperson.POST("/faceExtract",fileController.FaceExtract)
-		vdbperson.POST("/searchByPhoto",fileController.SearchByPhoto)
+		vdbperson.POST("/faceExtract", fileController.FaceExtract)
+		vdbperson.POST("/searchByPhoto", fileController.SearchByPhoto)
+		vdbperson.POST("/updateFace", dbPersonCont.UpdateFace)
+
+		vdbperson.POST("/joinDbTable", dbPersonCont.JoinDbTable)
+		vdbperson.POST("/move", dbPersonCont.Move)
+		vdbperson.POST("/copy", dbPersonCont.Copy)
 	}
 
 	// 绯荤粺璁剧疆 鎿嶄綔
@@ -180,6 +212,15 @@
 		vsset.POST("/saveDevInfo", ssController.SaveDevInfo)
 		vsset.GET("/gb28181ConfigShow", ssController.Gb28181ConfigShow)
 		vsset.POST("/gb28181ConfigEdit", ssController.Gb28181ConfigEdit)
+		vsset.GET("/clockInfo", ssController.GetClockinfo)
+		vsset.POST("/updateClock", ssController.SetSysClock)
+		vsset.GET("/ntpTest", ssController.TestNTPServer)
+		vsset.GET("/sysinfo", ssController.GetSysInfo)
+		vsset.GET("/sysThresholds", ssController.GetSysThresholds)
+
+		vsset.GET("/reboot", ssController.RebootOS)
+		vsset.GET("/rebootTask", ssController.GetRebootTask)
+		vsset.POST("/rebootTask", ssController.SetRebootTask)
 	}
 
 	//绠楁硶搴撴搷浣�
@@ -189,10 +230,11 @@
 		sdkApi.GET("/findAllSdk", sdkController.FindAllSdk)
 		sdkApi.GET("/findByTaskId", sdkController.FindByTaskId)
 		sdkApi.GET("/getById", sdkController.GetById)
+		sdkApi.GET("/sdkDownload", sdkController.SdkDownLoad)
 	}
 
 	//绠楁硶鍙傛暟
-	sdkArgApi :=r.Group(urlPrefix + "/sdkArg")
+	sdkArgApi := r.Group(urlPrefix + "/sdkArg")
 	{
 		sdkArgApi.GET("/getSdkArgs", sdkController.GetSdkArgs)
 	}
@@ -224,14 +266,17 @@
 		pollCApi.GET("/getPollConfig", pollConfigController.GetPollConfig)
 		pollCApi.POST("/updateEnable", pollConfigController.UpdateEnable)
 	}
-	clusterApi := r.Group(urlPrefix+"/cluster")
+	clusterApi := r.Group(urlPrefix + "/cluster")
 	{
+		clusterApi.GET("/findCluster", clusterController.FindCluster)
 		clusterApi.GET("/randomPwd", clusterController.RandomPwd)
 		clusterApi.POST("/create", clusterController.Create)
 		clusterApi.POST("/search", clusterController.Search)
 		clusterApi.POST("/stopSearching", clusterController.StopSearching)
 		clusterApi.GET("/getSearchNodes", clusterController.GetSearchNodes)
 		clusterApi.POST("/joinCluster", clusterController.JoinCluster)
+		clusterApi.POST("/updateClusterName", clusterController.UpdateClusterName)
+		clusterApi.POST("/leave", clusterController.Leave)
 	}
 
 	// 鏂囦欢 涓婁紶
diff --git a/service/FDetectClient.go b/service/FDetectClient.go
index 6d43c33..b020870 100644
--- a/service/FDetectClient.go
+++ b/service/FDetectClient.go
@@ -1 +1,35 @@
 package service
+
+import (
+	"basic.com/pubsub/protomsg.git"
+	"context"
+	"errors"
+	"strconv"
+	"time"
+	"webserver/extend/config"
+	"basic.com/valib/logger.git"
+
+	"google.golang.org/grpc"
+)
+
+func DoFDetectWithRpc(fdr *protomsg.FaceDetectRequest,t time.Duration) ([]*protomsg.ResultFaceDetect,error) {
+	fdUrl:=config.FaceDetectSet.Ip + ":" + strconv.Itoa(config.FaceDetectSet.Port)
+	conn,err := grpc.Dial(fdUrl, grpc.WithInsecure())
+	if err !=nil {
+		logger.Debug("grpc dial err:",err)
+	}
+	defer conn.Close()
+	c := protomsg.NewFaceDetectClient(conn)
+
+	ctx,cancel := context.WithTimeout(context.Background(), t)
+	defer cancel()
+	faces,err := c.FaceDetect(ctx,fdr)
+	if err !=nil {
+		logger.Debug("rpc call err:",err)
+		return nil,err
+	}
+	if faces !=nil {
+		return faces.Faces,nil
+	}
+	return nil,errors.New("no face detected")
+}
diff --git a/service/FaceCompareService.go b/service/FaceCompareService.go
index 04d5040..24aabde 100644
--- a/service/FaceCompareService.go
+++ b/service/FaceCompareService.go
@@ -8,9 +8,10 @@
 	"nanomsg.org/go-mangos/protocol/req"
 	"nanomsg.org/go-mangos/transport/ipc"
 	"nanomsg.org/go-mangos/transport/tcp"
+	"strconv"
 	"sync"
 	"webserver/extend/config"
-	"webserver/extend/logger"
+	"basic.com/valib/logger.git"
 )
 
 type FaceCompareService struct {
@@ -66,13 +67,13 @@
 func (sv *FaceCompareService) CompareVideoPersons() *CompareList{
 	sv.CompareArgs.TableIds = []string { CaptureTable }
 	b, err := proto.Marshal(&sv.CompareArgs)
-	esCompServerList := config.EsCompServerInfo.Url
+	esCompServerList := config.EsCompServerInfo.Ips
 	logger.Debug("compServerList:", esCompServerList)
 	//1.鍚戝悇涓狤s compare杩涚▼鍙戣捣璇锋眰鎷垮埌姣斿缁撴灉
 	var resultList CompareList
 
 	for _,str :=range esCompServerList{
-		reqUrl := "tcp://"+str
+		reqUrl := "tcp://"+str + ":"+strconv.Itoa(config.EsCompServerInfo.Port)
 		resultB := doCompareRequest(reqUrl,b)
 		if resultB == nil || len(*resultB) ==0 {
 			continue
@@ -98,12 +99,12 @@
 //姣斿搴曞簱
 func (sv *FaceCompareService) CompareDbPersons() *CompareList{
 	b, err := proto.Marshal(&sv.CompareArgs)
-	dbPersonCompServerUrl := config.DbPersonCompInfo.Url
+	dbPersonCompServerUrl := config.DbPersonCompInfo.Ip
 	logger.Debug("comp Server url:", dbPersonCompServerUrl)
 
 	var resultList CompareList
 
-	reqUrl := "tcp://"+dbPersonCompServerUrl
+	reqUrl := "tcp://"+dbPersonCompServerUrl+":"+strconv.Itoa(config.DbPersonCompInfo.Port)
 	resultB := doCompareRequest(reqUrl,b)
 	if resultB == nil || len(*resultB) ==0 {
 		return nil
diff --git a/service/FaceSdkService.go b/service/FaceSdkService.go
index ca7f185..366ab3d 100644
--- a/service/FaceSdkService.go
+++ b/service/FaceSdkService.go
@@ -2,17 +2,11 @@
 
 import (
 	"basic.com/pubsub/protomsg.git"
-	"basic.com/valib/deliver.git"
+	"basic.com/valib/logger.git"
 	"github.com/gogo/protobuf/proto"
-	"github.com/pierrec/lz4"
 	"github.com/pkg/errors"
-	"github.com/satori/go.uuid"
 	"gocv.io/x/gocv"
-	"image"
-	"sync"
 	"time"
-	"webserver/extend/logger"
-	"webserver/extend/util"
 )
 
 type FaceSdkService struct {
@@ -23,92 +17,62 @@
 }
 
 const (
-	Ipc_Push_Ext       = "_2.ipc"
-	Ipc_Pull_Ext       = "_1.ipc"
-	Ipc_Url_Pre        = "ipc:///tmp///"
 	faceExtractWebCID = "virtual-face-extract-web-camera-id"
-	Virtual_FaceTaskId = "92496BDF-2BFA-98F2-62E8-96DD9866ABD2"
-	Virtual_FaceSdkId  = "virtual-faceextract-sdk-pull"
-	Url_Service_PUSH   = Ipc_Url_Pre + Virtual_FaceSdkId + Ipc_Push_Ext
-	Url_Service_PULL   = Ipc_Url_Pre + Virtual_FaceSdkId + Ipc_Pull_Ext
 )
 
 func GetFaceFeaFromSdk(fileBytes []byte,deadTime time.Duration) ([]*protomsg.ResultFaceDetect,error,*protomsg.Image){
 	t1 := time.Now()
-	s := NewFaceSdkService(fileBytes, deadTime)
-	i, err := s.ReadFromUploadImg()
+	s := newFaceSdkService(fileBytes, deadTime)
+	i, err := s.readFromUploadImg()
 	logger.Debug("ReadFromUploadImg鐢ㄦ椂:", time.Since(t1))
-	t1 = time.Now()
 	if err !=nil{
 		logger.Debug("readFromUploadImg err:",err)
 		return nil,err,i
 	}
-	bc, err := ImgCompress(i)
-	logger.Debug("ImgCompress鐢ㄦ椂:", time.Since(t1))
-	t1 = time.Now()
+	imgBytes, err := proto.Marshal(i)
 	if err !=nil {
-		logger.Debug("ImgCompress err:",err)
+		logger.Debug("i marshal err:",err)
 		return nil,err,i
 	}
-	s.PushImgMsg(bc)
-	logger.Debug("PushImgMsg鐢ㄦ椂:", time.Since(t1))
-	t1 = time.Now()
-	s.GetFaceFea()
-	logger.Debug("GetFaceFea鐢ㄦ椂:", time.Since(t1))
-	if s.Result == nil{
-		return nil,errors.New("no fea"),i
+	detectResults, err := DoFDetectWithRpc(&protomsg.FaceDetectRequest{ReqParam: imgBytes}, deadTime)
+	logger.Debug("鎻愬彇face鍏辩敤鏃讹細", time.Since(t1))
+	if err !=nil {
+		logger.Debug("DoFDetectWithRpc err:",err)
+		return nil,err,i
 	} else {
-		return s.Result,nil,i
+		return detectResults,nil,i
 	}
 }
 
-func NewFaceSdkService(fileBytes []byte, deadTime time.Duration) FaceSdkService{
-	return FaceSdkService{
+func newFaceSdkService(fileBytes []byte, deadTime time.Duration) *FaceSdkService{
+	return &FaceSdkService{
 		File:fileBytes,
 		Id:time.Now().UnixNano(),
 		DeadTime:deadTime,
 	}
 }
 
-var imgPushChan chan []byte
-var client_push deliver.Deliver
-var client_pull deliver.Deliver
-
-func TestPushImgMsg() {
-	InitService()
-
-	i := readTestImgFile()
-
-	logger.Debug("width:%d,height:%d,data.length:%d,timestamp:%s,id:%d\n",i.Width,i.Height,len(i.Data),i.Timestamp,i.Id)
-
-	bc, err := ImgCompress(&i)
-	if err !=nil {
-		logger.Debug("image is not compressible")
-	} else {
-		var s FaceSdkService
-		s.PushImgMsg(bc)
-	}
-}
-
-func (s *FaceSdkService) ReadFromUploadImg() (*protomsg.Image,error){
+func (s *FaceSdkService) readFromUploadImg() (*protomsg.Image,error){
 	picMat, err := gocv.IMDecode(s.File, gocv.IMReadColor)
 	if err !=nil {
 		logger.Debug("gocv.IMDecode err:",err)
 		return nil,err
 	}
 	logger.Debug("picMat.Data.len:", len(picMat.ToBytes()))
-	newMat := gocv.NewMat()
-	size := 1024
-	if picMat.Rows() > size || picMat.Cols() > size {
-		fx := float64(size)/float64(picMat.Rows())
-		fy := float64(size)/float64(picMat.Cols())
-		ff := fx
-		if fx > fy{
-			ff = fy
-		}
-		gocv.Resize(picMat,&newMat, image.Pt(0,0), ff, ff, gocv.InterpolationDefault)
-		picMat = newMat
-	}
+
+	//鍥剧墖缂╁皬鍒嗚鲸鐜�
+	//newMat := gocv.NewMat()
+	//size := 1024
+	//if picMat.Rows() > size || picMat.Cols() > size {
+	//	fx := float64(size)/float64(picMat.Rows())
+	//	fy := float64(size)/float64(picMat.Cols())
+	//	ff := fx
+	//	if fx > fy{
+	//		ff = fy
+	//	}
+	//	gocv.Resize(picMat,&newMat, image.Pt(0,0), ff, ff, gocv.InterpolationDefault)
+	//	picMat = newMat
+	//}
 
 	defer picMat.Close()
 
@@ -130,199 +94,4 @@
 		Id: s.Id,
 		Cid: faceExtractWebCID,
 	},nil
-}
-
-func ImgCompress(i *protomsg.Image) ([]byte,error){
-	if b, err := proto.Marshal(i); err != nil {
-		logger.Debug("protoImage marshal err")
-		return nil,err
-	} else {
-		bc := make([]byte, len(b))
-		ht := make([]int, 64<<10)
-		n, err := lz4.CompressBlock(b, bc, ht)
-		if err != nil {
-			logger.Debug(err)
-			return nil,err
-		}
-		if n >= len(b) {
-			logger.Debug("image is not compressible")
-			return nil,errors.New("compressed len is 0")
-		}
-		bc = bc[:n]
-		return bc,nil
-	}
-}
-
-func (s *FaceSdkService) GetFaceFea(){
-	var wg sync.WaitGroup
-	wg.Add(1)
-	ticker := time.NewTicker(s.DeadTime)
-	go func(ticker *time.Ticker, s *FaceSdkService) {
-		defer ticker.Stop()
-		defer wg.Done()
-
-		for {
-			select {
-			case <-ticker.C:
-				return
-			default:
-				if faces,ok := resultMap.Get(s.Id);ok {
-					s.Result = faces
-					return
-				}
-			}
-		}
-	}(ticker, s)
-	wg.Wait()
-}
-
-func readTestImgFile() protomsg.Image{
-	var i protomsg.Image
-	timeUnix := time.Now().Unix()
-	formatTimeStr := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05")
-	filePath := "/home/user/workspace/timg.jpg"
-
-	picMat := gocv.IMRead(filePath, gocv.IMReadColor)
-
-	defer picMat.Close()
-
-	if picMat.Empty() {
-		logger.Debug("file not exist")
-		return i
-	}
-	height := int32(picMat.Rows())
-	width := int32(picMat.Cols())
-	data := picMat.ToBytes()
-	//wrMat,_ := gocv.NewMatFromBytes(picMat.Rows(),picMat.Cols(),gocv.MatTypeCV8UC3,data)
-	//
-	//gocv.IMWrite("xxx.jpg", wrMat)
-
-	i = protomsg.Image{
-		Width:     width,
-		Height:    height,
-		Timestamp: formatTimeStr,
-		Data:      data,
-		Id:        timeUnix,
-	}
-	i.Cid = uuid.NewV4().String() //鏁版嵁鍞竴id
-	logger.Debug("gocv read img completed")
-	return i
-}
-
-func  (s *FaceSdkService) PushImgMsg(is []byte){
-	imgPushChan <- is
-}
-
-type FeaResult struct {
-	FaceM map[int64][]*protomsg.ResultFaceDetect
-	Lock sync.Mutex
-}
-
-func (f *FeaResult) Write(id int64,faceDetectResult []*protomsg.ResultFaceDetect){
-	f.Lock.Lock()
-	defer f.Lock.Unlock()
-	f.FaceM[id] = faceDetectResult
-}
-
-func (f *FeaResult) Get(id int64) ([]*protomsg.ResultFaceDetect,bool){
-	f.Lock.Lock()
-	defer f.Lock.Unlock()
-	coms,ok := f.FaceM[id]
-	return coms,ok
-}
-
-func (f *FeaResult) Delete(id int64){
-	f.Lock.Lock()
-	defer f.Lock.Unlock()
-	delete(f.FaceM,id)
-}
-
-var resultMap =  FeaResult{}
-
-func InitService() {
-	logger.Debug("service init!")
-	imgPushChan = make(chan []byte)
-	resultMap.FaceM = make(map[int64][]*protomsg.ResultFaceDetect,0)
-	client_push = deliver.NewClient(deliver.PushPull, Url_Service_PUSH)
-	client_pull = deliver.NewClient(deliver.PushPull, Url_Service_PULL)
-	defer func() {
-		client_push.Close()
-		client_pull.Close()
-	}()
-	go thSend()
-
-	go thRecv()
-}
-
-func thSend() {
-	for {
-		select {
-		case d := <-imgPushChan:
-			logger.Debug("imgPushChan in")
-			err := client_push.Send(d)
-			if err != nil {
-				logger.Debug("img Send err:", err)
-			}
-		default:
-			//logger.Debug("no img in")
-		}
-	}
-}
-
-func thRecv() {
-	for {
-		resultBytes, err := client_pull.Recv()
-		if err != nil {
-			//logger.Debug("pull err:", err)
-			continue
-		}
-		rMsg := protomsg.SdkMessage{}
-		if err := proto.Unmarshal(resultBytes, &rMsg); err == nil {
-			i := protomsg.Image{}
-			bdata, err := util.UnCompress(rMsg.Data)
-			if err !=nil {
-				logger.Debug("uncompress err:",err)
-				continue
-			}
-			err = proto.Unmarshal(bdata, &i)
-			if err !=nil {
-				continue
-			}
-			perId := i.Id //鏁版嵁id
-			if rMsg.Tasklab != nil && rMsg.Tasklab.Taskid == Virtual_FaceTaskId {
-				sdkInfos := rMsg.Tasklab.Sdkinfos
-
-				logger.Debug("Len(sdkInfos)=",len(sdkInfos))
-				for _,swt :=range sdkInfos{
-					//浜鸿劯妫�娴嬬殑缁撴灉
-					if swt.Sdktype =="FaceDetect"{
-						logger.Debug("浜鸿劯妫�娴嬬粨鏋滈暱搴︼細",len(swt.Sdkdata))
-						if len(swt.Sdkdata)>1{
-							var pfp protomsg.ParamFacePos
-							err := proto.Unmarshal(swt.Sdkdata, &pfp)
-							if err !=nil {
-								logger.Debug("faceDetect result unmarshal err:",err)
-							} else {
-								logger.Debug("妫�娴嬩汉鑴告暟:",len(pfp.Faces))
-								if len(pfp.Faces)>0{
-									resultMap.Write(perId,pfp.Faces)
-								}
-								//for _,face :=range pfp.Faces{
-									//logger.Debug("FacePos:",face.Pos)
-									//logger.Debug("ThftResult:",face.Result)
-									//	base64Fea := base64.StdEncoding.EncodeToString(face.Feats)
-									//	logger.Debug("perId:",perId)
-									//	logger.Debug("faceFeature:",base64Fea)
-								//}
-							}
-						}
-						break
-					}
-				}
-			}
-		} else {
-			logger.Debug("recv msg Err:", err)
-		}
-
-	}
 }
diff --git a/service/SdkDownLoad.go b/service/SdkDownLoad.go
index 6d43c33..00715d9 100644
--- a/service/SdkDownLoad.go
+++ b/service/SdkDownLoad.go
@@ -1 +1,112 @@
 package service
+
+import (
+	"bytes"
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"strings"
+	"basic.com/valib/logger.git"
+
+	"webserver/util"
+)
+// 浠庢湇鍔″櫒涓婁笅杞芥枃浠跺埌涓存椂鐩綍锛屾牎楠屼箣鍚庡鏋滃畬鏁村皢鍏舵嫹璐濆埌鐩爣鐩綍涓�
+func DownSo(url string)(bool,error) {
+	resp, err := http.Get(url)
+	if err != nil {
+		logger.Error("鑾峰彇鏂囦欢澶辫触")
+		return false,err
+	}
+	// 浠巖esp涓鍑簔ip鏂囦欢瑙e帇缂╋紝瑙e嚭face.so,face.txt,鐒跺悗鎶婅В鍘嬪嚭鐨剆o鐢∕D5缂栫爜鍑轰竴涓猼emp.txt鏂囦欢锛屼笌瑙e帇鍑虹殑so.txt鏂囦欢姣斿锛�
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		logger.Error("璇诲彇resp.body澶辫触")
+		return false,err
+	}
+	CopyFile(body, "/opt/temp/temp.zip")
+	util.DeCompress("/opt/temp/temp.zip", "/opt/temp")
+	fileName := GetFileNameFromUrl(url,false)
+	md5str,err1 := File2md5("/opt/temp/"+fileName+".so")
+	if err1 != nil {
+		logger.Error(err1)
+		return false,err1
+	}
+	md5str_origin,err2 := ioutil.ReadFile("/opt/temp/"+fileName+".txt")
+	if err2 != nil {
+		logger.Error("璇诲彇瑙e帇鍚庣殑md5鏂囦欢澶辫触")
+		return false,err2
+	}
+	flag := CompareMd5([]byte(md5str),md5str_origin)
+	if flag {
+		logger.Info("涓ゆMD5缂栫爜涓�鑷达紒")
+	} else {
+		logger.Debug("涓ゆMD5缂栫爜涓嶄竴鑷达紝璇烽噸鏂颁笅杞�")
+		return false,nil
+	}
+	// 浠巙rl涓埅鍙杝oName
+	soName := GetFileNameFromUrl(url,true)
+	f, err := os.Create("/opt/workspace/ruleprocess/algorithm/" + soName)
+	if err != nil {
+		logger.Error("鍦ㄩ」鐩洰褰曚笅鍒涘缓so鏂囦欢澶辫触")
+		return false,err
+	}
+	data,_ := ioutil.ReadFile("/opt/temp/"+soName)
+	_,err4 := f.Write(data)
+	if err4 != nil {
+		logger.Error("澶嶅埗鏂囦欢鍑洪敊")
+		return false,err4
+	}
+	return true,nil
+}
+
+func CopyFile(byte []byte, dst string) (w int64, err error) {
+	dstFile, err := os.Create(dst)
+	if err != nil {
+		fmt.Println(err.Error())
+		return
+	}
+	defer dstFile.Close()
+	return io.Copy(dstFile, bytes.NewReader(byte))
+}
+
+// 鎸囧畾鐩綍鐨勬枃浠剁敓鎴愮浉搴旂殑MD5鐮佹枃浠�
+func File2md5 (filename string) (string, error) {
+	// 鏂囦欢鐢熸垚MD5鍔犲瘑鍔犲瘑鏂囦欢
+	file, err := os.Open(filename)
+	if err != nil {
+		fmt.Println("os Open error")
+		return "", err
+	}
+	md5 := md5.New()
+	_, err = io.Copy(md5, file)
+	if err != nil {
+		fmt.Println("io copy error")
+		return "", err
+	}
+	md5Str := hex.EncodeToString(md5.Sum(nil))
+	return md5Str,nil
+}
+// 浠巙rl涓埅鍙栧嚭鏂囦欢鍚嶏紝鍙傛暟鏄槸鍚﹀甫鍚庣紑
+func GetFileNameFromUrl(url string,withSuffix bool)string {
+	fileName := strings.Split(url,"/")[len(strings.Split(url,"/"))-1]
+	if withSuffix {
+		return fileName
+	} else {
+		withoutSuffix := strings.Split(fileName,".")[0]
+		return withoutSuffix
+	}
+}
+
+// 姣旇緝涓や釜MD5缂栫爜鏄惁涓�鑷�
+func CompareMd5(value1 []byte,value2 []byte) bool{
+	num := bytes.Compare(value1,value2)
+	if num == 0 {
+		return true
+	} else {
+		return false
+	}
+}
\ No newline at end of file
diff --git a/util/zip.go b/util/zip.go
index c7d8682..166173d 100644
--- a/util/zip.go
+++ b/util/zip.go
@@ -1 +1,118 @@
 package util
+
+import (
+	"archive/zip"
+	"io"
+	"os"
+	"strings"
+)
+
+//鍘嬬缉鏂囦欢
+//files 鏂囦欢鏁扮粍锛屽彲浠ユ槸涓嶅悓dir涓嬬殑鏂囦欢鎴栬�呮枃浠跺す
+//dest 鍘嬬缉鏂囦欢瀛樻斁鍦板潃
+func Compress2Zip(files []*os.File, dest string) error {
+	d, _ := os.Create(dest)
+	defer d.Close()
+	w := zip.NewWriter(d)
+	defer w.Close()
+	for _, file := range files {
+		err := compress(file, "", w)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func compress(file *os.File, prefix string, zw *zip.Writer) error {
+	info, err := file.Stat()
+	if err != nil {
+		return err
+	}
+	if info.IsDir() {
+		prefix = prefix + "/" + info.Name()
+		fileInfos, err := file.Readdir(-1)
+		if err != nil {
+			return err
+		}
+		for _, fi := range fileInfos {
+			f, err := os.Open(file.Name() + "/" + fi.Name())
+			if err != nil {
+				return err
+			}
+			err = compress(f, prefix, zw)
+			if err != nil {
+				return err
+			}
+		}
+	} else {
+		header, err := zip.FileInfoHeader(info)
+		header.Name = prefix + "/" + header.Name
+		if err != nil {
+			return err
+		}
+		writer, err := zw.CreateHeader(header)
+		if err != nil {
+			return err
+		}
+		_, err = io.Copy(writer, file)
+		file.Close()
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+//瑙e帇
+func DeCompress(zipFile, dest string) error {
+	reader, err := zip.OpenReader(zipFile)
+	if err != nil {
+		return err
+	}
+	defer reader.Close()
+	for _, file := range reader.File {
+		rc, err := file.Open()
+		if err != nil {
+			return err
+		}
+		defer rc.Close()
+		filename := dest + file.Name
+		err = os.MkdirAll(getDir(filename), 0755)
+		if err != nil {
+			return err
+		}
+		w, err := os.Create(filename)
+		if err != nil {
+			return err
+		}
+		defer w.Close()
+		_, err = io.Copy(w, rc)
+		if err != nil {
+			return err
+		}
+		w.Close()
+		rc.Close()
+	}
+	return nil
+}
+
+func getDir(path string) string {
+	return subString(path, 0, strings.LastIndex(path, "/"))
+}
+
+func subString(str string, start, end int) string {
+	rs := []rune(str)
+	length := len(rs)
+
+	if start < 0 || start > length {
+		panic("start is wrong")
+	}
+
+	if end < start || end > length {
+		panic("end is wrong")
+	}
+
+	return string(rs[start:end])
+}
+

--
Gitblit v1.8.0