Bläddra i källkod

项目~医疗~数据准备~备份

zhengkun 3 år sedan
förälder
incheckning
b319efdc28

+ 4 - 1
README.md

@@ -9,4 +9,7 @@
 +   
 
 
-#### fieldproject_medical(医疗数据处理模块)  
+#### fieldproject_medical(医疗数据处理模块) 
++ data_preparation (基础信息~数据准备~)
+  + 1、企业产品  2、医院整合  3、产品整合  4、修复代码表等
+

+ 150 - 0
filedproject_medical/data_preparation/src/class/initdata.go

@@ -0,0 +1,150 @@
+package class
+
+import log "github.com/donnie4w/go-logger/logger"
+
+var (
+	Save_Mgo, Qy_Mgo, Spi_Mgo   *MongodbSim
+	TimeLayout                  = "2006-01-02 15:04:05"
+	TimeTmeplate                = "2006-01-02"
+	MysqlTool                   *Mysql
+	Medical_type, Medical_level map[string]string
+
+	isLocal bool
+)
+
+func InitClass() {
+	isLocal = true //本地
+	initMgo()
+	initMysql()
+	initClassCode() //加载相关代码表
+}
+
+//初始化mgo
+func initMgo() {
+	if isLocal {
+		Save_Mgo = &MongodbSim{
+			MongodbAddr: "127.0.0.1:27017",
+			DbName:      "zhengkun",
+			Size:        10,
+			UserName:    "",
+			Password:    "",
+		}
+		Save_Mgo.InitPool()
+
+		//save_mgo = &MongodbSim{
+		//	MongodbAddr: "192.168.3.207:27092",
+		//	DbName:      "zhengkun",
+		//	Size:        10,
+		//	UserName:    "",
+		//	Password:    "",
+		//}
+		//save_mgo.InitPool()
+
+		Qy_Mgo = &MongodbSim{
+			MongodbAddr: "127.0.0.1:27017",
+			DbName:      "mixdata",
+			Size:        10,
+			UserName:    "",
+			Password:    "",
+		}
+		Qy_Mgo.InitPool()
+
+		Spi_Mgo = &MongodbSim{
+			MongodbAddr: "127.0.0.1:27017",
+			DbName:      "zhengkun",
+			Size:        10,
+			UserName:    "",
+			Password:    "",
+		}
+		Spi_Mgo.InitPool()
+	} else {
+		Save_Mgo = &MongodbSim{
+			MongodbAddr: "172.17.4.87:27080",
+			DbName:      "hospital",
+			Size:        10,
+			UserName:    "",
+			Password:    "",
+		}
+		Save_Mgo.InitPool()
+
+		Qy_Mgo = &MongodbSim{
+			MongodbAddr: "172.17.145.163:27083,172.17.4.187:27082",
+			DbName:      "mixdata",
+			Size:        10,
+			UserName:    "zhengkun",
+			Password:    "zk@123123",
+		}
+		Qy_Mgo.InitPool()
+
+		Spi_Mgo = &MongodbSim{
+			MongodbAddr: "172.17.4.181:27001",
+			DbName:      "mixdata",
+			Size:        10,
+			UserName:    "",
+			Password:    "",
+		}
+		Spi_Mgo.InitPool()
+	}
+}
+
+func initMysql() {
+	MysqlTool = &Mysql{
+		Address:  "192.168.3.217:4000",
+		UserName: "root",
+		PassWord: "=PDT49#80Z!RVv52_z",
+		DBName:   "jy_lycp",
+	}
+	MysqlTool.Init()
+
+}
+
+func initClassCode() {
+	//临时加载~后续需要加载sql
+	Medical_level = map[string]string{
+		"一级甲等": "01",
+		"一级乙等": "02",
+		"一级丙等": "03",
+		"一级其它": "04",
+		"二级甲等": "05",
+		"二级乙等": "06",
+		"二级丙等": "07",
+		"二级其它": "08",
+		"三级甲等": "09",
+		"三级乙等": "10",
+		"三级丙等": "11",
+		"三级特等": "12",
+		"三级其它": "13",
+		"其它":   "14",
+	}
+
+	Medical_type = map[string]string{
+		"综合医院":     "01",
+		"专科医院":     "02",
+		"中医医院":     "03",
+		"民族医院":     "04",
+		"康复医院":     "05",
+		"妇幼保健院":    "06",
+		"社区卫生服务中心": "07",
+		"乡镇卫生院":    "08",
+		"疗养院":      "09",
+		"门诊部":      "10",
+		"诊所及卫生所":   "11",
+		"村卫生室":     "12",
+		"急救中心":     "13",
+		"防治院":      "14",
+		"护理中心":     "15",
+		"检验诊断中心":   "16",
+		"美容整形":     "17",
+		"公司医院":     "18",
+		"校医院":      "19",
+		"其它":       "20",
+	}
+}
+
+//插入数据
+func InsertMysqlData(name string, data map[string]interface{}, mark string) {
+	inb := MysqlTool.Insert(name, data)
+	if inb == -1 {
+		log.Debug("插入数据异常...", name, "~", mark)
+	}
+}

+ 327 - 0
filedproject_medical/data_preparation/src/class/mgo.go

@@ -0,0 +1,327 @@
+package class
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/bson/primitive"
+	"go.mongodb.org/mongo-driver/mongo"
+	"go.mongodb.org/mongo-driver/mongo/options"
+)
+
+type MgoSess struct {
+	Db     string
+	Coll   string
+	Query  interface{}
+	Sorts  []string
+	fields interface{}
+	limit  int64
+	skip   int64
+	M      *MongodbSim
+}
+
+type MgoIter struct {
+	Cursor *mongo.Cursor
+}
+
+func (mt *MgoIter) Next(result interface{}) bool {
+	if mt.Cursor != nil {
+		if mt.Cursor.Next(nil) {
+			err := mt.Cursor.Decode(result)
+			if err != nil {
+				log.Println("mgo cur err", err.Error())
+				mt.Cursor.Close(nil)
+				return false
+			}
+			return true
+		} else {
+			mt.Cursor.Close(nil)
+			return false
+		}
+	} else {
+		return false
+	}
+
+}
+
+func (ms *MgoSess) DB(name string) *MgoSess {
+	ms.Db = name
+	return ms
+}
+
+func (ms *MgoSess) C(name string) *MgoSess {
+	ms.Coll = name
+	return ms
+}
+
+func (ms *MgoSess) Find(q interface{}) *MgoSess {
+	ms.Query = q
+	return ms
+}
+
+func (ms *MgoSess) Select(fields interface{}) *MgoSess {
+	ms.fields = fields
+	return ms
+}
+
+func (ms *MgoSess) Limit(limit int64) *MgoSess {
+	ms.limit = limit
+	return ms
+}
+func (ms *MgoSess) Skip(skip int64) *MgoSess {
+	ms.skip = skip
+	return ms
+}
+
+func (ms *MgoSess) Sort(sorts ...string) *MgoSess {
+	ms.Sorts = sorts
+	return ms
+}
+
+func (ms *MgoSess) Iter() *MgoIter {
+	it := &MgoIter{}
+	find := options.Find()
+	if ms.skip > 0 {
+		find.SetSkip(ms.skip)
+	}
+	if ms.limit > 0 {
+		find.SetLimit(ms.limit)
+	}
+	find.SetBatchSize(100)
+	if len(ms.Sorts) > 0 {
+		sort := bson.M{}
+		for _, k := range ms.Sorts {
+			switch k[:1] {
+			case "-":
+				sort[k[1:]] = -1
+			case "+":
+				sort[k[1:]] = 1
+			default:
+				sort[k] = 1
+			}
+		}
+		find.SetSort(sort)
+	}
+	if ms.fields != nil {
+		find.SetProjection(ms.fields)
+	}
+	cur, err := ms.M.C.Database(ms.Db).Collection(ms.Coll).Find(ms.M.Ctx, ms.Query, find)
+	if err != nil {
+		log.Println("mgo find err", err.Error())
+	} else {
+		it.Cursor = cur
+	}
+	return it
+}
+
+type MongodbSim struct {
+	MongodbAddr string
+	Size        int
+	//	MinSize     int
+	DbName   string
+	C        *mongo.Client
+	Ctx      context.Context
+	ShortCtx context.Context
+	pool     chan bool
+	UserName string
+	Password string
+}
+
+func (m *MongodbSim) GetMgoConn() *MgoSess {
+	//m.Open()
+	ms := &MgoSess{}
+	ms.M = m
+	return ms
+}
+
+func (m *MongodbSim) DestoryMongoConn(ms *MgoSess) {
+	//m.Close()
+	ms.M = nil
+	ms = nil
+}
+
+func (m *MongodbSim) InitPool() {
+	opts := options.Client()
+	opts.SetConnectTimeout(3 * time.Second)
+	opts.ApplyURI("mongodb://" + m.MongodbAddr)
+	opts.SetMaxPoolSize(uint64(m.Size))
+	m.pool = make(chan bool, m.Size)
+
+	if m.UserName != "" && m.Password != "" {
+		cre := options.Credential{
+			Username: m.UserName,
+			Password: m.Password,
+		}
+		opts.SetAuth(cre)
+	}
+
+	opts.SetMaxConnIdleTime(2 * time.Hour)
+	m.Ctx, _ = context.WithTimeout(context.Background(), 99999*time.Hour)
+	m.ShortCtx, _ = context.WithTimeout(context.Background(), 1*time.Minute)
+	client, err := mongo.Connect(m.ShortCtx, opts)
+	if err != nil {
+		log.Println("mgo init error:", err.Error())
+	} else {
+		m.C = client
+		log.Println("init success")
+	}
+}
+
+func (m *MongodbSim) Open() {
+	m.pool <- true
+}
+func (m *MongodbSim) Close() {
+	<-m.pool
+}
+
+//批量插入
+func (m *MongodbSim) UpSertBulk(c string, doc ...[]map[string]interface{}) (map[int64]interface{}, bool) {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	var writes []mongo.WriteModel
+	for _, d := range doc {
+		write := mongo.NewUpdateOneModel()
+		write.SetFilter(d[0])
+		write.SetUpdate(d[1])
+		write.SetUpsert(true)
+		writes = append(writes, write)
+	}
+	r, e := coll.BulkWrite(m.Ctx, writes)
+	if e != nil {
+		log.Println("mgo upsert error:", e.Error())
+		return nil, false
+	}
+	//	else {
+	//		if r.UpsertedCount != int64(len(doc)) {
+	//			log.Println("mgo upsert uncomplete:uc/dc", r.UpsertedCount, len(doc))
+	//		}
+	//		return true
+	//	}
+	return r.UpsertedIDs, true
+}
+
+//批量插入
+func (m *MongodbSim) SaveBulk(c string, doc ...map[string]interface{}) bool {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	var writes []mongo.WriteModel
+	for _, d := range doc {
+		write := mongo.NewInsertOneModel()
+		write.SetDocument(d)
+		writes = append(writes, write)
+	}
+	_, e := coll.BulkWrite(m.Ctx, writes)
+	if e != nil {
+		log.Println("mgo savebulk error:", e.Error())
+		return false
+	}
+	return true
+}
+
+//保存
+func (m *MongodbSim) Save(c string, doc map[string]interface{}) interface{} {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	r, err := coll.InsertOne(m.Ctx, doc)
+	if err != nil {
+		return nil
+	}
+	return r.InsertedID
+}
+
+//更新by Id
+func (m *MongodbSim) UpdateById(c, id string, doc map[string]interface{}) bool {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	_, err := coll.UpdateOne(m.Ctx, map[string]interface{}{"_id": StringTOBsonId(id)}, doc)
+	if err != nil {
+		return false
+	}
+	return true
+}
+
+//删除by id
+func (m *MongodbSim) DeleteById(c, id string) int64 {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	r, err := coll.DeleteOne(m.Ctx, map[string]interface{}{"_id": StringTOBsonId(id)})
+	if err != nil {
+		return 0
+	}
+	return r.DeletedCount
+}
+
+//通过条件删除
+func (m *MongodbSim) Delete(c string, query map[string]interface{}) int64 {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	r, err := coll.DeleteMany(m.Ctx, query)
+	if err != nil {
+		return 0
+	}
+	return r.DeletedCount
+}
+
+//findbyid
+func (m *MongodbSim) FindById(c, id string) map[string]interface{} {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	r := coll.FindOne(m.Ctx, map[string]interface{}{"_id": StringTOBsonId(id)})
+	v := map[string]interface{}{}
+	r.Decode(&v)
+	return v
+}
+
+//findone
+func (m *MongodbSim) FindOne(c string, query map[string]interface{}) map[string]interface{} {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	r := coll.FindOne(m.Ctx, query)
+	v := map[string]interface{}{}
+	r.Decode(&v)
+	return v
+}
+
+//find
+func (m *MongodbSim) Find(c string, query map[string]interface{}, sort, fields interface{}) ([]map[string]interface{}, error) {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	op := options.Find()
+	r, err := coll.Find(m.Ctx, query, op.SetSort(sort), op.SetProjection(fields))
+	if err != nil {
+		log.Fatal(err)
+		return nil, err
+	}
+
+	var results []map[string]interface{}
+	if err = r.All(m.Ctx, &results); err != nil {
+		log.Fatal(err)
+		return nil, err
+	}
+	return results, nil
+}
+
+//创建_id
+func NewObjectId() primitive.ObjectID {
+	return primitive.NewObjectID()
+}
+
+func StringTOBsonId(id string) primitive.ObjectID {
+	objectId, _ := primitive.ObjectIDFromHex(id)
+	return objectId
+}
+
+func BsonTOStringId(id interface{}) string {
+	return id.(primitive.ObjectID).Hex()
+}

+ 505 - 0
filedproject_medical/data_preparation/src/class/mysql.go

@@ -0,0 +1,505 @@
+package class
+
+import (
+	"bytes"
+	"database/sql"
+	"fmt"
+	"log"
+	"reflect"
+	"strings"
+	"time"
+
+	_ "github.com/go-sql-driver/mysql"
+)
+
+type Mysql struct {
+	Address      string  //数据库地址:端口
+	UserName     string  //用户名
+	PassWord     string  //密码
+	DBName       string  //数据库名
+	DB           *sql.DB //数据库连接池对象
+	MaxOpenConns int     //用于设置最大打开的连接数,默认值为0表示不限制。
+	MaxIdleConns int     //用于设置闲置的连接数。
+}
+
+func (m *Mysql) Init() {
+	if m.MaxOpenConns <= 0 {
+		m.MaxOpenConns = 20
+	}
+	if m.MaxIdleConns <= 0 {
+		m.MaxIdleConns = 20
+	}
+	var err error //utf8mb4
+	m.DB, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4", m.UserName, m.PassWord, m.Address, m.DBName))
+	if err != nil {
+		log.Println(err)
+		return
+	}
+	m.DB.SetMaxOpenConns(m.MaxOpenConns)
+	m.DB.SetMaxIdleConns(m.MaxIdleConns)
+	m.DB.SetConnMaxLifetime(time.Minute * 3)
+	err = m.DB.Ping()
+	if err != nil {
+		log.Println(err)
+	}
+}
+
+//新增
+func (m *Mysql) Insert(tableName string, data map[string]interface{}) int64 {
+	return m.InsertByTx(nil, tableName, data)
+}
+
+//带有事务的新增
+func (m *Mysql) InsertByTx(tx *sql.Tx, tableName string, data map[string]interface{}) int64 {
+	fields := []string{}
+	values := []interface{}{}
+	placeholders := []string{}
+	if tableName == "dataexport_order" {
+		if _, ok := data["user_nickname"]; ok {
+			data["user_nickname"] = ""
+		}
+	}
+	for k, v := range data {
+		fields = append(fields, k)
+		values = append(values, v)
+		placeholders = append(placeholders, "?")
+	}
+	q := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", tableName, strings.Join(fields, ","), strings.Join(placeholders, ","))
+	//log.Println("mysql", q, values)
+	return m.InsertBySqlByTx(tx, q, values...)
+}
+
+//sql语句新增
+func (m *Mysql) InsertBySql(q string, args ...interface{}) int64 {
+	return m.InsertBySqlByTx(nil, q, args...)
+}
+
+//带有事务的sql语句新增
+func (m *Mysql) InsertBySqlByTx(tx *sql.Tx, q string, args ...interface{}) int64 {
+	result, _ := m.ExecBySqlByTx(tx, q, args...)
+	if result == nil {
+		return -1
+	}
+	id, err := result.LastInsertId()
+	if err != nil {
+		log.Println(err)
+		return -1
+	}
+	return id
+}
+
+//批量新增
+func (m *Mysql) InsertIgnoreBatch(tableName string, fields []string, values []interface{}) (int64, int64) {
+	return m.InsertIgnoreBatchByTx(nil, tableName, fields, values)
+}
+
+//带事务的批量新增
+func (m *Mysql) InsertIgnoreBatchByTx(tx *sql.Tx, tableName string, fields []string, values []interface{}) (int64, int64) {
+	return m.insertOrReplaceBatchByTx(tx, "INSERT", "IGNORE", tableName, fields, values)
+}
+
+//批量新增
+func (m *Mysql) InsertBatch(tableName string, fields []string, values []interface{}) (int64, int64) {
+	return m.InsertBatchByTx(nil, tableName, fields, values)
+}
+
+//带事务的批量新增
+func (m *Mysql) InsertBatchByTx(tx *sql.Tx, tableName string, fields []string, values []interface{}) (int64, int64) {
+	return m.insertOrReplaceBatchByTx(tx, "INSERT", "", tableName, fields, values)
+}
+
+//批量更新
+func (m *Mysql) ReplaceBatch(tableName string, fields []string, values []interface{}) (int64, int64) {
+	return m.ReplaceBatchByTx(nil, tableName, fields, values)
+}
+
+//带事务的批量更新
+func (m *Mysql) ReplaceBatchByTx(tx *sql.Tx, tableName string, fields []string, values []interface{}) (int64, int64) {
+	return m.insertOrReplaceBatchByTx(tx, "REPLACE", "", tableName, fields, values)
+}
+
+func (m *Mysql) insertOrReplaceBatchByTx(tx *sql.Tx, tp string, afterInsert, tableName string, fields []string, values []interface{}) (int64, int64) {
+	placeholders := []string{}
+	for range fields {
+		placeholders = append(placeholders, "?")
+	}
+	placeholder := strings.Join(placeholders, ",")
+	array := []string{}
+	for i := 0; i < len(values)/len(fields); i++ {
+		array = append(array, fmt.Sprintf("(%s)", placeholder))
+	}
+	q := fmt.Sprintf("%s %s INTO %s (%s) VALUES %s", tp, afterInsert, tableName, strings.Join(fields, ","), strings.Join(array, ","))
+	result, _ := m.ExecBySqlByTx(tx, q, values...)
+	if result == nil {
+		return -1, -1
+	}
+	v1, e1 := result.RowsAffected()
+	if e1 != nil {
+		log.Println(e1)
+		return -1, -1
+	}
+	v2, e2 := result.LastInsertId()
+	if e2 != nil {
+		log.Println(e2)
+		return -1, -1
+	}
+	return v1, v2
+}
+
+//sql语句执行
+func (m *Mysql) ExecBySql(q string, args ...interface{}) (sql.Result, error) {
+	return m.ExecBySqlByTx(nil, q, args...)
+}
+
+//sql语句执行,带有事务
+func (m *Mysql) ExecBySqlByTx(tx *sql.Tx, q string, args ...interface{}) (sql.Result, error) {
+	var stmtIns *sql.Stmt
+	var err error
+	if tx == nil {
+		stmtIns, err = m.DB.Prepare(q)
+	} else {
+		stmtIns, err = tx.Prepare(q)
+	}
+	if err != nil {
+		log.Println(err)
+		return nil, err
+	}
+	defer stmtIns.Close()
+	result, err := stmtIns.Exec(args...)
+	if err != nil {
+		//log.Println(args, err)
+		log.Println(err)
+		return nil, err
+	}
+	return result, nil
+}
+
+/*不等于 map[string]string{"ne":"1"}
+ *不等于多个 map[string]string{"notin":[]interface{}{1,2}}
+ *字段为空 map[string]string{"name":"$isNull"}
+ *字段不为空 map[string]string{"name":"$isNotNull"}
+ */
+func (m *Mysql) Find(tableName string, query map[string]interface{}, fields, order string, start, pageSize int) *[]map[string]interface{} {
+	fs := []string{}
+	vs := []interface{}{}
+	for k, v := range query {
+		rt := reflect.TypeOf(v)
+		rv := reflect.ValueOf(v)
+		if rt.Kind() == reflect.Map {
+			for _, rv_k := range rv.MapKeys() {
+				if rv_k.String() == "ne" {
+					fs = append(fs, fmt.Sprintf("%s!=?", k))
+					vs = append(vs, rv.MapIndex(rv_k).Interface())
+				}
+				if rv_k.String() == "notin" {
+					if len(rv.MapIndex(rv_k).Interface().([]interface{})) > 0 {
+						for _, v := range rv.MapIndex(rv_k).Interface().([]interface{}) {
+							fs = append(fs, fmt.Sprintf("%s!=?", k))
+							vs = append(vs, v)
+						}
+					}
+				}
+				if rv_k.String() == "in" {
+					if len(rv.MapIndex(rv_k).Interface().([]interface{})) > 0 {
+						_fs := fmt.Sprintf("%s in (?", k)
+						for k, v := range rv.MapIndex(rv_k).Interface().([]interface{}) {
+							if k > 0 {
+								_fs += ",?"
+							}
+							vs = append(vs, v)
+						}
+						_fs += ")"
+						fs = append(fs, _fs)
+					}
+				}
+			}
+		} else {
+			if v == "$isNull" {
+				fs = append(fs, fmt.Sprintf("%s is null", k))
+			} else if v == "$isNotNull" {
+				fs = append(fs, fmt.Sprintf("%s is not null", k))
+			} else {
+				fs = append(fs, fmt.Sprintf("%s=?", k))
+				vs = append(vs, v)
+			}
+		}
+	}
+	var buffer bytes.Buffer
+	buffer.WriteString("select ")
+	if fields == "" {
+		buffer.WriteString("*")
+	} else {
+		buffer.WriteString(fields)
+	}
+	buffer.WriteString(" from ")
+	buffer.WriteString(tableName)
+	if len(fs) > 0 {
+		buffer.WriteString(" where ")
+		buffer.WriteString(strings.Join(fs, " and "))
+	}
+	if order != "" {
+		buffer.WriteString(" order by ")
+		buffer.WriteString(order)
+	}
+	if start > -1 && pageSize > 0 {
+		buffer.WriteString(" limit ")
+		buffer.WriteString(fmt.Sprint(start))
+		buffer.WriteString(",")
+		buffer.WriteString(fmt.Sprint(pageSize))
+	}
+	q := buffer.String()
+	//log.Println(q, vs)
+	return m.SelectBySql(q, vs...)
+}
+
+//sql语句查询
+func (m *Mysql) SelectBySql(q string, args ...interface{}) *[]map[string]interface{} {
+	return m.SelectBySqlByTx(nil, q, args...)
+}
+func (m *Mysql) SelectBySqlByTx(tx *sql.Tx, q string, args ...interface{}) *[]map[string]interface{} {
+	return m.Select(0, nil, tx, q, args...)
+}
+func (m *Mysql) Select(bath int, f func(l *[]map[string]interface{}), tx *sql.Tx, q string, args ...interface{}) *[]map[string]interface{} {
+	var stmtOut *sql.Stmt
+	var err error
+	if tx == nil {
+		stmtOut, err = m.DB.Prepare(q)
+	} else {
+		stmtOut, err = tx.Prepare(q)
+	}
+	if err != nil {
+		log.Println(err)
+		return nil
+	}
+	defer stmtOut.Close()
+	rows, err := stmtOut.Query(args...)
+	if err != nil {
+		log.Println(err)
+		return nil
+	}
+	if rows != nil {
+		defer rows.Close()
+	}
+	columns, err := rows.Columns()
+	if err != nil {
+		log.Println(err)
+		return nil
+	}
+	list := []map[string]interface{}{}
+	for rows.Next() {
+		scanArgs := make([]interface{}, len(columns))
+		values := make([]interface{}, len(columns))
+		ret := make(map[string]interface{})
+		for k, _ := range values {
+			scanArgs[k] = &values[k]
+		}
+		err = rows.Scan(scanArgs...)
+		if err != nil {
+			log.Println(err)
+			break
+		}
+		for i, col := range values {
+			if v, ok := col.([]uint8); ok {
+				ret[columns[i]] = string(v)
+			} else {
+				ret[columns[i]] = col
+			}
+		}
+		list = append(list, ret)
+		if bath > 0 && len(list) == bath {
+			f(&list)
+			list = []map[string]interface{}{}
+		}
+	}
+	if bath > 0 && len(list) > 0 {
+		f(&list)
+		list = []map[string]interface{}{}
+	}
+	return &list
+}
+func (m *Mysql) SelectByBath(bath int, f func(l *[]map[string]interface{}), q string, args ...interface{}) {
+	m.SelectByBathByTx(bath, f, nil, q, args...)
+}
+func (m *Mysql) SelectByBathByTx(bath int, f func(l *[]map[string]interface{}), tx *sql.Tx, q string, args ...interface{}) {
+	m.Select(bath, f, tx, q, args...)
+}
+func (m *Mysql) FindOne(tableName string, query map[string]interface{}, fields, order string) *map[string]interface{} {
+	list := m.Find(tableName, query, fields, order, 0, 1)
+	if list != nil && len(*list) == 1 {
+		temp := (*list)[0]
+		return &temp
+	}
+	return nil
+}
+
+//修改
+func (m *Mysql) Update(tableName string, query, update map[string]interface{}) bool {
+	return m.UpdateByTx(nil, tableName, query, update)
+}
+
+//带事务的修改
+func (m *Mysql) UpdateByTx(tx *sql.Tx, tableName string, query, update map[string]interface{}) bool {
+	q_fs := []string{}
+	u_fs := []string{}
+	values := []interface{}{}
+	for k, v := range update {
+		q_fs = append(q_fs, fmt.Sprintf("%s=?", k))
+		values = append(values, v)
+	}
+	for k, v := range query {
+		u_fs = append(u_fs, fmt.Sprintf("%s=?", k))
+		values = append(values, v)
+	}
+	q := fmt.Sprintf("update %s set %s where %s", tableName, strings.Join(q_fs, ","), strings.Join(u_fs, " and "))
+	//log.Println(q, values)
+	return m.UpdateOrDeleteBySqlByTx(tx, q, values...) >= 0
+}
+
+//删除
+func (m *Mysql) Delete(tableName string, query map[string]interface{}) bool {
+	return m.DeleteByTx(nil, tableName, query)
+}
+func (m *Mysql) DeleteByTx(tx *sql.Tx, tableName string, query map[string]interface{}) bool {
+	fields := []string{}
+	values := []interface{}{}
+	for k, v := range query {
+		fields = append(fields, fmt.Sprintf("%s=?", k))
+		values = append(values, v)
+	}
+	q := fmt.Sprintf("delete from %s where %s", tableName, strings.Join(fields, " and "))
+	log.Println(q, values)
+	return m.UpdateOrDeleteBySqlByTx(tx, q, values...) > 0
+}
+
+//修改或删除
+func (m *Mysql) UpdateOrDeleteBySql(q string, args ...interface{}) int64 {
+	return m.UpdateOrDeleteBySqlByTx(nil, q, args...)
+}
+
+//带事务的修改或删除
+func (m *Mysql) UpdateOrDeleteBySqlByTx(tx *sql.Tx, q string, args ...interface{}) int64 {
+	result, err := m.ExecBySqlByTx(tx, q, args...)
+	if err != nil {
+		log.Println(err)
+		return -1
+	}
+	count, err := result.RowsAffected()
+	if err != nil {
+		log.Println(err)
+		return -1
+	}
+	return count
+}
+
+//总数
+func (m *Mysql) Count(tableName string, query map[string]interface{}) int64 {
+	fields := []string{}
+	values := []interface{}{}
+	for k, v := range query {
+		rt := reflect.TypeOf(v)
+		rv := reflect.ValueOf(v)
+		if rt.Kind() == reflect.Map {
+			for _, rv_k := range rv.MapKeys() {
+				if rv_k.String() == "ne" {
+					fields = append(fields, fmt.Sprintf("%s!=?", k))
+					values = append(values, rv.MapIndex(rv_k).Interface())
+				}
+				if rv_k.String() == "notin" {
+					if len(rv.MapIndex(rv_k).Interface().([]interface{})) > 0 {
+						for _, v := range rv.MapIndex(rv_k).Interface().([]interface{}) {
+							fields = append(fields, fmt.Sprintf("%s!=?", k))
+							values = append(values, v)
+						}
+					}
+				}
+				if rv_k.String() == "in" {
+					if len(rv.MapIndex(rv_k).Interface().([]interface{})) > 0 {
+						_fs := fmt.Sprintf("%s in (?", k)
+						for k, v := range rv.MapIndex(rv_k).Interface().([]interface{}) {
+							if k > 0 {
+								_fs += ",?"
+							}
+							values = append(values, v)
+						}
+						_fs += ")"
+						fields = append(fields, _fs)
+					}
+				}
+			}
+		} else if v == "$isNull" {
+			fields = append(fields, fmt.Sprintf("%s is null", k))
+		} else if v == "$isNotNull" {
+			fields = append(fields, fmt.Sprintf("%s is not null", k))
+		} else {
+			fields = append(fields, fmt.Sprintf("%s=?", k))
+			values = append(values, v)
+		}
+	}
+	q := fmt.Sprintf("select count(1) as count from %s", tableName)
+	if len(query) > 0 {
+		q += fmt.Sprintf(" where %s", strings.Join(fields, " and "))
+	}
+	log.Println(q, values)
+	return m.CountBySql(q, values...)
+}
+func (m *Mysql) CountBySql(q string, args ...interface{}) int64 {
+	stmtIns, err := m.DB.Prepare(q)
+	if err != nil {
+		log.Println(err)
+		return -1
+	}
+	defer stmtIns.Close()
+
+	rows, err := stmtIns.Query(args...)
+	if err != nil {
+		log.Println(err)
+		return -1
+	}
+	if rows != nil {
+		defer rows.Close()
+	}
+	var count int64 = -1
+	if rows.Next() {
+		err = rows.Scan(&count)
+		if err != nil {
+			log.Println(err)
+		}
+	}
+	return count
+}
+
+//执行事务
+func (m *Mysql) ExecTx(msg string, f func(tx *sql.Tx) bool) bool {
+	tx, err := m.DB.Begin()
+	if err != nil {
+		log.Println(msg, "获取事务错误", err)
+	} else {
+		if f(tx) {
+			if err := tx.Commit(); err != nil {
+				log.Println(msg, "提交事务错误", err)
+			} else {
+				return true
+			}
+		} else {
+			if err := tx.Rollback(); err != nil {
+				log.Println(msg, "事务回滚错误", err)
+			}
+		}
+	}
+	return false
+}
+
+/*************方法命名不规范,上面有替代方法*************/
+func (m *Mysql) Query(query string, args ...interface{}) *[]map[string]interface{} {
+	return m.SelectBySql(query, args...)
+}
+
+func (m *Mysql) QueryCount(query string, args ...interface{}) (count int) {
+	count = -1
+	if !strings.Contains(strings.ToLower(query), "count(*)") {
+		fmt.Println("QueryCount need query like < select count(*) from ..... >")
+		return
+	}
+	count = int(m.CountBySql(query, args...))
+	return
+}

+ 117 - 0
filedproject_medical/data_preparation/src/company/company.go

@@ -0,0 +1,117 @@
+package company
+
+import (
+	"class"
+	log "github.com/donnie4w/go-logger/logger"
+	qu "qfw/util"
+	"sync"
+	"time"
+)
+
+var companylock sync.Mutex
+
+//开始执行企业产品信息
+func RunCompanyProductInfo() {
+	dealWithCompanyProductInfo()
+}
+
+//处理企业基本信息
+func dealWithCompanyProductInfo() {
+	//来源mgo~181
+	sess := class.Save_Mgo.GetMgoConn()
+	defer class.Save_Mgo.DestoryMongoConn(sess)
+	q := map[string]interface{}{}
+	it := sess.DB(class.Save_Mgo.DbName).C("zktest_mysql_company_info").Find(&q).Sort("_id").Iter()
+	pool := make(chan bool, 1)
+	wg := &sync.WaitGroup{}
+	total, isok1, isok2 := 0, 0, 0
+	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
+		if total%100 == 0 {
+			log.Debug("cur index ", total, isok1, isok2)
+		}
+		pool <- true
+		wg.Add(1)
+		go func(tmp map[string]interface{}) {
+			defer func() {
+				<-pool
+				wg.Done()
+			}()
+			company_name := qu.ObjToString(tmp["company_name"])
+			business_type := qu.ObjToString(tmp["business_type"])
+			sc_info, jy_info := treatCompanyTypeInfo(company_name, business_type)
+
+			companylock.Lock()
+			isok1 += len(sc_info)
+			isok2 += len(jy_info)
+			companylock.Unlock()
+		}(tmp)
+		tmp = make(map[string]interface{})
+	}
+	wg.Wait()
+
+	log.Debug("is over ", total, isok1, isok2)
+}
+
+//构建产品信息~
+func treatCompanyTypeInfo(company_name string, company_type string) ([]map[string]interface{}, []map[string]interface{}) {
+	sc_info := []map[string]interface{}{}
+	jy_info := []map[string]interface{}{}
+	arr := *class.MysqlTool.Find("v_bidclass", nil, "", "", -1, -1)
+	log.Debug(arr)
+	//关联的有product.id 需要生成产品表
+	dataArr := *class.MysqlTool.Find("f_product", map[string]interface{}{
+		"company_name": company_name,
+	}, "id,product_name,approve_date,company_id,medical_equipment_code", "", -1, -1)
+	//dataArr,_ := save_mgo.Find("zktest_mysql_product_info", map[string]interface{}{
+	//	"company_name":company_name,
+	//},nil,nil)
+
+	//是否过滤~信息~根绝名称去重~选取一个有效的信息
+	keys := map[string]map[string]interface{}{}
+	new_dataArr := make([]map[string]interface{}, 0)
+	for _, data := range dataArr {
+		product_name := qu.ObjToString(data["product_name"])
+		if keys[product_name] == nil {
+			new_dataArr = append(new_dataArr, data)
+			keys[product_name] = data
+		} else {
+			pre_v := keys[product_name]
+			pre_approve_date := qu.ObjToString(pre_v["approve_date"])
+			cur_approve_date := qu.ObjToString(data["approve_date"])
+			pre_approve_time, _ := time.Parse(class.TimeTmeplate, pre_approve_date)
+			cur_approve_time, _ := time.Parse(class.TimeTmeplate, cur_approve_date)
+			if cur_approve_time.Unix() > pre_approve_time.Unix() {
+				keys[product_name] = data
+				//替换数据
+				index := 0
+				isreplace := false
+				for k, v := range new_dataArr {
+					if qu.ObjToString(v["product_name"]) == product_name {
+						index = k
+						isreplace = true
+						break
+					}
+				}
+				if isreplace {
+					new_dataArr[index] = data
+				}
+			}
+		}
+	}
+
+	for _, v := range dataArr {
+		dict := map[string]interface{}{}
+		dict["company_id"] = qu.ObjToString(v["company_id"])
+		dict["product_id"] = qu.ObjToString(v["id"])
+		dict["medical_equipment_code"] = qu.ObjToString(v["medical_equipment_code"])
+		if company_type == "1" { //生产
+			sc_info = append(sc_info, dict)
+		} else if company_type == "2" { //经营
+			jy_info = append(jy_info, dict)
+		} else if company_type == "3" { //生产&经营
+			sc_info = append(sc_info, dict)
+			jy_info = append(jy_info, dict)
+		}
+	}
+	return sc_info, jy_info
+}

+ 343 - 0
filedproject_medical/data_preparation/src/hospital/hospital.go

@@ -0,0 +1,343 @@
+package hospital
+
+import (
+	"class"
+	log "github.com/donnie4w/go-logger/logger"
+	qu "qfw/util"
+	"strings"
+	"sync"
+	"time"
+	"unicode/utf8"
+)
+
+var hospitallock sync.Mutex
+var data_hospitals = map[string][]map[string]interface{}{}
+
+//开始执行医院数据
+func RunHospitalInfo() {
+	//医院信息处理
+	dealWithHospitalBaseInfo("f_hospital_39jk", "hospital_39jk_ain_depart")
+	dealWithHospitalBaseInfo("f_hospital_hdf", "hospital_hdf_ain_depart")
+	dealWithHospitalBaseInfo("f_hospital_yydq", "hospital_yydq_ain_depart")
+	dealWithHospitalBaseInfo("f_hospital_yyyc", "")
+	confirmHospitalData("zzzzzzkkkkkk")
+}
+
+//整合医院数据
+func confirmHospitalData(save_coll string) {
+	//处理~医院信息
+	log.Debug("整合医院信息~", len(data_hospitals))
+	for _, v := range data_hospitals {
+		data := mergeHospitalInfo(v)
+		class.Save_Mgo.Save(save_coll, data)
+	}
+	log.Debug("待判重数据存储完毕~")
+	time.Sleep(10 * time.Second)
+	repeatHospital(save_coll)
+}
+
+//判重~医院数据
+func repeatHospital(save_coll string) {
+	log.Debug("开始判重医院数据...")
+	sess := class.Save_Mgo.GetMgoConn()
+	defer class.Save_Mgo.DestoryMongoConn(sess)
+	data_hospitals_alias := make(map[string][]string, 0)
+	data_hospitals_id := make(map[string]string, 0)
+	data_hospitals_region := make(map[string]map[string]string, 0)
+	q := map[string]interface{}{}
+	it := sess.DB(class.Save_Mgo.DbName).C(save_coll).Find(&q).Sort("_id").Select(map[string]interface{}{
+		"name":  1,
+		"alias": 1,
+	}).Iter()
+	total, isok := 0, 0
+	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
+		if total%1000 == 0 {
+			log.Debug("cur index ", total, "~", isok)
+		}
+		region := map[string]string{
+			"area":     qu.ObjToString(tmp["area"]),
+			"city":     qu.ObjToString(tmp["city"]),
+			"district": qu.ObjToString(tmp["district"]),
+		}
+		alias := qu.ObjToString(tmp["alias"])
+		name := qu.ObjToString(tmp["name"])
+		alias_arr := strings.Split(alias, ",")
+		alias_arr = append(alias_arr, name)
+
+		//减少重复...待
+
+		tmpid := class.BsonTOStringId(tmp["_id"])
+		if data_hospitals_alias[name] == nil {
+			//对比名称~
+			is_r := false
+			is_r_n := ""
+			for _, name_new := range alias_arr {
+				if name_new == "" {
+					continue
+				}
+				for k, v := range data_hospitals_alias {
+					//地域不一致~过滤
+					if !repeatRegion(data_hospitals_region[k], region) {
+						continue
+					}
+					for _, v1 := range v {
+						if v1 == "" {
+							continue
+						}
+						if strings.Contains(v1, name_new) || strings.Contains(name_new, v1) {
+							is_r = true
+							is_r_n = k
+							break
+						}
+					}
+					if is_r {
+						break
+					}
+				}
+				if is_r {
+					break
+				}
+			}
+			if is_r {
+				isok++
+				if is_r_n != "" {
+
+				}
+				class.Save_Mgo.UpdateById(save_coll, tmpid, map[string]interface{}{
+					"$set": map[string]interface{}{
+						"repeat":    1,
+						"repeat_id": data_hospitals_id[is_r_n],
+					},
+				})
+			}
+			data_hospitals_id[name] = tmpid
+			data_hospitals_region[name] = region
+			data_hospitals_alias[name] = alias_arr
+		}
+		tmp = make(map[string]interface{})
+	}
+	log.Debug("is over ", total, "~", isok)
+
+	//合并判重后的数据
+	mergeRepeatHospital(save_coll)
+}
+
+//最终合并判重后的医院数据
+func mergeRepeatHospital(save_coll string) {
+	log.Debug("开始合并重复后的数据~待")
+	return
+	sess := class.Save_Mgo.GetMgoConn()
+	defer class.Save_Mgo.DestoryMongoConn(sess)
+	q := map[string]interface{}{}
+	it := sess.DB(class.Save_Mgo.DbName).C(save_coll).Find(&q).Sort("_id").Iter()
+	total, isok := 0, 0
+	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
+		if total%1000 == 0 {
+			log.Debug("cur index ", total, "~", isok)
+		}
+		//最终保存
+
+		tmp = make(map[string]interface{})
+	}
+	log.Debug("is over ", total, "~", isok)
+}
+
+//处理医院基本信息~涉及多张表
+func dealWithHospitalBaseInfo(hos_coll string, depart_coll string) {
+	log.Debug("处理医疗~医院基本信息")
+	sess := class.Save_Mgo.GetMgoConn()
+	defer class.Save_Mgo.DestoryMongoConn(sess)
+	q := map[string]interface{}{}
+	it := sess.DB(class.Save_Mgo.DbName).C(hos_coll).Find(&q).Sort("_id").Iter()
+	pool := make(chan bool, 6)
+	wg := &sync.WaitGroup{}
+	total, isok := 0, 0
+	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
+		if total%10000 == 0 {
+			log.Debug("cur index ", total)
+		}
+		pool <- true
+		wg.Add(1)
+		go func(tmp map[string]interface{}) {
+			defer func() {
+				<-pool
+				wg.Done()
+			}()
+			name := qu.ObjToString(tmp["hospitalname"])
+			if name != "" && utf8.RuneCountInString(name) > 3 {
+				//医院基本信息
+				data_info := treatHospitalInfo(tmp)
+				name = qu.ObjToString(data_info["name"])
+				//科室相关信息
+				hos_id := qu.ObjToString(tmp["_id"])
+				data_depart := treatHospitalDepartment(hos_id, depart_coll)
+				data_info["departs"] = data_depart
+				//别名信息
+				data_info["alias"] = qu.ObjToString(tmp["alias"])
+
+				hospitallock.Lock()
+				if data_hospitals[name] == nil {
+					arr := []map[string]interface{}{data_info}
+					data_hospitals[name] = arr
+					isok++
+				} else {
+					arr := data_hospitals[name]
+					arr = append(arr, data_info)
+					data_hospitals[name] = arr
+				}
+				hospitallock.Unlock()
+			}
+		}(tmp)
+		tmp = make(map[string]interface{})
+	}
+	wg.Wait()
+	log.Debug("is cur over ", len(data_hospitals), "~", total, "~", isok)
+}
+
+//数据构建~医院基本信息
+func treatHospitalInfo(tmp map[string]interface{}) map[string]interface{} {
+	data := map[string]interface{}{}
+	hospitalname := qu.ObjToString(tmp["hospitalname"])
+	hospitalname = strings.ReplaceAll(hospitalname, " ", "")
+	//医院名称~
+	data["name"] = hospitalname
+	//医院简介
+	data["introduce"] = qu.ObjToString(tmp["introduce"])
+
+	//医院地址
+	data["address"] = qu.ObjToString(tmp["address"])
+	//医院设备
+	data["equipment"] = qu.ObjToString(tmp["equipment"])
+	//床位数~
+	beds := qu.IntAll(tmp["beds"])
+	if beds > 0 {
+		data["beds"] = beds
+	}
+	//门诊量/日
+	visit_perday := qu.IntAll(tmp["visit_perday"])
+	if visit_perday > 0 {
+		data["visit_perday"] = visit_perday
+	}
+	//员工人数
+	doctorsnum := qu.IntAll(tmp["doctorsnum"])
+	if doctorsnum > 0 {
+		data["doctorsnum"] = doctorsnum
+	}
+	//联系电话~
+	data["tel"] = qu.ObjToString(tmp["tel"])
+	//传真号码
+	data["fax_number"] = qu.ObjToString(tmp["fax_number"])
+	//医院网站
+	data["website"] = qu.ObjToString(tmp["website"])
+
+	//等级~性质~代码
+	//n_level, n_type, n_bus_type := inquirHospitalLevelType(qu.ObjToString(tmp["level"]), qu.ObjToString(tmp["type"]), qu.ObjToString(tmp["business_type"]))
+	//data["level_code"] = n_level
+	//data["mi_type_code"] = n_type
+	//data["business_type"] = qu.IntAll(n_bus_type)
+	data["level"] = qu.ObjToString(tmp["level"])
+	data["type"] = qu.ObjToString(tmp["type"])
+	data["business_type"] = qu.ObjToString(tmp["business_type"])
+
+	//省~市~区 ~可完善
+	area := qu.ObjToString(tmp["area"])
+	city := qu.ObjToString(tmp["city"])
+	district := qu.ObjToString(tmp["district"])
+	if city == "" { //补充~省份城市信息
+		//supplementRegionally(&area, &city, &district, hospitalname, qu.ObjToString(tmp["address"]))
+	}
+	data["area"] = area
+	data["city"] = city
+	data["district"] = district
+
+	company_id := ""
+	//关联企业信息~查询顺序~企业~特殊~自生
+	//company_id = inquirBaseInfoid(hospitalname)
+	data["company_id"] = company_id
+
+	//入库时间
+	//data["comeintime"] = time.Unix(qu.Int64All(tmp["comeintime"]), 0).Format(timeLayout)
+	//更新时间
+	//data["updatetime"] = time.Unix(qu.Int64All(tmp["updatetime"]), 0).Format(timeLayout)
+
+	return data
+}
+
+//数据构建~医院科室信息
+func treatHospitalDepartment(hos_id string, depart_coll string) []map[string]interface{} {
+	new_arr := []map[string]interface{}{}
+	if depart_coll == "" {
+		return new_arr
+	}
+	dataArr, _ := class.Save_Mgo.Find(depart_coll, map[string]interface{}{"hospital_id": hos_id}, nil, nil)
+	//考虑去重~相同科室
+	keys := map[string]string{}
+	for _, v := range dataArr {
+		main_departclass1 := qu.ObjToString(v["main_departclass1"])
+		main_departclass2 := qu.ObjToString(v["main_departclass2"])
+		key := main_departclass1 + "~" + main_departclass2
+		if keys[key] == "" {
+			new_arr = append(new_arr, map[string]interface{}{
+				"departclass1": main_departclass1,
+				"departclass2": main_departclass2,
+			})
+			keys[key] = key
+		} else {
+			//log.Debug("重复科室~",main_departclass1,main_departclass2)
+		}
+	}
+	return new_arr
+}
+
+//合并医院信息~
+func mergeHospitalInfo(dataArr []map[string]interface{}) map[string]interface{} {
+	data := map[string]interface{}{}
+	if len(dataArr) == 1 {
+		return dataArr[0]
+	} else if len(dataArr) > 1 {
+		//合并重复信息
+		temp := dataArr[0]
+		for k, v := range temp {
+			isMerge := false
+			//合并别名~
+
+			//合并科室信息
+
+			//选取最优值
+			if new_v, ok := v.(string); ok {
+				if new_v == "" { //查询其他数据~补充
+					for ks, vs := range dataArr {
+						if ks == 0 {
+							continue
+						}
+						if qu.ObjToString(vs[k]) != "" {
+							data[k] = vs[k]
+							isMerge = true
+							break
+						}
+					}
+				}
+			}
+			if new_v, ok := v.(int); ok {
+				if new_v == 0 { //查询其他数据~补充
+					for ks, vs := range dataArr {
+						if ks == 0 {
+							continue
+						}
+						if qu.IntAll(vs[k]) > 0 {
+							data[k] = vs[k]
+							isMerge = true
+							break
+						}
+					}
+				}
+			}
+			if !isMerge {
+				data[k] = v
+			}
+		}
+	} else {
+
+	}
+	return data
+}

+ 201 - 0
filedproject_medical/data_preparation/src/hospital/hospital_method.go

@@ -0,0 +1,201 @@
+package hospital
+
+import (
+	"class"
+	"encoding/json"
+	log "github.com/donnie4w/go-logger/logger"
+	"io/ioutil"
+	"net/http"
+	qu "qfw/util"
+	"regexp"
+	"strings"
+)
+
+var med_lev_Reg1 = regexp.MustCompile("^([一二三])([甲乙丙特])$")
+var med_lev_Reg2 = regexp.MustCompile("^([一二三])(级)(医院)?$")
+
+//类型 等级 性质  ~ 综合清洗分析验证
+func inquirHospitalLevelType(med_level string, med_type string, med_bus_type string) (string, string, string) {
+	new_level, new_type, new_bus_type := "", "", ""
+	//医疗性质相关
+	if med_bus_type != "" {
+		new_bus_type = relevanceBusType(med_bus_type)
+		//针对~类型划分
+		arr := strings.Split(med_bus_type, "/")
+		if len(arr) == 2 {
+			new_type = relevanceType(arr[1])
+		}
+	}
+	//医疗等级相关
+	if med_level != "" {
+		new_level = relevanceLevel(med_level)
+		//针对~性质划分
+		new_bus_type = relevanceBusType(med_bus_type)
+	}
+
+	//医疗类型相关~采集异常~需要清洗
+	if med_type != "" && new_type == "" {
+
+		//医疗类型
+		new_type = relevanceType(med_type)
+
+		if new_level == "" {
+			new_level = relevanceLevel(new_type)
+		}
+		if new_bus_type == "" {
+			new_bus_type = relevanceBusType(new_type)
+		}
+	}
+
+	//最终核对
+	if new_level == "" {
+		new_level = class.Medical_level["其它"]
+	}
+	if new_type == "" {
+		new_type = class.Medical_type["其它"]
+		log.Debug(new_type)
+	}
+	if new_bus_type == "" {
+		new_bus_type = "2"
+	}
+	return new_level, new_type, new_bus_type
+}
+
+// level 医疗等级对比
+func relevanceLevel(med_level string) string {
+	new_level := ""
+	if class.Medical_level[med_level] != "" {
+		new_level = class.Medical_level[med_level]
+	} else { //特殊描述映射关系
+		if med_lev_Reg1.MatchString(med_level) {
+			med_level = med_lev_Reg1.ReplaceAllString(med_level, "${1}级${2}等")
+			new_level = class.Medical_level[med_level]
+		}
+		if med_lev_Reg2.MatchString(med_level) {
+			med_level = med_lev_Reg2.ReplaceAllString(med_level, "${1}${2}其它")
+			new_level = class.Medical_level[med_level]
+		}
+	}
+	return new_level
+}
+
+//type 类型划分
+func relevanceType(med_type string) string {
+	new_type := ""
+	//扩展~包含关系~等等规则
+	new_type = class.Medical_type[med_type]
+	return new_type
+}
+
+//bus_type 性质划分
+func relevanceBusType(med_bus_type string) string {
+	new_bus_type := ""
+	//0公立、1民营、2其它
+	if strings.Contains(med_bus_type, "公立") {
+		new_bus_type = "0"
+	}
+	if strings.Contains(med_bus_type, "民营") {
+		new_bus_type = "1"
+	}
+	return new_bus_type
+}
+
+//查询企业id
+func inquirBaseInfoid(name string) (company_id string) {
+	company_id = ""
+	query := map[string]interface{}{
+		"company_name": name,
+	}
+	data_base := class.Spi_Mgo.FindOne("company_base", query)
+	if data_base != nil && len(data_base) > 2 {
+		company_id = qu.ObjToString(data_base["company_id"])
+	} else {
+		data_spec := class.Spi_Mgo.FindOne("special_enterprise", query)
+		if data_spec != nil && len(data_spec) > 2 {
+			company_id = qu.ObjToString(data_spec["company_id"])
+		}
+	}
+	return
+}
+
+//补充~地域区划
+func supplementRegionally(area *string, city *string, district *string, name string, address string) {
+	//查询其他表~
+	if *area == "" || *area == "全国" {
+		*area = "全国"
+		*city = ""
+		*district = ""
+	}
+	data := class.Save_Mgo.FindOne("data_info", map[string]interface{}{
+		"name": name,
+	})
+	if data != nil && len(data) > 2 {
+		data_area := qu.ObjToString(data["area"])
+		data_city := qu.ObjToString(data["city"])
+		data_district := qu.ObjToString(data["district"])
+		if data_district != "" {
+			*area = data_area
+			*city = data_city
+			*district = data_district
+		} else {
+			if data_city != "" {
+				*area = data_area
+				*city = data_city
+			} else {
+				if data_area != "" && data_area != "全国" {
+					*area = data_area
+				}
+			}
+		}
+	}
+	if *city != "" {
+		return
+	}
+
+	//地址字段抽取~请求接口
+	resp, err := http.Get("http://extcity.spdata.jianyu360.com/getcity?detail=" + address)
+	if err == nil {
+		defer resp.Body.Close()
+		bs, _ := ioutil.ReadAll(resp.Body)
+		var rep map[string]interface{}
+		json.Unmarshal(bs, &rep)
+
+		rep_area := qu.ObjToString(rep["area"])
+		rep_city := qu.ObjToString(rep["city"])
+		rep_district := qu.ObjToString(rep["district"])
+
+		if rep_district != "" {
+			*area = rep_area
+			*city = rep_city
+			*district = rep_district
+		} else {
+			if rep_city != "" {
+				*area = rep_area
+				*city = rep_city
+			} else {
+				if rep_area != "" && rep_area != "全国" {
+					*area = rep_area
+				}
+			}
+		}
+	}
+}
+
+//是否相同地域
+func repeatRegion(region map[string]string, data map[string]string) bool {
+	if region["district"] != "" && data["district"] != "" &&
+		region["district"] != data["district"] {
+		return false
+	}
+	if region["city"] != "" && data["city"] != "" &&
+		region["city"] != data["city"] {
+		return false
+	}
+	if region["area"] != "" && data["area"] != "" &&
+		region["area"] != data["area"] &&
+		region["area"] != "全国" && data["area"] != "全国" {
+		return false
+	}
+
+	return true
+}

+ 31 - 0
filedproject_medical/data_preparation/src/main.go

@@ -0,0 +1,31 @@
+package main
+
+import (
+	"class"
+	"flag"
+	log "github.com/donnie4w/go-logger/logger"
+	"net/http"
+	"time"
+)
+
+func init() {
+	class.InitClass()
+}
+func main() {
+	log.Debug("领域化产品准备......")
+
+	//具体数据处理
+
+	time.Sleep(999 * time.Hour)
+}
+
+//暂不使用~
+func testPort() {
+	var port, path string
+	flag.StringVar(&port, "port", "8188", "端口")
+	flag.StringVar(&path, "path", "/", "路径")
+	flag.Parse()
+	http.Handle("/", http.FileServer(http.Dir(path)))
+	log.Debug("port:", port)
+	http.ListenAndServe(":"+port, nil)
+}

+ 113 - 0
filedproject_medical/data_preparation/src/product/product.go

@@ -0,0 +1,113 @@
+package product
+
+import (
+	"class"
+	log "github.com/donnie4w/go-logger/logger"
+	qu "qfw/util"
+	"strings"
+	"sync"
+)
+
+var productlock sync.Mutex
+
+//开始处理医疗产品信息
+func RunMedicalProductInfo() {
+	dealWithMedicalProductInfo()
+}
+
+//处理产品信息~
+func dealWithMedicalProductInfo() {
+	sess := class.Save_Mgo.GetMgoConn()
+	defer class.Save_Mgo.DestoryMongoConn(sess)
+	q := map[string]interface{}{}
+	it := sess.DB(class.Save_Mgo.DbName).C("zktest_mysql_product_info").Find(&q).Sort("_id").Iter()
+	pool := make(chan bool, 5)
+	wg := &sync.WaitGroup{}
+	total, isok := 0, 0
+	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
+		if total%10000 == 0 {
+			log.Debug("cur index ", total, isok)
+		}
+		pool <- true
+		wg.Add(1)
+		go func(tmp map[string]interface{}) {
+			defer func() {
+				<-pool
+				wg.Done()
+			}()
+
+			data := treatProductInfo(tmp)
+			if data != nil {
+				productlock.Lock()
+				isok++
+				productlock.Unlock()
+			}
+		}(tmp)
+		tmp = make(map[string]interface{})
+	}
+	wg.Wait()
+
+	log.Debug("is over ", total, isok)
+
+}
+
+//构建产品信息数据~
+func treatProductInfo(tmp map[string]interface{}) map[string]interface{} {
+	data := map[string]interface{}{}
+	data["regno"] = qu.ObjToString(tmp["regno"])
+	data["company_name"] = qu.ObjToString(tmp["company_name"])
+	data["company_address"] = qu.ObjToString(tmp["company_address"])
+	data["make_adress"] = qu.ObjToString(tmp["make_adress"])
+	data["make_country"] = qu.ObjToString(tmp["make_country"])
+	data["agent_name"] = qu.ObjToString(tmp["agent_name"])
+	data["agent_address"] = qu.ObjToString(tmp["agent_address"])
+	data["model"] = qu.ObjToString(tmp["model"])
+	data["main_part"] = qu.ObjToString(tmp["main_part"])
+	data["product_descrip"] = qu.ObjToString(tmp["product_descrip"])
+	data["use_scope"] = qu.ObjToString(tmp["use_scope"])
+	data["storage_conditions"] = qu.ObjToString(tmp["storage_conditions"])
+	data["remark"] = qu.ObjToString(tmp["remark"])
+	data["approve_depart"] = qu.ObjToString(tmp["approve_depart"])
+
+	//日期清洗
+	approve_date := qu.ObjToString(tmp["approve_date"])
+	validity_date := qu.ObjToString(tmp["validity_date"])
+	if !cleanErrDateTime(approve_date) {
+		data["approve_date"] = approve_date
+	}
+	if !cleanErrDateTime(validity_date) {
+		data["validity_date"] = validity_date
+	}
+
+	data["changes"] = qu.ObjToString(tmp["changes"])
+	data["regist_type"] = qu.ObjToString(tmp["regist_type"])
+	data["source_channel"] = qu.ObjToString(tmp["source_channel"])
+	data["manage_type"] = qu.ObjToString(tmp["manage_type"])
+	data["product_name"] = qu.ObjToString(tmp["product_name"])
+
+	data["medical_equipment_class1"] = qu.ObjToString(tmp["product_class1"])
+	data["medical_equipment_class2"] = qu.ObjToString(tmp["product_class2"])
+	data["medical_equipment_class3"] = qu.ObjToString(tmp["product_class3"])
+	data["sdproduct_name"] = qu.ObjToString(tmp["product_class4"])
+
+	//需要清洗
+	data["medical_equipment_code"] = qu.ObjToString(tmp["product_code"])
+	data["Isvalid"] = true
+
+	return data
+}
+
+//清洗日期~
+func cleanErrDateTime(datetime string) bool {
+	/*
+		1、有效年1900 ~  2200年
+	*/
+	arr := strings.Split(datetime, "-")
+	if len(arr) > 0 {
+		year := qu.IntAll(arr[0])
+		if year < 1900 || year > 2200 {
+			return true
+		}
+	}
+	return false
+}

+ 96 - 0
filedproject_medical/data_preparation/src/repair/repairclass.go

@@ -0,0 +1,96 @@
+package repair
+
+import (
+	"class"
+	log "github.com/donnie4w/go-logger/logger"
+	qu "qfw/util"
+	"unicode/utf8"
+)
+
+//修复产品分类表
+func repairProductClass() {
+	sess := class.Save_Mgo.GetMgoConn()
+	defer class.Save_Mgo.DestoryMongoConn(sess)
+	q := map[string]interface{}{}
+	it := sess.DB(class.Save_Mgo.DbName).C("zktest_mysql_product_info").Find(&q).Select(map[string]interface{}{
+		"product_code": 1,
+	}).Sort("_id").Iter()
+	total := 0
+	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
+		if total%10000 == 0 {
+			log.Debug("cur index ", total)
+		}
+		product_code := qu.ObjToString(tmp["product_code"])
+		if utf8.RuneCountInString(product_code) == 8 || utf8.RuneCountInString(product_code) == 14 {
+			new_code := updatecode(product_code)
+			if new_code == "" {
+				log.Debug("异常~~~~", tmp["_id"])
+			}
+			class.Save_Mgo.UpdateById("zktest_mysql_product_info", class.BsonTOStringId(tmp["_id"]), map[string]interface{}{
+				"$set": map[string]interface{}{
+					"product_code": new_code,
+				},
+			})
+		}
+
+		tmp = make(map[string]interface{})
+	}
+
+	log.Debug("is over ", total)
+}
+
+//修复医疗器械v表
+func repairYlqxClass() {
+	sess := class.Save_Mgo.GetMgoConn()
+	defer class.Save_Mgo.DestoryMongoConn(sess)
+	q := map[string]interface{}{}
+	it := sess.DB(class.Save_Mgo.DbName).C("zktest_mysql_ylqxclass").Find(&q).Sort("_id").Iter()
+	total := 0
+
+	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
+		if total%1000 == 0 {
+			log.Debug("cur index ", total)
+		}
+		code := qu.ObjToString(tmp["code"])
+		pcode := qu.ObjToString(tmp["pcode"])
+		level := qu.ObjToString(tmp["level"])
+		if level == "3" { //调整code
+			new_code := updatecode(code)
+			class.Save_Mgo.UpdateById("zktest_mysql_ylqxclass", class.BsonTOStringId(tmp["_id"]), map[string]interface{}{
+				"$set": map[string]interface{}{
+					"code": new_code,
+				},
+			})
+		} else if level == "4" { //调整code pcode
+			new_code := updatecode(code)
+			new_pcode := updatecode(pcode)
+			class.Save_Mgo.UpdateById("zktest_mysql_ylqxclass", class.BsonTOStringId(tmp["_id"]), map[string]interface{}{
+				"$set": map[string]interface{}{
+					"code":  new_code,
+					"pcode": new_pcode,
+				},
+			})
+		} else {
+
+		}
+
+		tmp = make(map[string]interface{})
+	}
+
+	log.Debug("is over ", total)
+
+}
+
+//更新code表
+func updatecode(code string) string {
+	rc := []rune(code)
+	new_code := code
+	if len(rc) == 8 {
+		new_code = string(rc[:4]) + string(rc[5:8])
+	}
+	if len(code) == 14 {
+		new_code = string(rc[:4]) + string(rc[5:8]) + string(rc[10:14])
+	}
+
+	return new_code
+}