一、angular
1、总目录
2、代码
chat.comment.html
<div class="chatroom">
<div class="chathello">
Pagge聊天室
<button>
<a [routerLink]="['/friends', userid]">返回</a>
</button>
<div style="float: right;margin: 5px;color: rgb(162, 165, 47);">{{friename}}</div>
</div>
<div class="p_detial" id="autore">
<div class="p_content" *ngFor="let users of messagelist ">
{{ judge(users.sid ) }} {{users.time}}
<br> {{ users.message }}
<br>
<div *ngIf="users.imgid!=0">
<img [(src)]="imgurl[users.imgid] " >
</div>
<!-- <div [innerHTML]="userreceiveimg(users.imgid)"></div> -->
<!-- <br> {{userreceiveimg(users.imgid)}} -->
<hr>
</div>
</div>
<div>
<textarea class="yourwrite" placeholder="输入你的文字" [(ngModel)]="textm" ></textarea>
<input type="file" class="yourpicture" id="newUpload" (change)="getUpload($event)" >
<h6>*仅接受图片文件</h6>
<button class="yoursent" (click)="usersendmessage()">发送</button>
</div>
</div>
chat.comment.scss
.chatroom{
width: 440px;
height: 550px;
margin: 100px auto;
background-color: #ffffff42;
padding: 15px;
border: 1px solid #0066da;
}
.chathello{
width: 430px;
height: 28px;
padding: 8px;
border: 0px solid #0066daa6;
button{
width: 65px;
height: 30px;
float: right;
}
img{
width: 50px;
height: 30px;
margin: 0px 34px 0px 0px;
float: right;
}
}
.p_detial{
width: 440px;
height: 300px;
background-color: #f0f6ff;
padding: 0px;
margin: 0px;
border: 0px solid #0066da61;
float: left;
overflow: scroll;
overflow-x: hidden;
img{
width: 100px;
height: 60px;
margin: 0px 34px 0px 0px;
float: center;
}
}
.yourwrite{
width: 435px;
height: 100px;
margin: 5px 0px 0px 0px;
overflow: scroll;
overflow-x: hidden;
}
.yourpicture{
width: 430px;
height: 24px;
border: 5px solid #dee2e661;
}
.yoursent{
margin: 0px 15px 10px 364px;
width: 63px;
height: 40px;
}
h6{
margin: 0px 0px 0px 0px;
}
chat.comment.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CommonService } from '../../services/common.service';
import { flushMicrotasks } from '@angular/core/testing';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.scss']
})
export class ChatComponent implements OnInit {
// public domain:string='';
// public list:any[]=[];
constructor(public sanitizer: DomSanitizer,
public route:ActivatedRoute,
public common:CommonService ) {
// this.domain=this.common.domain;
}
public userid :any
public frieid :any
public friename :any=""
ngOnInit() {
this.route.params.subscribe((value:any)=>{
this.userid = value.userid
this.frieid = value.frieid
this.friename = value.friename
this.userreceiveMessage(this.userid, this.frieid)
})
}
public messagelist:any[]=[];
userreceiveMessage(uid, fid){
this.common.receive(uid, fid).then((Response:any)=>{
console.log(Response);
if(Response.status==-1){
alert("获取消息列表失败")
return
}
this.messagelist = Response.messageList
this.userreceiveimg()
})
return
}
judge(sid){
if ( sid== this.userid){
return "我"
}else{
return this.friename
}
}
public imgurl :any[]=[]
userreceiveimg(){
this.imgurl[0]=""
var n:any = this.messagelist.length;
for(var i =0; i<n; i++){
var id:any =this.messagelist[i].imgid
if(id==0){
continue
}
this.createimgurl(id)
}
console.log(this.imgurl)
}
createimgurl(id){
this.common.receiveimg(id).then((Response:any)=>{
// this.createImageFromBlob(Response);
console.log( Response);
let reader = new FileReader();
reader.readAsDataURL(Response);
reader.onload = () => {
var fileBase64 = <string>reader.result //读取该文件base64编码
// var url = "data:image/jpeg;base64,"+fileBase64
// var url = fileBase64
this.imgurl[id] = this.sanitizer.bypassSecurityTrustResourceUrl(fileBase64);
}
})
}
public textm :any=""
public imgm :any
public imageid:any
public getUpload(e) {
if (e.target.files[0]) {
this.imgm = e.target.files[0];
}
}
usersendmessage(){
// var files = $('#images').prop('files');
// console.log(files);
// var data = new FormData();
// data.append('image',this.imgm);
console.log( this.imgm)
if( this.imgm ){
this.common.sendimg(this.imgm).then((Response:any)=>{
console.log(Response);
// var list = Object.assign([], Response);
// console.log("list :"+list);
if(Response.stauts==-1){
alert("发送图片失败 "+ Response.msg)
return
}
this.imageid = Response.id+""
// var imid :String = Response.id
// console.log("imgid: "+ this.imageid);
console.log("imgid: "+ this.imageid);
console.log(typeof this.imageid);
this.common.send(this.userid, this.frieid, this.textm, this.imageid).then((Response:any)=>{
console.log(Response);
if(Response.status==-1){
alert("发送消息失败")
}
})
})
}else{
this.imageid="0"
console.log("textm: "+ this.textm);
console.log("imgid: "+ this.imageid);
this.common.send(this.userid, this.frieid, this.textm, this.imageid).then((Response:any)=>{
console.log(Response)
if(Response.status==-1){
alert("发送消息失败:"+Response.msg)
}
})
}
window.location.reload()
return
}
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule,HttpClientJsonpModule } from '@angular/common/http';
import { CommonService } from './services/common.service';
import { FormsModule } from '@angular/forms';
import {RouterModule} from '@angular/router';
import { CookieService } from 'ngx-cookie-service';
// import {ChangeDetectionStrategy } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UserloginComponent } from './components/userlogin/userlogin.component';
import { UserregisterComponent } from './components/userregister/userregister.component';
import { ChatComponent } from './components/chat/chat.component';
import { FriendsComponent } from './components/friends/friends.component';
import { ManageComponent } from './components/manage/manage.component';
@NgModule({
declarations: [
AppComponent,
UserloginComponent,
UserregisterComponent,
ChatComponent,
FriendsComponent,
ManageComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
HttpClientJsonpModule,
FormsModule,
RouterModule,
],
providers: [
CookieService,
CommonService
],
bootstrap: [AppComponent]
})
export class AppModule { }
comment.service.ts
import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders} from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class CommonService {
constructor(public http:HttpClient) { }
// get(api){
// return new Promise((resolve,reject)=>{
// this.http.get(this.domain+api).subscribe((response)=>{
// resolve(response);
// });
// })
// }
public domain:string='http://localhost:8888';
register(name, phone, mail, pw){
var url =this.domain+"/register"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
username: name,
userphone: phone,
usermail: mail,
password: pw
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
login(info, pw){
var url =this.domain+"/login"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
useraccount: info,
password: pw
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
show(id){
var url =this.domain+"/show"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
userid: id
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
check(id){
var url =this.domain+"/check"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
userid: id
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
receive(uid, fid){
var url =this.domain+"/receive"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
userid :uid,
userfriendid :fid
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
receiveimg(id){
var url =this.domain+"/sendimg?id="+id
console.log(url)
return new Promise((resolve,reject)=>{
this.http.get(url, { responseType: 'blob' }).subscribe((response)=>{
resolve(response);
});
})
}
// receiveimg(id) {
// var url =this.domain+"/sendimg?id="+id
// console.log(url)
// return this.http.get(url, { responseType: 'blob' });
// }
send(ssid, rrid, mes, mid){
var url =this.domain+"/send"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
sid: ssid,
rid: rrid,
message: mes,
imgid : mid
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
sendimg(img){
var url =this.domain+"/receiveimg"
// const headers = new HttpHeaders({'Content-Type': 'multipart/form-data'});
const headers = new HttpHeaders();
let im = new FormData();
im.append("Image", img);
// 获取 window 的 URL 工具
// var URL = window.URL || window.webkitURL;
// var URL = window.URL;
// 通过 file 生成目标 url
// var imgURL = URL.createObjectURL(img);
// let im = {
// Image: img
// };
return new Promise((resolve,reject)=>{
console.log(im)
this.http.post(url, im, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
delete(id){
var url =this.domain+"/delete"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
userfriendid: id,
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
update(name, phone, mail, pw, id){
var url =this.domain+"/update"
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
let data = {
username:name,
userphone:phone,
usermail:mail,
password:pw,
userfriendid: id,
};
return new Promise((resolve,reject)=>{
this.http.post(url, data, {headers: headers}).subscribe((response)=>{
resolve(response);
});
})
}
}
3、运行效果
4、bug
本页面轮询功能未完成,暂时用window.location.reload()
代替,会出现发送失败的bug
二、golang
1、总目录
(数据库为 postgresql)
2、代码
receivesendingimg.go
package servewr
import (
"bufio"
"bytes"
// "crypto/md5"
// "database/sql"
// "encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
// "log"
"net/http"
"net/url"
"os"
"strconv"
"../dbtable"
// _ "github.com/lib/pq"
)
//RespProto 接口响应协议
type RespProto struct {
ID int `json:"id"`
Status int `json:"status"`
Message string `json:"message"`
}
// ReceiveImg 接收图片数据,并返回图片id,接受post
func ReceiveImg(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域
w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
w.Header().Set("content-type", "application/json") //返回数据格式是json
r.ParseMultipartForm(32 << 20)
file, handler, err := r.FormFile("Image")
// file, handler, err := r.File("Image")
if err != nil {
fmt.Println(err)
sendErrToClient(err.Error(), w)
return
}
defer file.Close()
file1 := file
imgBytes := make([]byte, handler.Size)
bufr := bufio.NewReader(file1)
_, err = bufr.Read(imgBytes)
if err != nil {
fmt.Println(err)
sendErrToClient(err.Error(), w)
return
}
MD5 := dbtable.Calmd5(imgBytes)
if MD5 == "" {
fmt.Println(fmt.Errorf("图片的md5获取失败"))
sendErrToClient("图片的md5获取失败", w)
return
}
var response RespProto
// 检索数据库,查看是否有相同的md5的数据
fileid, res := dbtable.CheckRepeat(MD5) // true代表该图片以存在
if res {
response.ID = fileid
response.Message = "repeat and success "
result, err := json.Marshal(response)
if err != nil {
fmt.Println(err)
sendErrToClient(err.Error(), w)
return
}
w.Write(result)
return
}
// 将图片存入服务器
filename := MD5 + ".png"
filePath := "././images/" + filename
f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666) //打开文件
if err != nil {
fmt.Println(err)
sendErrToClient(err.Error(), w)
return
}
defer f.Close()
io.Copy(f, bytes.NewReader(imgBytes))
// 将图片相关信息存入数据库
dbtable.InsertData(filename, filePath, MD5)
id, res := dbtable.CheckRepeat(MD5) // true代表已经存在
if !res {
fmt.Println(errors.New("存入数据库中的数据的数据id获取不成功"))
sendErrToClient("存入数据库中的数据的数据id获取不成功", w)
return
}
response.ID = id
response.Status = 0
response.Message = "success"
result, err := json.Marshal(response)
if err != nil {
fmt.Println(err)
sendErrToClient(err.Error(), w)
return
}
w.Write(result)
}
// SendImg 接收图片id,返回相应图片,接受get
func SendImg(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域
u := r.URL
m, err := url.ParseQuery(u.RawQuery)
if err != nil {
fmt.Println(err)
// sendErrToClient(err.Error(), w)
return
}
id, err := strconv.Atoi(m["id"][0])
if err != nil {
fmt.Println(err)
// sendErrToClient(err.Error(), w)
return
}
if id == 0 {
// sendErrToClient("该消息没有图片", w)
return
}
filePath := dbtable.GetFilePath(id)
imgBytes := dbtable.ReadFile(filePath)
// log.Printf("imgbytes:"+string(imgBytes))
w.Write(imgBytes)
}
sendreceive.go
package servewr
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
// 使用相对路径引用dbtable
"../dbtable"
)
// SendResp send接口的响应
type SendResp struct {
Status int `json:"status"`
}
// Send 发送接口的处理函数
func Send(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") // 允许访问所有域
w.Header().Add("Access-Control-Allow-Headers", "Content-TypeAuthorization") // header的类型
w.Header().Set("content-type", "application/json")
// 只处理POST请求
if r.Method != "POST" {
return
}
resp := &SendResp{
Status: 0,
}
// 读取请求实体中的数据
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Printf("read http request failed, err:%v", err)
sendErrToClient(err.Error(), w)
return
}
if body == nil || len(body) == 0 {
log.Println("http request body is null")
sendErrToClient("http request body is null", w)
return
}
defer r.Body.Close()
data := make(map[string]interface{})
// json反序列化请求实体中的数据
if err = json.Unmarshal(body, &data); err != nil {
log.Printf("json unmarshal failed, err:%v", err)
sendErrToClient(err.Error(), w)
return
}
// 类型断言
sid, ok := data["sid"].(string)
if !ok {
log.Printf("type assert failed")
sendErrToClient("type assert failed", w)
return
}
rid, ok := data["rid"].(string)
if !ok {
log.Println("type assert failed")
sendErrToClient("type assert failed", w)
return
}
imgid, ok := data["imgid"].(string)
if !ok {
log.Println("type assert failed")
sendErrToClient("type assert failed", w)
return
}
message, ok := data["message"].(string)
if !ok {
log.Println("type assertion failed")
sendErrToClient("type assertion failed", w)
return
}
if message == ""&&imgid=="0" {
log.Println("the message is empty string")
sendErrToClient("the message is empty string", w)
return
}
fmt.Printf("sid: %s \nrid: %s \nmessage: %s\n", sid, rid, message)
// 把消息的发送者和接收者以及消息的内容存储到数据库
err = dbtable.AddMessage(sid, rid, message, imgid)
if err!=nil{
log.Println(err)
x := fmt.Sprintf("%s", err)
sendErrToClient(x, w)
return
}
// 设置成功的状态码
resp.Status = 0
// 将响应的数据json序列化
respByte, err := json.Marshal(resp)
if err != nil {
log.Printf("json marshal failed, err:%v", err)
sendErrToClient(err.Error(), w)
return
}
// 响应数据
_, err = w.Write(respByte)
if err != nil {
log.Printf("write the response failed, err:%v", err)
sendErrToClient(err.Error(), w)
return
}
return
}
// ReceiveResp receive接口的响应
type ReceiveResp struct {
Status int `json:"status"`
MessageList []dbtable.MessageList `json:"messageList"` // 消息列表
}
// Receive 接收消息接口的处理函数
func Receive(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域
w.Header().Add("Access-Control-Allow-Headers", "Content-TypeAuthorization") //header的类型
w.Header().Set("content-type", "application/json")
resp := ReceiveResp{}
// 读取请求实体中的数据
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Printf("read http request failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
if body == nil || len(body) == 0 {
log.Println("http request body is null")
sendErrToClient("http request body is null", w)
return
}
defer r.Body.Close()
data := make(map[string]interface{})
// json反序列化请求实体中的数据
if err = json.Unmarshal(body, &data); err != nil {
log.Printf("json unmarshal failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
if data == nil {
log.Println("json unmarshal data is null")
sendErrToClient("json unmarshal data is null", w)
return
}
// 类型断言
userid, ok := data["userid"].(string)
if !ok {
log.Println("type assert failed")
sendErrToClient("type assert failed", w)
return
}
if userid == "" {
log.Println("the userid from http request is empty string")
sendErrToClient("the userid from http request is empty string", w)
return
}
userfriendid, ok := data["userfriendid"].(string)
if !ok {
log.Println("type assert failed")
sendErrToClient("type assert failed", w)
return
}
if userfriendid == "" {
log.Println("the userfriendid from http request is empty string")
sendErrToClient("the userfriendid from http request is empty string", w)
return
}
// 根据id从数据库读取消息列表
messageList, err := dbtable.GetMessageList(userid, userfriendid)
if err != nil {
log.Printf("get message list failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
resp.Status = 0
resp.MessageList = messageList
for _, v := range messageList {
fmt.Printf("发送方: %s, 接受方:%s , message: %s , time:%s, imgid:%s\n", v.Sid, v.Rid, v.Message, v.Time, v.Imgid)
}
// json序列化receive接口的响应
respByte, err := json.Marshal(resp)
if err != nil {
log.Printf("json marshal failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
// 响应数据
_, err = w.Write(respByte)
if err != nil {
log.Printf("write response failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
}
// CheckResp Check接口的响应
type CheckResp struct {
Status int `json:"status"` // 响应的状态码
Num int `json:"num"` // 用户的id
}
//Check 检查未读消息接口处理函数
func Check(w http.ResponseWriter, r *http.Request){
w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域
w.Header().Add("Access-Control-Allow-Headers", "Content-TypeAuthorization") //header的类型
w.Header().Set("content-type", "application/json")
// 只处理POST请求
if r.Method != "POST" {
return
}
resp := &CheckResp{
Status: 0,
Num: 0,
}
// 读取请求实体中的数据
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Printf("read http request failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
if body == nil || len(body) == 0 {
log.Println("http request body is null")
sendErrToClient("http request body is null", w)
return
}
defer r.Body.Close()
data := make(map[string]interface{})
// json反序列化请求实体中的数据
if err = json.Unmarshal(body, &data); err != nil {
log.Printf("json unmarshal failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
if data == nil {
log.Println("json unmarshal data is null")
sendErrToClient("json unmarshal data is null", w)
return
}
// 类型断言
userid, ok := data["userid"].(string)
if !ok {
log.Println("type assert failed")
sendErrToClient("type assert failed", w)
return
}
if userid == "" {
log.Println("the userid from http request is empty string")
sendErrToClient("the userid from http request is empty string", w)
return
}
// 根据id从数据库读取消息列表
number, err := dbtable.CheckUnreadMessage(userid)
if err != nil {
log.Printf("check message list failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
resp.Status = 0
resp.Num = number
fmt.Printf( "用户: %s 未读消息条数:% v\n", userid, number)
// json序列化receive接口的响应
respByte, err := json.Marshal(resp)
if err != nil {
log.Printf("json marshal failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
// 响应数据
_, err = w.Write(respByte)
if err != nil {
log.Printf("write response failed, err: %v", err)
sendErrToClient(err.Error(), w)
return
}
}
initDB.go
package dbtable
import (
// "crypto/md5"
"database/sql"
// "encoding/hex"
// "errors"
"fmt"
"log"
"os"
// postgres 驱动
_ "github.com/lib/pq"
)
//全局变量,数据库实例
var db *sql.DB
//数据库连接配置
const (
host = "localhost"
port = 5432
user = "postgres"
password = "postgres"
dbname = "postgres"
)
// Initdb 初始化连接数据库
func Initdb() (err error) {
//打开数据库
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
db, err = sql.Open("postgres", psqlInfo)
if err != nil {
log.Printf("初始化数据库失败, err: %v\n", err)
return
}
err = db.Ping()
if err != nil {
log.Printf("连接数据库失败, err: %v\n", err)
return
}
err = CreateUserTable()
if err != nil {
log.Printf("创建用户表失败, err: %v\n", err)
return
}
err = CreatOfflineMessageTable()
if err != nil {
log.Printf("创建消息表失败, err: %v\n", err)
return
}
err = CreatUserFriendListTable()
if err != nil {
log.Printf("创建好友表失败, err: %v\n", err)
return
}
err = CreatImginfoTable()
if err != nil {
log.Printf("创建图片表失败, err: %v\n", err)
return
}
fmt.Println("数据库连接成功!!")
return
}
//InitDir 创建文件夹
func InitDir() (err error) {
dir := "././images"
exist, err := PathExists(dir)
if err != nil {
fmt.Println(err)
return
}
if exist {
fmt.Printf("![%v] has been existed\n", dir)
} else {
err := os.Mkdir(dir, os.ModePerm)
if err != nil {
log.Fatal(fmt.Sprintf("mkdir failed![%v]\n", err))
} else {
fmt.Printf("mkdir success!\n")
}
}
return nil
}
// CreateUserTable 创建用户表
func CreateUserTable() (err error) {
// //如果表存在, 先删除表
// statement := `DROP TABLE IF EXISTS myusers;`
// _, err = db.Exec(statement)
// if err != nil {
// log.Printf("drop table myusers failed, err: %v", err)
// return
// }
// CREATE TABLE IF NOT EXISTS `db_database_user` (SQL)
statement := `CREATE TABLE IF NOT EXISTS myusers (
id VARCHAR(64) NOT NULL,
username VARCHAR(64) NOT NULL,
userphone VARCHAR(64) NOT NULL,
usermail VARCHAR(64) NOT NULL,
password VARCHAR(64) NOT NULL
);`
_, err = db.Exec(statement)
if err != nil {
// log.Printf("create user table failed, err: %v", err)
return
}
return
}
// CreatOfflineMessageTable 创建数据库离线消息表
func CreatOfflineMessageTable() (err error) {
//如果表存在, 先删除表
// statement := `DROP TABLE IF EXISTS offlinemessage;`
// _, err = db.Exec(statement)
// if err != nil {
// log.Printf("drop table offlinemessage failed, err: %v", err)
// return
// }
statement := `CREATE TABLE IF NOT EXISTS offlinemessage (
id serial NOT NULL primary key,
sid VARCHAR(64) NOT NULL,
rid VARCHAR(64) NOT NULL,
imgid INT NOT NULL,
message VARCHAR(64) NULL DEFAULT NULL,
datime TIMESTAMP,
readwhether BOOLEAN
);`
_, err = db.Exec(statement)
if err != nil {
// log.Printf("create offlineMessage table failed, err: %v", err)
return
}
return
}
//CreatUserFriendListTable 创建用户好友联系表
func CreatUserFriendListTable() (err error) {
//如果表存在, 先删除表
// statement := `DROP TABLE IF EXISTS offlinemessage;`
// _, err = db.Exec(statement)
// if err != nil {
// log.Printf("drop table offlinemessage failed, err: %v", err)
// return
// }
statement := `CREATE TABLE IF NOT EXISTS userfriendlist (
id serial NOT NULL primary key,
userid VARCHAR(64) NOT NULL,
userfriendid VARCHAR(64) NOT NULL
);`
_, err = db.Exec(statement)
if err != nil {
// log.Printf("create offlineMessage table failed, err: %v", err)
return
}
return
}
//CreatImginfoTable 创建图片表
func CreatImginfoTable() (err error) {
//如果表存在, 先删除表
// statement := `DROP TABLE IF EXISTS offlinemessage;`
// _, err = db.Exec(statement)
// if err != nil {
// log.Printf("drop table offlinemessage failed, err: %v", err)
// return
// }
statement := `CREATE TABLE IF NOT EXISTS imginfo (
id serial,
name varchar(255) NOT NULL,
type varchar(255),
size varchar(255),
path varchar(255) NOT NULL,
md5 varchar(255),
time timestamp with time zone default current_timestamp
);`
_, err = db.Exec(statement)
if err != nil {
// log.Printf("create offlineMessage table failed, err: %v", err)
return
}
return
}
// Close 关闭数据库
func Close() {
db.Close()
}
handleDB.go
在下列代码中寻找相应的函数
package dbtable
import (
"bufio"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"log"
"os"
"regexp"
"time"
)
// GetMd5String 根据账号生成64位md5字符串
func GetMd5String(username string) (string, error) {
if username == "" {
log.Printf("the username is null")
return "", errors.New("the username is null")
}
usernameHash := md5.New()
_, err := usernameHash.Write([]byte(username))
if err != nil {
log.Printf("create md5 string by username failed, err: %v", err)
return "", err
}
return hex.EncodeToString(usernameHash.Sum(nil)), nil
}
//VerifyEmailFormat 验证邮箱是否正确
func VerifyEmailFormat(email string) bool {
//pattern := `\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*` //匹配电子邮箱
pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$`
reg := regexp.MustCompile(pattern)
return reg.MatchString(email)
}
//VerifyMobileFormat 验证手机是否正确
func VerifyMobileFormat(mobileNum string) bool {
regular := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"
reg := regexp.MustCompile(regular)
fmt.Println(reg.MatchString(mobileNum))
return reg.MatchString(mobileNum)
}
//VerifyNameFormat 验证用户名是否正确
func VerifyNameFormat(name string) bool {
pattern := "^[a-zA-Z][a-zA-Z0-9_]{4,15}$"
reg := regexp.MustCompile(pattern)
fmt.Println(reg.MatchString(name))
return reg.MatchString(name)
}
// CreateUser 系统初始化就生成2个已经注册的用户
func CreateUser() error {
rows, err := db.Query(" select * from myusers where username=$1", "xiaoming")
if rows.Next() {
log.Println("小明已存在")
rows.Close()
return nil
}
rows, err = db.Query(" select * from myusers where username=$1", "xiaohei")
if rows.Next() {
log.Println("小黑已存在")
rows.Close()
return nil
}
defer rows.Close()
id1, err := GetMd5String("xiaoming")
if err != nil {
log.Println("get md5 string failed:", err)
return err
}
id2, err := GetMd5String("xiaohei")
if err != nil {
log.Println("get md5 string failed:", err)
return err
}
stmt, err := db.Prepare(`insert into myusers(id,username,userphone, usermail, password) values($1,$2,$3,$4,$5)`)
if err != nil {
log.Fatal(err)
return err
}
defer stmt.Close()
_, err = stmt.Exec(id1, "xiaoming", "13726845659", "123456@qq.com", "123456")
if err != nil {
log.Println("insert user failed:", err)
return err
}
_, err = stmt.Exec(id2, "xiaohei", "19926849899", "abcde@abx.com", "234567")
if err != nil {
log.Println("insert user failed:", err)
return err
}
return nil
}
// CreateXiaohuaFriend 系统初始化就生成小华的好友
func CreateXiaohuaFriend() error {
var id1, id2, id3 string
rows, err := db.Query(" select id from myusers where username=$1", "xiaohua")
defer rows.Close()
if err != nil {
log.Println("get friends id failed")
rows.Close()
return nil
}
for rows.Next() {
if err = rows.Scan(&id1); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
if id1 == "" {
log.Printf("xiaohua not exit , err: %v", err)
return err
}
rowscheckinit, err := db.Query(" select userid from userfriendlist where userid=$1", id1)
if rowscheckinit.Next() {
log.Println("小华好友已初始化")
rowscheckinit.Close()
return nil
}
defer rowscheckinit.Close()
rows, err = db.Query(" select id from myusers where username=$1", "xiaoming")
if err != nil {
log.Println("get friends id failed")
rows.Close()
return nil
}
for rows.Next() {
if err = rows.Scan(&id2); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
rows, err = db.Query(" select id from myusers where username=$1", "xiaohei")
if err != nil {
log.Println("get friends id failed")
rows.Close()
return nil
}
for rows.Next() {
if err = rows.Scan(&id3); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
defer rows.Close()
statement := `insert into userfriendlist(userid,userfriendid) values($1,$2)`
_, err = db.Exec(statement, id1, id1)
if err != nil {
log.Println("insert user failed:", err)
return err
}
_, err = db.Exec(statement, id1, id2)
if err != nil {
log.Println("insert user failed:", err)
return err
}
//双向绑定
_, err = db.Exec(statement, id2, id1)
if err != nil {
log.Println("insert user failed:", err)
return err
}
_, err = db.Exec(statement, id1, id3)
if err != nil {
log.Println("insert user failed:", err)
return err
}
_, err = db.Exec(statement, id3, id1)
if err != nil {
log.Println("insert user failed:", err)
return err
}
return nil
}
// StorageUserInfoToDB 把用户信息存储进数据库
func StorageUserInfoToDB(username, userphone, usermail, password string) (id string, err error) {
//检查是否为空
if username == "" {
log.Println("the username is empty string")
return "",errors.New("the username is empty string")
}
if userphone == "" {
log.Println("the userphone is empty string")
return "",errors.New("the userphone is empty string")
}
if usermail == "" {
log.Println("the username is empty string")
return "",errors.New("the usermail is empty string")
}
if password == "" {
log.Println("the password is empty string")
return "",errors.New("the password is empty string")
}
//验证格式是否正确
verify := VerifyMobileFormat(userphone)
if verify == false {
log.Println("the userphone is improper")
return "",errors.New("the userphone is improper")
}
verify = VerifyEmailFormat(usermail)
if verify == false {
log.Println("the usermail is improper")
return "",errors.New("the usermail is improper")
}
verify = VerifyNameFormat(username)
if verify == false {
log.Println("the username is improper")
return "",errors.New("the username is improper")
}
//检查是否重复
rows, err := db.Query(" select * from myusers where username=$1", username)
defer rows.Close()
if rows.Next() {
log.Println("the username has existed")
return "",errors.New("tthe username has existed")
}
rows, err = db.Query(" select * from myusers where userphone=$1", userphone)
if rows.Next() {
log.Println("the userphone has existed")
return "",errors.New("tthe userphone has existed")
}
rows, err = db.Query(" select * from myusers where usermail=$1", usermail)
if rows.Next() {
log.Println("the usermail has existed")
return "",errors.New("tthe usermail has existed")
}
id, err = GetMd5String(username)
if err != nil {
log.Println("get md5 string failed:", err)
return "",err
}
statement := `insert into myusers(id, username, userphone, usermail, password) values($1, $2, $3,$4,$5)`
_, err = db.Exec(statement, id, username, userphone, usermail, password)
if err != nil {
log.Printf("sql exce failed, err: %v", err)
return
}
log.Printf("%s录入成功\n", username)
return
}
// GetUserIDByUseraccountAndPassword 根据账户和密码获取用户id
func GetUserIDByUseraccountAndPassword(useraccount, password string) (id string, err error) {
if useraccount == "" {
log.Println("the username is empty string")
return "", errors.New("the useraccount is empty string")
}
if password == "" {
log.Println("the password is empty string")
return "", errors.New("the password is empty string")
}
if db == nil {
log.Println("the db pointer is null")
return "", errors.New("the db pointer is null")
}
statement := `select id from myusers where username = $1 and password = $2`
err = db.QueryRow(statement, useraccount, password).Scan(&id)
if err == nil {
return
}
log.Printf("query id by username and password failed, err: %v", err)
statement = `select id from myusers where userphone = $1 and password = $2`
err = db.QueryRow(statement, useraccount, password).Scan(&id)
if err == nil {
return
}
log.Printf("query id by userphone and password failed, err: %v", err)
statement = `select id from myusers where usermail = $1 and password = $2`
err = db.QueryRow(statement, useraccount, password).Scan(&id)
if err == nil {
return
}
log.Printf("query id by usermail and password failed, err: %v", err)
return "", err
}
// AddMessage 往消息列表里面写入离线消息
func AddMessage(sid, rid, message, imgid string) (err error) {
rows, err := db.Query(" select * from myusers where id=$1", sid)
defer rows.Close()
if !rows.Next() {
log.Println("错误,发送方不存在")
return errors.New("错误,发送方不存在")
}
rows, err = db.Query(" select * from myusers where id=$1", rid)
if !rows.Next() {
log.Println("错误,接受方不存在")
return errors.New("错误,接受方不存在")
}
t := time.Now()
b :=false
statement := `insert into offlinemessage( sid, rid, message, datime, readwhether, imgid) values($1, $2, $3, $4, $5, $6)`
_, err = db.Exec(statement, sid, rid, message, t, b, imgid)
if err != nil {
log.Printf("sql exce failed, err: %v", err)
return
}
return
}
// MessageList 消息列表
type MessageList struct {
Sid string `json:"sid"` // 发送方
Rid string `json:"rid"` //接受方
Message string `json:"message"` // 消息内容
Time string `json:"time"` //发送时间
Imgid string `json:"imgid"` //发送时间
}
// GetMessageList 获取消息列表
func GetMessageList(userid string, userfriendid string) ([]MessageList, error) {
rows, err := db.Query(" select * from myusers where id=$1", userid)
defer rows.Close()
if !rows.Next() {
log.Println("错误,user 不存在")
return nil, errors.New("错误,user不存在")
}
rows, err = db.Query(" select * from myusers where id=$1", userfriendid)
if !rows.Next() {
log.Println("错误,user's friend 不存在")
return nil, errors.New("错误,user's friend不存在")
}
messageArray := []MessageList{}
messageList := MessageList{}
//找出所有有关本用户的消息
statement := `select id, sid, rid, message, datime, readwhether, imgid from offlinemessage where rid = $1 or sid = $2`
rows, err = db.Query(statement, userid, userid)
if err != nil {
log.Printf("query failed, err: %v", err)
return nil, err
}
var messageid int
var changeReadWhether bool
for rows.Next() {
if err = rows.Scan(&messageid, &messageList.Sid, &messageList.Rid, &messageList.Message, &messageList.Time, &changeReadWhether, &messageList.Imgid); err != nil {
log.Printf("rows scan failed, err: %v", err)
return nil, err
}
if messageList.Sid == userfriendid || messageList.Rid == userfriendid {
if changeReadWhether == false&& messageList.Sid == userfriendid {
_, err := db.Exec("UPDATE offlinemessage SET readwhether=$1 where id=$2", true, messageid)
if err != nil {
log.Printf("change readwhether failed, err: %v", err)
return nil, err
}
}
messageArray = append(messageArray, messageList)
}
}
return messageArray, nil
}
//CheckUnreadMessage 检查未读列表
func CheckUnreadMessage(userid string) (num int, err error) {
rows, err := db.Query(" select * from myusers where id=$1", userid)
defer rows.Close()
if !rows.Next() {
log.Println("错误,user 不存在")
return -1, errors.New("错误,user不存在")
}
statement := `select readwhether from offlinemessage where rid = $1`
rows, err = db.Query(statement, userid)
defer rows.Close()
if err != nil {
log.Printf("query failed, err: %v", err)
return -1, err
}
var check bool
num = 0
for rows.Next() {
if err = rows.Scan(&check); err != nil {
log.Printf("rows scan failed, err: %v", err)
return -1, err
}
if check == false {
num++
}
}
log.Printf("未读消息%v条", num)
return num, nil
}
// UserfriendList 好友列表
type UserfriendList struct {
Userfriendname string `json:"userfriendname"`
Userfriendphone string `json:"userfriendphone"`
Userfriendmail string `json:"userfriendmail"`
Userfriendpassword string `json:"userfriendpassword"`
Userfriendid string `json:"userfriendid"`
}
// GetUserfriendList 获取好友列表
func GetUserfriendList(userid string) ([]UserfriendList, error) {
rows, err := db.Query(" select * from myusers where id=$1", userid)
defer rows.Close()
if !rows.Next() {
log.Println("错误,user 不存在")
return nil, errors.New("错误,user不存在")
}
userfriendListArray := []UserfriendList{}
userfriendList := UserfriendList{}
//找出所有有关本用户的消息
statement := `select userfriendid from userfriendlist where userid = $1 `
rows, err = db.Query(statement, userid)
if err != nil {
log.Printf("query failed, err: %v", err)
return nil, err
}
var userfriendID string
for rows.Next() {
if err = rows.Scan(&userfriendID); err != nil {
log.Printf("rows scan failed, err: %v", err)
return nil, err
}
statement = `select username, userphone, usermail, password from myusers where id = $1 `
rowsinfo, err := db.Query(statement, userfriendID)
defer rowsinfo.Close()
if err != nil {
log.Printf("query failed, err: %v", err)
return nil, err
}
for rowsinfo.Next() {
if err = rowsinfo.Scan(&userfriendList.Userfriendname, &userfriendList.Userfriendphone, &userfriendList.Userfriendmail, &userfriendList.Userfriendpassword); err != nil {
log.Printf("rowsinfo scan failed, err: %v", err)
return nil, err
}
}
userfriendList.Userfriendid = userfriendID
userfriendListArray = append(userfriendListArray, userfriendList)
}
return userfriendListArray, nil
}
// DeleteUserFromDB 把用户信息从数据库删除
func DeleteUserFromDB(userfriendid string) (err error) {
rows, err := db.Query(" select * from myusers where id=$1", userfriendid)
defer rows.Close()
if !rows.Next() {
log.Println("错误,user 不存在")
return errors.New("错误,user不存在")
}
stmt, err := db.Prepare("DELETE from myusers where id=$1")
defer stmt.Close()
if err != nil {
log.Println("SQL语句设置失败:", err)
return err
}
result, err := stmt.Exec(userfriendid)
if err != nil {
log.Println("参数添加失败:", err)
return err
}
num, err := result.RowsAffected()
if err != nil {
log.Println("从myusers删除失败:", err)
return err
}
log.Printf("从myusers删除行数:%v", num)
stmt, err = db.Prepare("DELETE from userfriendlist where userid=$1")
if err != nil {
log.Println("SQL语句设置失败:", err)
return err
}
result, err = stmt.Exec(userfriendid)
if err != nil {
log.Println("参数添加失败:", err)
return err
}
num, err = result.RowsAffected()
if err != nil {
log.Println("从userfriendlist userid删除失败:", err)
return err
}
log.Printf("从userfriendlist userid删除行数:%v", num)
stmt, err = db.Prepare("DELETE from userfriendlist where userfriendid=$1")
if err != nil {
log.Println("SQL语句设置失败:", err)
return err
}
result, err = stmt.Exec(userfriendid)
if err != nil {
log.Println("参数添加失败:", err)
return err
}
num, err = result.RowsAffected()
if err != nil {
log.Println("从userfriendlist userfriendid删除失败:", err)
return err
}
log.Printf("从userfriendlist userfriendid删除行数:%v", num)
stmt, err = db.Prepare("DELETE from offlinemessage where rid=$1")
if err != nil {
log.Println("SQL语句设置失败:", err)
return err
}
result, err = stmt.Exec(userfriendid)
if err != nil {
log.Println("参数添加失败:", err)
return err
}
num, err = result.RowsAffected()
if err != nil {
log.Println("从offlinemessage rid删除失败:", err)
return err
}
log.Printf("从offlinemessage rid删除行数:%v", num)
stmt, err = db.Prepare("DELETE from offlinemessage where sid=$1")
if err != nil {
log.Println("SQL语句设置失败:", err)
return err
}
result, err = stmt.Exec(userfriendid)
if err != nil {
log.Println("参数添加失败:", err)
return err
}
num, err = result.RowsAffected()
if err != nil {
log.Println("从offlinemessage sid删除失败:", err)
return err
}
log.Printf("从offlinemessage sid删除行数:%v", num)
log.Println("删除成功")
return nil
}
// UpdateUserInfo 修改用户信息
func UpdateUserInfo(username, userphone, usermail, password, userfriendid string) (err error) {
rows, err := db.Query(" select * from myusers where id=$1", userfriendid)
if !rows.Next() {
rows.Close()
log.Println("用户不存在")
return errors.New("the username is empty string")
}
defer rows.Close()
nf := true
pf := true
mf := true
//检查是否为空
if username == "" {
nf = false
}
if userphone == "" {
pf = false
}
if usermail == "" {
mf = false
}
if nf == false && pf == false && mf == false && password == "" {
log.Println("nothing change")
return errors.New("nothing change")
}
if nf == false {
rows, err := db.Query(" select username from myusers where id=$1", userfriendid)
for rows.Next() {
if err = rows.Scan(&username); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
}
if pf == false {
rows, err := db.Query(" select userphone from myusers where id=$1", userfriendid)
for rows.Next() {
if err = rows.Scan(&userphone); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
}
if mf == false {
rows, err := db.Query(" select usermail from myusers where id=$1", userfriendid)
for rows.Next() {
if err = rows.Scan(&usermail); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
}
if password == "" {
rows, err := db.Query(" select password from myusers where id=$1", userfriendid)
for rows.Next() {
if err = rows.Scan(&password); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
}
//验证格式是否正确
verify := VerifyMobileFormat(userphone)
if verify == false {
log.Println("the userphone is improper")
return errors.New("the userphone is improper")
}
verify = VerifyEmailFormat(usermail)
if verify == false {
log.Println("the usermail is improper")
return errors.New("the usermail is improper")
}
verify = VerifyNameFormat(username)
if verify == false {
log.Println("the username is improper")
return errors.New("the username is improper")
}
//检查是否重复
var checkflag string
checknum := 0
rows, err = db.Query(" select id from myusers where username=$1", username)
if rows.Next() {
if err = rows.Scan(&checkflag); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
checknum++
if checkflag != userfriendid {
log.Println("the username has existed")
return errors.New("the username has existed")
}
}
rows, err = db.Query(" select id from myusers where userphone=$1", userphone)
if rows.Next() {
if err = rows.Scan(&checkflag); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
checknum++
if checkflag != userfriendid {
log.Println("the userphone has existed")
return errors.New("tthe userphone has existed")
}
}
rows, err = db.Query(" select id from myusers where usermail=$1", usermail)
if rows.Next() {
if err = rows.Scan(&checkflag); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
checknum++
if checkflag != userfriendid {
log.Println("the usermail has existed")
return errors.New("tthe usermail has existed")
}
}
rows, err = db.Query(" select id from myusers where password=$1", password)
if rows.Next() {
if err = rows.Scan(&checkflag); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
if checkflag != userfriendid {
checknum++
}
}
if checknum == 4 {
log.Println("the userinfo didn't change")
return errors.New("用户没有修改信息")
}
stmt, err := db.Prepare("UPDATE myusers SET username=$1, userphone=$2, usermail=$3, password=$4 where id=$5")
if err != nil {
log.Println("SQL语句设置失败:", err)
return err
}
_, err = stmt.Exec(username, userphone, usermail, password, userfriendid)
if err != nil {
log.Println("参数添加失败:", err)
return err
}
log.Printf("修改成功")
defer stmt.Close()
return
}
// InsertData 插入数据
func InsertData(filename string, filePath string, MD5 string) {
res, err := db.Exec("INSERT INTO imginfo (name,path,md5) VALUES ($1,$2,$3)", filename, filePath, MD5)
if err != nil {
fmt.Println(err)
return
}
var affectedRows int64
affectedRows, err = res.RowsAffected()
if err != nil {
fmt.Println(err)
return
}
if affectedRows == 0 {
fmt.Println(errors.New("0 row affected"))
return
}
}
//PathExists 判断文件夹是否存在
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
// Calmd5 计算MD5
func Calmd5(bytes []byte) (md5str string) {
MD5 := md5.New()
MD5.Write(bytes)
md5str = hex.EncodeToString(MD5.Sum(nil))
return
}
// CheckRepeat 查重,若文件已存在,则返回其id
func CheckRepeat(MD5 string) (fileid int, res bool) {
row := db.QueryRow("select id from imginfo where md5 = $1", MD5)
err := row.Scan(&fileid)
if err != nil {
fmt.Println(err)
return
}
return fileid, true
}
// GetFilePath 获取文件的存储路径
func GetFilePath(fileid int) (filePath string) {
row := db.QueryRow("SELECT path FROM imginfo where id = $1", fileid)
err := row.Scan(&filePath)
if err != nil {
fmt.Println(err)
return
}
if filePath == "" {
fmt.Println(fmt.Errorf("the submit of the problem %d is null", fileid))
return
}
return filePath
}
// ReadFile 读取文件内容
func ReadFile(filePath string) (bytes []byte) {
file, err := os.Open(filePath)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
stats, err := file.Stat()
if err != nil {
fmt.Println(err)
return
}
var size = stats.Size()
bytes = make([]byte, size)
bufr := bufio.NewReader(file)
_, err = bufr.Read(bytes)
if err != nil {
fmt.Println(err)
return
}
return
}
// ConetFriendXiaohua 成为小华的好友
func ConetFriendXiaohua(username string) error {
var id1, id2 string
rows, err := db.Query(" select id from myusers where username=$1", "xiaohua")
defer rows.Close()
if err != nil {
log.Println("get friends id failed")
rows.Close()
return err
}
for rows.Next() {
if err = rows.Scan(&id1); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
if id1 == "" {
log.Printf("xiaohua not exit , err: %v", err)
return errors.New("小华为空")
}
rows, err = db.Query(" select id from myusers where username=$1", username)
if err != nil {
log.Println("get friends id failed")
rows.Close()
return nil
}
for rows.Next() {
if err = rows.Scan(&id2); err != nil {
log.Printf("rows scan failed, err: %v", err)
return err
}
}
defer rows.Close()
statement := `insert into userfriendlist(userid,userfriendid) values($1,$2)`
_, err = db.Exec(statement, id1, id2)
if err != nil {
log.Println("insert user failed:", err)
return err
}
//双向绑定
_, err = db.Exec(statement, id2, id1)
if err != nil {
log.Println("insert user failed:", err)
return err
}
return nil
}
handleErr.go
package servewr
import (
"encoding/json"
"log"
"net/http"
)
// 错误的响应
type errResp struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
// sendErrToClient 把接口处理函数中遇到的错误返回给前端(客户端)
func sendErrToClient(errMsg string, w http.ResponseWriter) {
resp := errResp{}
resp.Status = -1
resp.Msg = errMsg
data, err := json.Marshal(resp)
if err != nil {
log.Printf("json marshal failed, err: %v", err)
return
}
_, err = w.Write(data)
if err != nil {
log.Printf("write response failed, err: %v", err)
return
}
}
main.go
package main
import (
"fmt"
"log"
"net/http"
// 使用相对路径引用自定义包
"./dbtable"
"./servewr"
)
func main() {
// 设置log打印文件和行号
log.SetFlags(log.Lshortfile | log.LstdFlags)
// 初始化数据库
err := dbtable.Initdb()
if err != nil {
log.Printf("init database failed, err: %v", err)
dbtable.Close()
return
}
defer dbtable.Close()
err = dbtable.InitDir()
if err != nil {
log.Printf("init images file failed, err: %v", err)
dbtable.Close()
return
}
err = dbtable.CreateUser()
if err != nil {
log.Println("create user failed:", err)
dbtable.Close()
return
}
mux := http.NewServeMux()
mux.HandleFunc("/login", servewr.Login)
mux.HandleFunc("/register", servewr.Register)
mux.HandleFunc("/send", servewr.Send)
mux.HandleFunc("/receive", servewr.Receive)
mux.HandleFunc("/check", servewr.Check)
mux.HandleFunc("/show", servewr.Show)
mux.HandleFunc("/delete", servewr.Delete)
mux.HandleFunc("/update", servewr.Update)
mux.HandleFunc("/receiveimg", servewr.ReceiveImg)
mux.HandleFunc("/sendimg", servewr.SendImg)
// 添加receive接口
// mux.HandleFunc("/receive", controllers.Receive)
fmt.Println("Web服务器启动...端口:8888")
err = http.ListenAndServe(":8888", mux)
if err != nil {
log.Printf("listen and server failed, err: %v", err)
dbtable.Close()
return
}
}
3,运行