master
nima 2024-01-08 16:06:31 +03:30
commit d348bd323e
58 changed files with 3929 additions and 0 deletions

7
config/.env 100644
View File

@ -0,0 +1,7 @@
DB_HOST="localhost"
DB_PORT=5432
DB_USER="postgres"
DB_PASSWORD="1"
DB_NAME="cctv"
SECRET = "uHkSNkpm5Uqr61IJt43Mow0lzRWdH2PTdylmK0pcg00oGrw0Ek3/406hRLIc7CglEY+aJy7zT//jfdqj2RQi6hxOfD4KWcS/3kEYmnuS92x9LPVvOeXS7BcAbsOkbk6EpbFNwcXdjYTpDDK88ZZhW/Tpqb/4cjBRUnemsHWCym/LXsBuoPWKrS5jKN8G0ehhErHogMZPu6FVY1uZ2bbX3YbRpTIp97CohlBIELUJCBGQzHloTM4JzJMGqMdBWlnA2DACHKeNT291jVDA/gn3Wcg9M/gIS3DUguuLXtB2pxl/RWMga6LqnPUntIp2l3wGiCLy2d6bSQLVESgTvVA5P55jYElAYq+3VD5NDJNrlAXER76ync5C3G6PEw0RPqWAMeA8OC2xIfjLAcbcvd8Ep3sacExXDiMTpXhyQv04h6M="

45
data.txt 100644
View File

@ -0,0 +1,45 @@
username
user info
passsword
email
phone number
address
product
procuct specs
description
price
quantity
garantee
orders
activity
recent pages
messages
wishlist
comments
entity : user - order - comment - prodcut - wishlist - user_profile - category
user : username - address - email - password - user_id(PK) - phone_number - created_at - removed_at - updated_at
user_profile : autorize_code - birth_day - first_name - last_name - created_at - removed_at - updated_at - user_id(foreign_key)
prodcut : name - specs - price - description - quantity - garantee - product_id - created_at - removed_at - updated_at - category
orders : order_id - user_id(foreign_key) - date - product_id - price - created_at - removed_at - updated_at - quantity_ordered
wishlist : wishlist_id - product_id - created_at - removed_at - updated_at - user_id
comments : comments_id - comment_date - created_at - removed_at - updated_at - content - user_id - product_id
User Table: user_id (PK), username, email(unique), password, created_at, removed_at, updated_at , is_deleted , role
User Profile Table: user_profile_id (PK), authorize_code(unique), birth_day, first_name, last_name, created_at, updated_at, user_id (FK), is_deleted , removed_at
Phone Table : created_at, updated_at, user_id (FK), is_deleted , removed_at , Phone_id ,
Product Table: product_id (PK), name, price, description, quantity, guarantee, created_at, removed_at, updated_at, category, is_deleted
Orders Table: order_id (PK), user_id (FK), date, product_id (FK), price, created_at, removed_at, updated_at, quantity_ordered, is_deleted
Wishlist Table: wishlist_id (PK), product_id (FK), created_at, removed_at, updated_at, user_id (FK), is_deleted
Comments Table: comments_id (PK), comment_date, created_at, removed_at, updated_at, content, user_id (FK), product_id (FK), is_deleted
specs Table : spec_id(PK) , product_id(FK) , type , value , is_deleted,created_at, removed_at, updated_at
address Table : address_id(PK) , user_id(FK) , address , created_at, removed_at, updated_at,is_deleted

110
database/psql.go 100644
View File

@ -0,0 +1,110 @@
package database
import (
"fmt"
"os"
"strconv"
models "app/models"
"github.com/joho/godotenv"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func Db() gorm.DB {
err := godotenv.Load("./config/.env")
if err != nil {
panic(err)
}
host := os.Getenv("DB_HOST")
port, err := strconv.Atoi(os.Getenv("DB_PORT"))
if err != nil {
fmt.Println(os.Getenv("DB_PORT"))
panic(err)
}
user := os.Getenv("DB_USER")
password := os.Getenv("DB_PASSWORD")
dbname := os.Getenv("DB_NAME")
dbc := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
db, err := gorm.Open(postgres.Open(dbc), &gorm.Config{})
if err != nil {
panic(err)
}
return *db
}
func Create_tables() {
db := Db()
err := db.AutoMigrate(&models.User{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Address{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Phone{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(models.Product{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Order{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(models.Specs{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Comment{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Wishlist{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Order_products{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Images{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Jwt{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Carts{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.Cart_items{})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.PriceHistory{})
if err != nil {
panic(err)
}
}

142
docs/docs.go 100644
View File

@ -0,0 +1,142 @@
// Code generated by swaggo/swag. DO NOT EDIT.
package docs
import "github.com/swaggo/swag"
const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/users/": {
"post": {
"description": "Send UserModel",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"register"
],
"summary": "Register User",
"parameters": [
{
"description": "User Model",
"name": "user",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.User"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/models.User"
}
},
"400": {
"description": "Bad Request"
}
}
}
}
},
"definitions": {
"models.User": {
"type": "object",
"properties": {
"birthDay": {
"type": "string"
},
"created_at": {
"type": "string"
},
"email": {
"type": "string"
},
"first_name": {
"type": "string"
},
"is_removed": {
"type": "boolean"
},
"last_name": {
"type": "string"
},
"national_code": {
"type": "string"
},
"password": {
"type": "string"
},
"postCode": {
"type": "string"
},
"removed_at": {
"type": "string"
},
"role": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"user_id": {
"type": "integer"
},
"username": {
"type": "string"
}
}
}
},
"securityDefinitions": {
"BasicAuth": {
"type": "basic"
}
},
"externalDocs": {
"description": "OpenAPI",
"url": "https://swagger.io/resources/open-api/"
}
}`
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0",
Host: "localhost:8000",
BasePath: "",
Schemes: []string{},
Title: "Swagger Example API",
Description: "This is a sample server celler server.",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}

116
docs/swagger.json 100644
View File

@ -0,0 +1,116 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server celler server.",
"title": "Swagger Example API",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "1.0"
},
"host": "localhost:8000",
"paths": {
"/users/": {
"post": {
"description": "Send UserModel",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"register"
],
"summary": "Register User",
"parameters": [
{
"description": "User Model",
"name": "user",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.User"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/models.User"
}
},
"400": {
"description": "Bad Request"
}
}
}
}
},
"definitions": {
"models.User": {
"type": "object",
"properties": {
"birthDay": {
"type": "string"
},
"created_at": {
"type": "string"
},
"email": {
"type": "string"
},
"first_name": {
"type": "string"
},
"is_removed": {
"type": "boolean"
},
"last_name": {
"type": "string"
},
"national_code": {
"type": "string"
},
"password": {
"type": "string"
},
"postCode": {
"type": "string"
},
"removed_at": {
"type": "string"
},
"role": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"user_id": {
"type": "integer"
},
"username": {
"type": "string"
}
}
}
},
"securityDefinitions": {
"BasicAuth": {
"type": "basic"
}
},
"externalDocs": {
"description": "OpenAPI",
"url": "https://swagger.io/resources/open-api/"
}
}

77
docs/swagger.yaml 100644
View File

@ -0,0 +1,77 @@
definitions:
models.User:
properties:
birthDay:
type: string
created_at:
type: string
email:
type: string
first_name:
type: string
is_removed:
type: boolean
last_name:
type: string
national_code:
type: string
password:
type: string
postCode:
type: string
removed_at:
type: string
role:
type: string
updated_at:
type: string
user_id:
type: integer
username:
type: string
type: object
externalDocs:
description: OpenAPI
url: https://swagger.io/resources/open-api/
host: localhost:8000
info:
contact:
email: support@swagger.io
name: API Support
url: http://www.swagger.io/support
description: This is a sample server celler server.
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
termsOfService: http://swagger.io/terms/
title: Swagger Example API
version: "1.0"
paths:
/users/:
post:
consumes:
- application/json
description: Send UserModel
parameters:
- description: User Model
in: body
name: user
required: true
schema:
$ref: '#/definitions/models.User'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/models.User'
"400":
description: Bad Request
summary: Register User
tags:
- register
securityDefinitions:
BasicAuth:
type: basic
swagger: "2.0"

49
go.mod 100644
View File

@ -0,0 +1,49 @@
module app
go 1.19
require github.com/swaggo/echo-swagger v1.4.0
require github.com/kavenegar/kavenegar-go v0.0.0-20221124112814-40341057b5ca // indirect
require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.2.0 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.3.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/echo-jwt/v4 v4.2.0 // indirect
github.com/labstack/echo/v4 v4.10.2 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/swaggo/files/v2 v2.0.0 // indirect
github.com/swaggo/swag v1.16.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/postgres v1.5.2 // indirect
gorm.io/gorm v1.25.1 // indirect
)

161
go.sum 100644
View File

@ -0,0 +1,161 @@
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.2.0 h1:/Jdm5QfyM8zdlqT6WVZU4cfP23sot6CEHA4CS49Ezig=
github.com/PuerkitoBio/purell v1.2.0/go.mod h1:OhLRTaaIzhvIyofkJfB24gokC7tM42Px5UhoT32THBk=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kavenegar/kavenegar-go v0.0.0-20221124112814-40341057b5ca h1:aEyiDaExheG7fNpEYcILCVGgM7jlLzTVgxEQAGaepeM=
github.com/kavenegar/kavenegar-go v0.0.0-20221124112814-40341057b5ca/go.mod h1:CRhvvr4KNAyrg+ewrutOf+/QoHs7lztSoLjp+GqhYlA=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/echo-jwt/v4 v4.2.0 h1:odSISV9JgcSCuhgQSV/6Io3i7nUmfM/QkBeR5GVJj5c=
github.com/labstack/echo-jwt/v4 v4.2.0/go.mod h1:MA2RqdXdEn4/uEglx0HcUOgQSyBaTh5JcaHIan3biwU=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/swaggo/echo-swagger v1.4.0 h1:RCxLKySw1SceHLqnmc41pKyiIeE+OiD7NSI7FUOBlLo=
github.com/swaggo/echo-swagger v1.4.0/go.mod h1:Wh3VlwjZGZf/LH0s81tz916JokuPG7y/ZqaqnckYqoQ=
github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw=
github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM=
github.com/swaggo/swag v1.8.12 h1:pctzkNPu0AlQP2royqX3apjKCQonAnf7KGoxeO4y64w=
github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its=
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=

123
handlers/address.go 100644
View File

@ -0,0 +1,123 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"fmt"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
// Create(a *models.Address) error
// GetAddresses(id uint) ([]models.Address, error)
// UpdateAddress(id uint, address string) error
// Delete(id uint) error
func initAddress() *repositories.Address_repository {
db := database.Db()
addressRepository := new(repositories.Address_repository)
addressRepository.DB = &db
return addressRepository
}
func CreateAddress(c echo.Context) error {
address := new(models.Address)
if err := c.Bind(address); err != nil {
panic(err)
}
addressRepository := initAddress()
err := addressRepository.Create(address)
if err != nil {
panic(err)
}
return c.JSON(http.StatusCreated, address)
}
func GetUserAddresses(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
addressRepository := initAddress()
addresses, err := addressRepository.GetAddresses(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, addresses)
}
func UpdateAddress(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewAddress string `json:"address"`
}
addressRepository := initAddress()
if update.NewAddress != "" {
err = addressRepository.UpdateAddress(update.NewAddress, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdatePostCode(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
var update struct {
NewPostCode string `json:"postcode"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
addressRepository := initAddress()
if update.NewPostCode != "" {
err = addressRepository.UpdatePostCode(update.NewPostCode, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func DeleteAddress(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
addressRepository := initAddress()
err = addressRepository.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

View File

@ -0,0 +1,153 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"app/utils"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
func initCartItems() *repositories.Cart_items_repository {
db := database.Db()
cartRepository := new(repositories.Cart_items_repository)
cartRepository.DB = &db
return cartRepository
}
func Create_cart_item(c echo.Context) error {
db := database.Db()
// get user's coockie
cookie, err := c.Cookie("authorization")
if err != nil {
return echo.ErrUnauthorized
}
// parse jwt token
token, err := utils.ParseToken(cookie.Value)
if err != nil {
return echo.ErrUnauthorized
}
// convert jwt content to int
jwtID, err := strconv.Atoi(token)
if err != nil {
return err
}
// check if user exists and return userID
userID, _, err := utils.CheckUserByJwt(uint(jwtID))
if err != nil {
return err
}
cartRepository := new(repositories.Carts_repository)
cartRepository.DB = &db
cart, err := cartRepository.GetCart(userID)
if err != nil {
return err
}
cart_items := new(models.Cart_items)
cart_items.Cart_id = cart.Cart_id
//cart_items.Price = uint64(cart_items.Quantity) * cart_items.
if err := c.Bind(cart_items); err != nil {
return err
}
productRepository := new(repositories.Product_repository)
productRepository.DB = &db
product, err := productRepository.GetByID(cart_items.Product_id)
if err != nil {
panic(err)
}
count, err := utils.GetProductCount(int64(cart_items.Product_id), cart_items.Cart_id)
if err != nil {
return err
}
cartItemRepository := initCartItems()
if count == 0 {
cart_items.Price = product.Price
cart_items.PricePerUnit = product.Price
err = cartItemRepository.Create(cart_items)
if err != nil {
return err
}
} else {
var certainItem models.Cart_items
err := db.Where("product_id = ?", cart_items.Product_id).Where("cart_id = ?", cart.Cart_id).Where("status = ?", "pending").First(&certainItem).Error
if err != nil {
return err
}
if certainItem.Quantity == product.Quantity {
return c.String(http.StatusNotAcceptable, "limit reached")
}
if certainItem.Quantity < product.Quantity {
err = cartItemRepository.IncreaseQuantity(certainItem.Cart_item_id)
if err != nil {
return err
}
}
}
return c.JSON(http.StatusCreated, cart_items)
}
func GetCartItems(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return err
}
cartRepository := initCartItems()
items, err := cartRepository.GetItems(uint(id), "pending")
if err != nil {
return err
}
return c.JSON(http.StatusAccepted, items)
}
func UpdateItemStatus(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return err
}
cartRepository := initCartItems()
err = cartRepository.UpdateStatus(uint(id))
if err != nil {
return err
}
return c.String(http.StatusAccepted, "updated")
}
func Remove_cart_item(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return err
}
cartRepository := initCartItems()
err = cartRepository.Remove(uint(id))
if err != nil {
return err
}
return c.String(http.StatusAccepted, "removed")
}

113
handlers/comment.go 100644
View File

@ -0,0 +1,113 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
// Create(c *models.Comment) error
// GetUserComments(id uint) ([]models.Comment, error)
// GetProductComments(id uint) ([]models.Comment, error)
// UpdateContent(id uint, content string) error
// Delete(id uint) error
func initComment() *repositories.Comment_repository {
db := database.Db()
commentRepository := new(repositories.Comment_repository)
commentRepository.DB = &db
return commentRepository
}
func CreateComment(c echo.Context) error {
comment := new(models.Comment)
if err := c.Bind(comment); err != nil {
panic(err)
}
commentRepository := initComment()
err := commentRepository.Create(comment)
if err != nil {
panic(err)
}
return c.JSON(http.StatusCreated, comment)
}
func GetUserComments(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
commentRepository := initComment()
comments, err := commentRepository.GetUserComments(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, comments)
}
func GetProductComments(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
commentRepository := initComment()
comments, err := commentRepository.GetUserComments(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, comments)
}
func UpdateComment(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewContent string `json:"content"`
}
commentRepository := initComment()
if update.NewContent != "" {
err = commentRepository.UpdateContent(uint(id), update.NewContent)
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func DeleteComment(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
commentRepository := initComment()
err = commentRepository.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

134
handlers/orders.go 100644
View File

@ -0,0 +1,134 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
// Create(o *models.Order) error
// GetOrders(id uint) ([]models.Order, error)
// GetOrdersByDate(start time.Time, end time.Time) ([]models.Order, error)
// Delete(id uint) error
type Status string
const (
StatusPending Status = "pending"
StatusPurchased Status = "purchased"
StatusRejected Status = "rejected"
)
func initOrder() *repositories.Orders_repository {
db := database.Db()
orderRepository := new(repositories.Orders_repository)
orderRepository.DB = &db
return orderRepository
}
func getTotalPrice(items []models.Cart_items) uint64 {
var totalPrice uint64
totalPrice = 0
for i := 0; i < len(items); i++ {
totalPrice += items[i].Price
}
return totalPrice
}
func CreateOrder(c echo.Context, cart models.Carts, TransportationFee uint64) error {
db := database.Db()
order := new(models.Order)
var order_products []models.Order_products
itemsRepository := new(repositories.Cart_items_repository)
itemsRepository.DB = &db
// get cart_items related to this user
items, err := itemsRepository.GetItems(cart.Cart_id, string(StatusPurchased))
if err != nil {
return err
}
orderRepository := initOrder()
order.User_id = cart.User_id
// calculate prices
order.ProductsTotalPrice = getTotalPrice(items)
tax := float64(getTotalPrice(items)) * 0.09
order.Tax = uint64(tax)
order.TotalPrice = uint64(tax) + TransportationFee + getTotalPrice(items)
err = orderRepository.Create(order)
if err != nil {
panic(err)
}
order_productsRepository := new(repositories.Order_Product_repository)
order_productsRepository.DB = &db
productRepository := new(repositories.Product_repository)
productRepository.DB = &db
for i := 0; i < len(items); i++ {
order_products[i].Order_id = order.Order_id
order_products[i].Product_id = items[i].Product_id
order_products[i].Quantity_ordered = items[i].Quantity
order_products[i].Price = items[i].Price
productQuantity, err := productRepository.GetQuantity(items[i].Product_id)
if err != nil {
return err
}
err = productRepository.UpdateQuantity(productQuantity-items[i].Quantity, items[i].Product_id)
if err != nil {
return err
}
err = order_productsRepository.Create(&order_products[i])
if err != nil {
return err
}
}
for i := 0; i < len(items); i++ {
itemsRepository.Remove(items[i].Cart_item_id)
}
return c.JSON(http.StatusCreated, order)
}
func GetUserOrders(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
orderRepository := initOrder()
orders, err := orderRepository.GetOrders(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, orders)
}
func GetOrdersByDate(c echo.Context) error {
return c.String(http.StatusAccepted, "not ready")
}
func DeleteOrder(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
orderRepository := initOrder()
err = orderRepository.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

118
handlers/phone.go 100644
View File

@ -0,0 +1,118 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
// Create(p *models.Phone) error
// GetPhones(id uint) (*models.Phone, error)
// UpdatePhoneNumber(number string, id uint) error
// UpdateCellPhone(number string, id uint) error
// Delete(id uint) error
func initPhone() *repositories.Phone_repository {
db := database.Db()
phoneRepository := new(repositories.Phone_repository)
phoneRepository.DB = &db
return phoneRepository
}
func CreatePhone(c echo.Context) error {
phone := new(models.Phone)
if err := c.Bind(phone); err != nil {
panic(err)
}
phonerepository := initPhone()
err := phonerepository.Create(phone)
if err != nil {
panic(err)
}
return c.JSON(http.StatusCreated, phone)
}
func GetUserPhoneNumbers(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
phonerepository := initPhone()
phone, err := phonerepository.GetPhones(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, phone)
}
func UpdatePhoneNumber(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewNumber string `json:"phonenumber"`
}
phone := initPhone()
if update.NewNumber != "" {
err = phone.UpdatePhoneNumber(update.NewNumber, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateCellPhoneNumber(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewNumber string `json:"cellphonenumber"`
}
phone := initPhone()
if update.NewNumber != "" {
err = phone.UpdateCellPhone(update.NewNumber, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func DeletePhone(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
phone := initPhone()
err = phone.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

259
handlers/product.go 100644
View File

@ -0,0 +1,259 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
// Create(p *models.Product) error
// GetByName(name string) ([]models.Product, error)
// GetByID(id uint) (*models.Product, error)
// GetByCategory(category string) ([]models.Product, error)
// UpdateName(name string, id uint) error
// UpdateDescription(content string, id uint) error
// UpdateWarranty(name string, id uint) error
// UpdateQuantity(quantity uint, id uint) error
// UpdateCategory(category string, id uint) error
// UpdatePrice(price uint64, id uint) error
// Delete(name string, id uint) error
func initProduct() *repositories.Product_repository {
db := database.Db()
productRepository := new(repositories.Product_repository)
productRepository.DB = &db
return productRepository
}
func CreateProduct(c echo.Context) error {
product := new(models.Product)
if err := c.Bind(product); err != nil {
panic(err)
}
productRepository := initProduct()
err := productRepository.Create(product)
if err != nil {
panic(err)
}
return c.JSON(http.StatusCreated, product)
}
func GetProductByName(c echo.Context) error {
name := c.Param("name")
productRepository := initProduct()
product, err := productRepository.GetByName(name)
if err != nil {
return err
}
return c.JSON(http.StatusAccepted, product)
}
func GetProductByID(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
productRepository := initProduct()
product, err := productRepository.GetByID(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, product)
}
func GetProductByCategory(c echo.Context) error {
name := c.Param("name")
productRepository := initProduct()
product, err := productRepository.GetByCategory(name)
if err != nil {
return err
}
return c.JSON(http.StatusAccepted, product)
}
func UpdateProductName(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewName string `json:"name"`
}
if err := c.Bind(update); err != nil {
panic(err)
}
product := initProduct()
if update.NewName != "" {
err = product.UpdateName(update.NewName, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateDescription(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewDescription string `json:"description"`
}
if err := c.Bind(update); err != nil {
panic(err)
}
product := initProduct()
if update.NewDescription != "" {
err = product.UpdateDescription(update.NewDescription, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateWarranty(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewWarranty string `json:"warranty"`
}
if err := c.Bind(update); err != nil {
panic(err)
}
product := initProduct()
if update.NewWarranty != "" {
err = product.UpdateWarranty(update.NewWarranty, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateQuantity(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewQuantity uint `json:"description"`
}
if err := c.Bind(update); err != nil {
panic(err)
}
product := initProduct()
err = product.UpdateQuantity(update.NewQuantity, uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateCategory(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewCategory string `json:"category"`
}
if err := c.Bind(update); err != nil {
panic(err)
}
product := initProduct()
if update.NewCategory != "" {
err = product.UpdateCategory(update.NewCategory, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdatePrice(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewPrie uint64 `json:"price"`
}
if err := c.Bind(update); err != nil {
panic(err)
}
product := initProduct()
err = product.UpdatePrice(update.NewPrie, uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "updated")
}
func DeleteProduct(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
product := initProduct()
err = product.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

118
handlers/specs.go 100644
View File

@ -0,0 +1,118 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
// Create(s *models.Specs) error
// GetSpecs(id uint) (*models.Specs, error)
// UpdateType(newType string, id uint) error
// UpdateValue(newValue string, id uint) error
// Delete(id uint) error
func initSpecs() *repositories.Specs_repository {
db := database.Db()
specsRepository := new(repositories.Specs_repository)
specsRepository.DB = &db
return specsRepository
}
func CreateSpecs(c echo.Context) error {
spec := new(models.Specs)
specsRepository := initSpecs()
if err := c.Bind(spec); err != nil {
panic(err)
}
err := specsRepository.Create(spec)
if err != nil {
panic(err)
}
return c.JSON(http.StatusCreated, spec)
}
func GetSpecs(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
specsRepository := initSpecs()
specs, err := specsRepository.GetSpecs(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, specs)
}
func UpdateType(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewType string `json:"type"`
}
specsRepository := initSpecs()
if update.NewType != "" {
err = specsRepository.UpdateType(update.NewType, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateValue(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewValue string `json:"value"`
}
specsRepository := initSpecs()
if update.NewValue != "" {
err = specsRepository.UpdateValue(update.NewValue, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func DeleteSpecs(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
specsRepository := initSpecs()
err = specsRepository.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

368
handlers/user.go 100644
View File

@ -0,0 +1,368 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"app/utils"
"net/http"
"strconv"
"fmt"
"github.com/labstack/echo/v4"
)
func initUser() *repositories.User_repository {
db := database.Db()
userRepository := new(repositories.User_repository)
userRepository.DB = &db
return userRepository
}
// RegisterUser godoc
// @Summary Register User
// @Description Send UserModel
// @Tags register
// @Accept json
// @Produce json
// @Param user body models.User true "User Model"
// @Success 200 {object} models.User
// @Failure 400
// @Router /users/ [post]
func RegisterUser(c echo.Context) error {
user := new(models.User)
db := database.Db()
if err := c.Bind(user); err != nil {
return err
}
userRepository := initUser()
user.Role = "user"
err := userRepository.Create(user)
if err != nil {
return err
}
tempUser, err := utils.GetByPhoneNumber(user.CellPhone_number)
if err != nil {
return err
}
cartRepository := new(repositories.Carts_repository)
cartRepository.DB = &db
cart := new(models.Carts)
cart.User_id = tempUser.User_id
err = cartRepository.Create(cart)
if err != nil {
return err
}
//utils.GenerateToken(c,*user)
return c.JSON(http.StatusCreated, user)
}
func GetSameUserNames(c echo.Context) error {
username := c.Param("name")
userRepository := initUser()
users, err := userRepository.GetByName(username)
if err != nil {
return err
}
return c.JSON(http.StatusAccepted, users)
}
func GetUserByID(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
userRepository := initUser()
user, err := userRepository.GetByID(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, user)
}
// UpdateUserName(name string, id uint) error
// UpdateEmail(email string, id uint) error
// UpdatePassword(password string, id uint) error
// UpdateRole(newRole string, id uint) error
// UpdateNationalCode(newCode string, id uint) error
// UpdateBirthDay(newBirthDay string, id uint) error
// UpdateFirstName(firstName string, id uint) error
// UpdateLastName(lastName string, id uint) error
// UpdatePostCode(newPostCode string, id uint) error
// Delete(name string, id uint) error
func UpdateUserName(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
var update struct {
NewUsername string `json:"username"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
err = userRepository.UpdateUserName(update.NewUsername, uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateEmail(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
var update struct {
NewEmail string `json:"email"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
if update.NewEmail != "" {
err = userRepository.UpdateEmail(update.NewEmail, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdatePassword(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
isNull := true
var update struct {
OldPassword string `json:"oldpassword"`
NewPassword string `json:"password"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
user, err := userRepository.GetByID(uint(id))
if err != nil {
return err
}
if user.Password != "" {
isNull = false
}
if isNull {
password, err := utils.HashPW(update.NewPassword)
if err != nil {
return err
}
err = userRepository.UpdatePassword(password, uint(id))
if err != nil {
panic(err)
}
} else {
checkpw, err := utils.Match(update.OldPassword, user.Email)
if err != nil {
return err
}
if checkpw {
password, err := utils.HashPW(update.NewPassword)
if err != nil {
return err
}
err = userRepository.UpdatePassword(password, uint(id))
if err != nil {
panic(err)
}
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateRole(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
var update struct {
NewRole string `json:"role"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
if update.NewRole != "" {
err = userRepository.UpdateRole(update.NewRole, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateNationalCode(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
var update struct {
NewNationalCode string `json:"national_code"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
if update.NewNationalCode != "" {
err = userRepository.UpdateNationalCode(update.NewNationalCode, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateBirthDay(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
var update struct {
NewBirthDay string `json:"birthday"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
if update.NewBirthDay != "" {
err = userRepository.UpdateBirthDay(update.NewBirthDay, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateFirstName(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
var update struct {
NewFirstName string `json:"firstname"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
if update.NewFirstName != "" {
err = userRepository.UpdateFirstName(update.NewFirstName, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func UpdateLastName(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
var update struct {
NewLastName string `json:"lastname"`
}
if err := c.Bind(&update); err != nil {
panic(err)
}
userRepository := initUser()
if update.NewLastName != "" {
err = userRepository.UpdateLastName(update.NewLastName, uint(id))
if err != nil {
panic(err)
}
}
return c.String(http.StatusAccepted, "updated")
}
func DeleteUser(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
fmt.Println(err)
}
userRepository := initUser()
err = userRepository.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

View File

@ -0,0 +1,74 @@
package handlers
import (
database "app/database"
"app/models"
"app/repositories"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
// Create(w *models.Wishlist) error
// GetList(id uint) ([]models.Wishlist, error)
// Delete(id uint) error
func initWishlist() *repositories.Wishlist_repository {
db := database.Db()
wishRepository := new(repositories.Wishlist_repository)
wishRepository.DB = &db
return wishRepository
}
func CreateWishlist(c echo.Context) error {
wishlist := new(models.Wishlist)
wishlistReposiory := initWishlist()
if err := c.Bind(wishlist); err != nil {
panic(err)
}
err := wishlistReposiory.Create(wishlist)
if err != nil {
panic(err)
}
return c.JSON(http.StatusCreated, wishlist)
}
func GetWishlist(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
wishlistReposiory := initWishlist()
wishlist, err := wishlistReposiory.GetList(uint(id))
if err != nil {
panic(err)
}
return c.JSON(http.StatusAccepted, wishlist)
}
func DeleteWishlist(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
panic(err)
}
wishlistReposiory := initWishlist()
err = wishlistReposiory.Delete(uint(id))
if err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "removed")
}

43
main.go 100644
View File

@ -0,0 +1,43 @@
package main
import (
db "app/database"
_ "app/docs"
route "app/router"
"github.com/labstack/echo/v4"
echoSwagger "github.com/swaggo/echo-swagger"
)
// @title Swagger Example API
// @version 1.0
// @description This is a sample server celler server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8000
// @securityDefinitions.basic BasicAuth
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
func main() {
db.Create_tables()
e := echo.New()
e.GET("/swagger/*", echoSwagger.WrapHandler)
route.UserRoutes(e)
route.ProductRoutes(e)
route.CartRoutes(e)
route.LoginLogout(e)
e.Logger.Fatal(e.Start(":8000"))
}

View File

@ -0,0 +1,55 @@
package middlewares
import (
"app/database"
"app/models"
"app/utils"
"net/http"
"strconv"
"github.com/labstack/echo/v4"
)
func AdminOnly() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
cookie, err := c.Cookie("authorization")
if err != nil {
return err
}
token, err := utils.ParseToken(cookie.Value)
if err != nil {
return err
}
id, err := strconv.Atoi(token)
if err != nil {
return err
}
_, checkuser, err := utils.CheckUserByJwt(uint(id))
if err != nil {
return err
}
if !checkuser {
return echo.ErrNotFound
}
user := new(models.User)
db := database.Db()
if err := db.Where("is_removed = ?", false).Where("user_id = ?", id).First(user).Error; err != nil {
return err
}
// Check if the user has the admin role
if user.Role != "admin" {
return echo.NewHTTPError(http.StatusForbidden, "Access denied")
}
return next(c)
}
}
}

View File

@ -0,0 +1,17 @@
package models
import "time"
type Order_products struct {
Order_products_id uint `gorm:"primaryKey"`
Order_id uint
Order Order `gorm:"references:Order_id"`
Product_id uint
Product Product `gorm:"references:Product_id"`
Price uint64
Quantity_ordered uint
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

16
models/address.go 100644
View File

@ -0,0 +1,16 @@
package models
import "time"
type Address struct {
Address_id uint `gorm:"primaryKey"`
User_id uint
User User `gorm:"references:User_id"`
Address string `gorm:"type:TEXT"`
PostCode string `gorm:"type:varchar(10)"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_active bool
Is_removed bool `gorm:"default:false"`
}

View File

@ -0,0 +1,18 @@
package models
import "time"
type Cart_items struct {
Cart_item_id uint `gorm:"primaryKey"`
Cart_id uint
Cart Carts `gorm:"references:Cart_id"`
Product_id uint
Product Product `gorm:"references:Product_id"`
Quantity uint `gorm:"default:1"`
PricePerUnit uint64
Price uint64
Status string `gorm:"default:pending"`
Created_at time.Time
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

12
models/carts.go 100644
View File

@ -0,0 +1,12 @@
package models
import "time"
type Carts struct {
Cart_id uint `gorm:"primaryKey"`
User_id uint
User User `gorm:"references:User_id"`
Created_at time.Time
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

16
models/comments.go 100644
View File

@ -0,0 +1,16 @@
package models
import "time"
type Comment struct {
Comment_id uint `gorm:"primaryKey"`
User_id uint
User User `gorm:"references:User_id"`
Product_id uint
Product Product `gorm:"references:Product_id"`
Content string `gorm:"type:TEXT"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

14
models/images.go 100644
View File

@ -0,0 +1,14 @@
package models
import "time"
type Images struct {
Img_id uint `gorm:"primary"`
Product_id uint
Product Product `gorm:"references:Product_id"`
Address string `gorm:"type:varchar(255)"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

7
models/jwt.go 100644
View File

@ -0,0 +1,7 @@
package models
type Jwt struct {
Jwt_id uint `gorm:"primaryKey"`
User_id uint
User User `gorm:"references:User_id"`
}

View File

@ -0,0 +1,8 @@
package models
import "github.com/golang-jwt/jwt/v5"
type JwtClaims struct {
Jwt_id uint `json:"jwtID"`
jwt.RegisteredClaims
}

32
models/orders.go 100644
View File

@ -0,0 +1,32 @@
package models
import "time"
// type Order struct {
// Order_id uint `gorm:"primaryKey"`
// User_id uint
// UserRef User `gorm:"foreignKey:User_id"`
// Procuct_id uint
// ProductRef Product `gorm:"foreignKey:Product_id"`
// Price uint64
// Quantity_ordered uint
// Order_date time.Time
// Created_at time.Time
// Updated_at time.Time
// Removed_at time.Time
// Is_removed bool `gorm:"default:false"`
// }
type Order struct {
Order_id uint `gorm:"primaryKey"`
User_id uint
User User `gorm:"references:User_id"`
TransportationFee uint64
Tax uint64
ProductsTotalPrice uint64
TotalPrice uint64
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

15
models/phone.go 100644
View File

@ -0,0 +1,15 @@
package models
import "time"
type Phone struct {
Phone_id uint `gorm:"primaryKey"`
User_id uint
User User `gorm:"references:User_id"`
Phone_number string `gorm:"type:varchar(11)"`
BackUp_nummber string `gorm:"type:varchar(11)"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

View File

@ -0,0 +1,13 @@
package models
import "time"
type PriceHistory struct {
Price_id uint
Product_id uint
Product Product `gorm:"references:Product_id"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

17
models/product.go 100644
View File

@ -0,0 +1,17 @@
package models
import "time"
type Product struct {
Product_id uint `gorm:"primaryKey"`
Name string `gorm:"type:varchar(255)"`
Description string `gorm:"type:TEXT"`
Warranty string `gorm:"type:varchar(255)"`
Quantity uint
Category string `gorm:"type:varchar(255)"`
Price uint64
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

15
models/specs.go 100644
View File

@ -0,0 +1,15 @@
package models
import "time"
type Specs struct {
Specs_id uint `gorm:"primaryKey"`
Product_id uint
Product Product `gorm:"references:Product_id"`
Type string `gorm:"type:varchar(255)"`
Value string `gorm:"type:varchar(255)"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

20
models/user.go 100644
View File

@ -0,0 +1,20 @@
package models
import "time"
type User struct {
User_id uint `gorm:"primaryKey"`
Username string `gorm:"type:varchar(100)"`
Email string `gorm:"type:varchar(255)"`
Password string `gorm:"type:varchar(255)"`
CellPhone_number string `gorm:"unique;type:varchar(11)"`
Role string `gorm:"type:varchar(50)"`
National_code string `gorm:"type:varchar(10)"`
BirthDay string `gorm:"type:varchar(255)"`
First_name string `gorm:"type:varchar(50)"`
Last_name string `gorm:"type:varchar(50)"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

15
models/wishlist.go 100644
View File

@ -0,0 +1,15 @@
package models
import "time"
type Wishlist struct {
Wishlist_id uint `gorm:"primaryKey"`
User_id uint
User User `gorm:"references:User_id"`
Product_id uint
Product Product `gorm:"references:Product_id"`
Created_at time.Time
Updated_at time.Time `gorm:"default:null"`
Removed_at time.Time `gorm:"default:null"`
Is_removed bool `gorm:"default:false"`
}

View File

@ -0,0 +1,64 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Address interface {
Create(a *models.Address) error
GetAddresses(id uint) ([]models.Address, error)
UpdateAddress(address string, id uint) error
UpdatePostCode(newPostCode string, id uint) error
Delete(id uint) error
}
type Address_repository struct {
DB *gorm.DB
}
func newAddressRepository(db *gorm.DB) Address {
return &Address_repository{DB: db}
}
func (r *Address_repository) Create(address *models.Address) error {
if err := r.DB.Create(&address).Error; err != nil {
return err
}
return nil
}
func (r *Address_repository) GetAddresses(id uint) ([]models.Address, error) {
var address []models.Address
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&address).Error; err != nil {
return nil, err
}
return address, nil
}
func (r *Address_repository) UpdateAddress(newAddress string, id uint) error {
var address models.Address
if err := r.DB.Where("is_removed = ?", false).Where("address_id = ? ", id).Model(&address).Update("address", newAddress).Error; err != nil {
return err
}
return nil
}
func (r *Address_repository) UpdatePostCode(newPostCode string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("address_id = ? ", id).Model(&user).Update("post_code", newPostCode).Error; err != nil {
return err
}
return nil
}
func (r *Address_repository) Delete(id uint) error {
var address models.Address
if err := r.DB.Where("address_id = ?", id).Model(&address).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,100 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Carts_items interface {
Create(*models.Cart_items) error
GetItems(id uint, status string) ([]models.Cart_items, error)
IncreaseQuantity(id uint) error
DecreaseQuantity(id uint) error
UpdateStatus(id uint) error
Remove(id uint) error
}
type Cart_items_repository struct {
DB *gorm.DB
}
func newCartsItemsRepository(db *gorm.DB) Carts_items {
return &Cart_items_repository{DB: db}
}
func (r *Cart_items_repository) Create(cart_items *models.Cart_items) error {
if err := r.DB.Create(&cart_items).Error; err != nil {
return err
}
return nil
}
func (r *Cart_items_repository) GetItems(id uint, status string) ([]models.Cart_items, error) {
var items []models.Cart_items
if err := r.DB.Where("is_removed = ?", false).Where("cart_id = ? ", id).Where("status = ?", status).Find(&items).Error; err != nil {
return nil, err
}
return items, nil
}
func (r *Cart_items_repository) IncreaseQuantity(id uint) error {
var item models.Cart_items
if err := r.DB.Where("is_removed = ?", false).Where("status = ? ", "pending").Where("cart_item_id = ?", id).First(&item).Error; err != nil {
return err
}
quantity := item.Quantity + 1
if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&item).Update("quantity", quantity).Error; err != nil {
return err
}
if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&item).Update("price", item.PricePerUnit*uint64(quantity)).Error; err != nil {
return err
}
return nil
}
func (r *Cart_items_repository) DecreaseQuantity(id uint) error {
var item, temp models.Cart_items
if err := r.DB.Where("is_removed = ?", false).Where("status = pending").Where("cart_item_id = ?", id).First(&item).Error; err != nil {
return err
}
if item.Quantity > 1 {
quantity := item.Quantity - 1
price := item.Price * uint64(quantity)
if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&temp).Update("quantity", quantity).Error; err != nil {
return err
}
if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&temp).Update("price", price).Error; err != nil {
return err
}
}
return nil
}
func (r *Cart_items_repository) UpdateStatus(id uint) error {
var item models.Cart_items
if err := r.DB.Where("is_removed = ?", false).Where("cart_item_id = ?", id).Model(&item).Update("status", "purchased").Error; err != nil {
return err
}
return nil
}
func (r *Cart_items_repository) Remove(id uint) error {
var cart_items models.Cart_items
if err := r.DB.Where("cart_item_id = ?", id).Model(&cart_items).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,37 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Carts interface {
Create(*models.Carts) error
GetCart(id uint) (*models.Carts, error)
}
type Carts_repository struct {
DB *gorm.DB
}
func newCartsRepository(db *gorm.DB) Carts {
return &Carts_repository{DB: db}
}
func (r *Carts_repository) Create(carts *models.Carts) error {
if err := r.DB.Create(&carts).Error; err != nil {
return err
}
return nil
}
func (r *Carts_repository) GetCart(id uint) (*models.Carts, error) {
var cart models.Carts
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).First(&cart).Error; err != nil {
return nil, err
}
return &cart, nil
}

View File

@ -0,0 +1,67 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Comment interface {
Create(c *models.Comment) error
GetUserComments(id uint) ([]models.Comment, error)
GetProductComments(id uint) ([]models.Comment, error)
UpdateContent(id uint, content string) error
Delete(id uint) error
}
type Comment_repository struct {
DB *gorm.DB
}
func newCommentRepository(db *gorm.DB) Comment {
return &Comment_repository{DB: db}
}
func (r *Comment_repository) Create(comment *models.Comment) error {
if err := r.DB.Create(&comment).Error; err != nil {
return err
}
return nil
}
func (r *Comment_repository) GetUserComments(id uint) ([]models.Comment, error) {
var comments []models.Comment
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&comments).Error; err != nil {
return nil, err
}
return comments, nil
}
func (r *Comment_repository) GetProductComments(id uint) ([]models.Comment, error) {
var comments []models.Comment
if err := r.DB.Where("is_removed = ?", false).Where("product_id = ?", id).Find(&comments).Error; err != nil {
return nil, err
}
return comments, nil
}
func (r *Comment_repository) UpdateContent(id uint, content string) error {
var comments models.Comment
if err := r.DB.Where("is_removed = ? ", false).Where("comment_id = ?", id).Model(comments).Update("content", content).Error; err != nil {
return err
}
return nil
}
func (r *Comment_repository) Delete(id uint) error {
var comments models.Comment
if err := r.DB.Where("comment_id = ?", id).Model(&comments).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,35 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Order_Product interface {
Create(op *models.Order_products) error
Delete(id uint) error
}
type Order_Product_repository struct {
DB *gorm.DB
}
func newOrderProductRepository(db *gorm.DB) Order_Product {
return &Order_Product_repository{DB: db}
}
func (r *Order_Product_repository) Create(op *models.Order_products) error {
if err := r.DB.Create(&op).Error; err != nil {
return err
}
return nil
}
func (r *Order_Product_repository) Delete(id uint) error {
var op models.Order_products
if err := r.DB.Where("order_products_id = ?", id).Model(&op).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,57 @@
package repositories
import (
"app/models"
"time"
"gorm.io/gorm"
)
type Orders interface {
Create(o *models.Order) error
GetOrders(id uint) ([]models.Order, error)
GetOrdersByDate(start time.Time, end time.Time) ([]models.Order, error)
Delete(id uint) error
}
type Orders_repository struct {
DB *gorm.DB
}
func newOrdersRepository(db *gorm.DB) Orders {
return &Orders_repository{DB: db}
}
func (r *Orders_repository) Create(order *models.Order) error {
if err := r.DB.Create(&order).Error; err != nil {
return err
}
return nil
}
func (r *Orders_repository) GetOrders(id uint) ([]models.Order, error) {
var orders []models.Order
if err := r.DB.Where("is_removed = ?", false).Where("user_id").Find(&orders).Error; err != nil {
return nil, err
}
return orders, nil
}
func (r *Orders_repository) GetOrdersByDate(start time.Time, end time.Time) ([]models.Order, error) {
var orders []models.Order
if err := r.DB.Where("is_removed = ?", false).Where("created_at BETWEEN ? and ?", start, end).Find(&orders).Error; err != nil {
return nil, err
}
return orders, nil
}
func (r *Orders_repository) Delete(id uint) error {
var order models.Order
if err := r.DB.Where("order_id = ?", id).Model(&order).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,67 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Phone interface {
Create(p *models.Phone) error
GetPhones(id uint) (*models.Phone, error)
UpdatePhoneNumber(number string, id uint) error
UpdateCellPhone(number string, id uint) error
Delete(id uint) error
}
type Phone_repository struct {
DB *gorm.DB
}
func newPhoneRepository(db *gorm.DB) Phone {
return &Phone_repository{DB: db}
}
func (r *Phone_repository) Create(phone *models.Phone) error {
if err := r.DB.Create(&phone).Error; err != nil {
return err
}
return nil
}
func (r *Phone_repository) GetPhones(id uint) (*models.Phone, error) {
var phone models.Phone
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&phone).Error; err != nil {
return nil, err
}
return &phone, nil
}
func (r *Phone_repository) UpdatePhoneNumber(number string, id uint) error {
var phone models.Phone
if err := r.DB.Where("is_removed = ? ", false).Where("phone_id = ? ", id).Model(&phone).Update("phone_number", number).Error; err != nil {
return err
}
return nil
}
func (r *Phone_repository) UpdateCellPhone(number string, id uint) error {
var phone models.Phone
if err := r.DB.Where("is_removed = ? ", false).Where("phone_id = ? ", id).Model(&phone).Update("cell_phone_number", number).Error; err != nil {
return err
}
return nil
}
func (r *Phone_repository) Delete(id uint) error {
var phone models.Phone
if err := r.DB.Where("phone_id = ?", id).Model(&phone).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,129 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Product interface {
Create(p *models.Product) error
GetByName(name string) ([]models.Product, error)
GetByID(id uint) (*models.Product, error)
GetByCategory(category string) ([]models.Product, error)
GetQuantity(id uint) (uint, error)
UpdateName(name string, id uint) error
UpdateDescription(content string, id uint) error
UpdateWarranty(name string, id uint) error
UpdateQuantity(quantity uint, id uint) error
UpdateCategory(category string, id uint) error
UpdatePrice(price uint64, id uint) error
Delete(id uint) error
}
type Product_repository struct {
DB *gorm.DB
}
func newProductRepository(db *gorm.DB) Product {
return &Product_repository{DB: db}
}
func (r *Product_repository) Create(p *models.Product) error {
if err := r.DB.Create(&p).Error; err != nil {
return err
}
return nil
}
func (r *Product_repository) GetByName(name string) ([]models.Product, error) {
var product []models.Product
if err := r.DB.Where("is_removed = ?", false).Where("name = ? ", name).Find(&product).Error; err != nil {
return nil, err
}
return product, nil
}
func (r *Product_repository) GetByID(id uint) (*models.Product, error) {
var product models.Product
if err := r.DB.Where("is_removed = ?", false).Where("product_id = ? ", id).First(&product).Error; err != nil {
return nil, err
}
return &product, nil
}
func (r *Product_repository) GetByCategory(category string) ([]models.Product, error) {
var product []models.Product
if err := r.DB.Where("is_removed = ?", false).Where("category = ?", category).Find(&product).Error; err != nil {
return nil, err
}
return product, nil
}
func (r *Product_repository) GetQuantity(id uint) (uint, error) {
var product models.Product
if err := r.DB.Where("is_removed = ?", false).Where("product_id = ?", id).First(&product).Error; err != nil {
return 0, err
}
return product.Quantity, nil
}
func (r *Product_repository) UpdateName(name string, id uint) error {
var product models.Product
if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("name", name).Error; err != nil {
return err
}
return nil
}
func (r *Product_repository) UpdateDescription(content string, id uint) error {
var product models.Product
if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("description", content).Error; err != nil {
return err
}
return nil
}
func (r *Product_repository) UpdateWarranty(name string, id uint) error {
var product models.Product
if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("warranty", name).Error; err != nil {
return err
}
return nil
}
func (r *Product_repository) UpdateQuantity(quantity uint, id uint) error {
var product models.Product
if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("quantity", quantity).Error; err != nil {
return err
}
return nil
}
func (r *Product_repository) UpdateCategory(category string, id uint) error {
var product models.Product
if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("category", category).Error; err != nil {
return err
}
return nil
}
func (r *Product_repository) UpdatePrice(price uint64, id uint) error {
var product models.Product
if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("price", price).Error; err != nil {
return err
}
return nil
}
func (r *Product_repository) Delete(id uint) error {
var product models.Product
if err := r.DB.Where("product_id = ?", id).Model(&product).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,60 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Specs interface {
Create(s *models.Specs) error
GetSpecs(id uint) (*models.Specs, error)
UpdateType(newType string, id uint) error
UpdateValue(newValue string, id uint) error
Delete(id uint) error
}
type Specs_repository struct {
DB *gorm.DB
}
func newSpecsRepository(db *gorm.DB) Specs {
return &Specs_repository{DB: db}
}
func (r *Specs_repository) Create(s *models.Specs) error {
if err := r.DB.Create(&s).Error; err != nil {
return err
}
return nil
}
func (r *Specs_repository) GetSpecs(id uint) (*models.Specs, error) {
var specs models.Specs
if err := r.DB.Where("is_removed = ?", false).Where("product_id = ?", id).Find(&specs).Error; err != nil {
return nil, err
}
return &specs, nil
}
func (r *Specs_repository) UpdateType(newType string, id uint) error {
var specs models.Specs
if err := r.DB.Where("is_deleted = ?", false).Where("specs_id = ?", id).Model(&specs).Update("type", newType).Error; err != nil {
return err
}
return nil
}
func (r *Specs_repository) UpdateValue(newValue string, id uint) error {
var specs models.Specs
if err := r.DB.Where("is_deleted = ?", false).Where("specs_id = ?", id).Model(&specs).Update("value", newValue).Error; err != nil {
return err
}
return nil
}
func (r *Specs_repository) Delete(id uint) error {
var specs models.Specs
if err := r.DB.Where("specs_id = ?", id).Model(&specs).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,144 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type User interface {
Create(u *models.User) error
//GetAll()([]models.User,error)
GetByName(name string) ([]models.User, error)
GetByID(id uint) (*models.User, error)
UpdateUserName(name string, id uint) error
UpdateEmail(email string, id uint) error
UpdatePassword(password string, id uint) error
UpdateRole(newRole string, id uint) error
UpdateNationalCode(newCode string, id uint) error
UpdateBirthDay(newBirthDay string, id uint) error
UpdateFirstName(firstName string, id uint) error
UpdateLastName(lastName string, id uint) error
Delete(id uint) error
}
type User_repository struct {
DB *gorm.DB
}
func newUserRepository(db *gorm.DB) User {
return &User_repository{DB: db}
}
func (r *User_repository) Create(user *models.User) error {
// if user.Password != "" {
// pw := user.Password
// hashpw, err := utils.HashPW(pw)
// if err != nil {
// return err
// }
// user.Password = hashpw
// }
if err := r.DB.Create(&user).Error; err != nil {
return err
}
return nil
}
// func (r *User_repository)GetAll()([]models.User,error){
// var user []models.User
// if err := r.DB.Find(&user).
// }
func (r *User_repository) GetByName(name string) ([]models.User, error) {
var user []models.User
if err := r.DB.Where("is_removed = ?", false).Where("username = ? ", name).Limit(12).Find(&user).Error; err != nil {
return nil, err
}
return user, nil
}
func (r *User_repository) GetByID(id uint) (*models.User, error) {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).First(&user).Error; err != nil {
return nil, err
}
return &user, nil
}
func (r *User_repository) UpdateUserName(name string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("username", name).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) UpdateEmail(email string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("email", email).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) UpdatePassword(password string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("password", password).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) UpdateRole(newRole string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("role", newRole).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) UpdateNationalCode(newCode string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("national_code", newCode).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) UpdateBirthDay(newBirthDay string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("birth_day", newBirthDay).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) UpdateFirstName(firstName string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("first_name", firstName).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) UpdateLastName(lastName string, id uint) error {
var user models.User
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("last_name", lastName).Error; err != nil {
return err
}
return nil
}
func (r *User_repository) Delete(id uint) error {
var user models.User
if err := r.DB.Where("User_id = ?", id).Model(&user).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,47 @@
package repositories
import (
"app/models"
"gorm.io/gorm"
)
type Wishlist interface {
Create(w *models.Wishlist) error
GetList(id uint) ([]models.Wishlist, error)
Delete(id uint) error
}
type Wishlist_repository struct {
DB *gorm.DB
}
func newWishlistRepository(db *gorm.DB) Wishlist {
return &Wishlist_repository{DB: db}
}
func (r *Wishlist_repository) Create(wishlist *models.Wishlist) error {
if err := r.DB.Create(&wishlist).Error; err != nil {
return err
}
return nil
}
func (r *Wishlist_repository) GetList(id uint) ([]models.Wishlist, error) {
var wishlist []models.Wishlist
if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&wishlist).Error; err != nil {
return nil, err
}
return wishlist, nil
}
func (r *Wishlist_repository) Delete(id uint) error {
var wishlist models.Wishlist
if err := r.DB.Where("wishlist_id = ?", id).Model(&wishlist).Update("is_removed", true).Error; err != nil {
return err
}
return nil
}

123
router/routers.go 100644
View File

@ -0,0 +1,123 @@
package router
import (
"app/handlers"
"app/middlewares"
login "app/services"
"github.com/labstack/echo/v4"
)
func UserRoutes(e *echo.Echo) {
users := e.Group("/users")
users.POST("/", handlers.RegisterUser)
users.GET("/usernames/:name", handlers.GetSameUserNames)
users.GET("/:id", handlers.GetUserByID)
users.PUT("/username/:id", handlers.UpdateUserName)
users.PUT("/email/:id", handlers.UpdateEmail)
users.PUT("/password/:id", handlers.UpdatePassword)
users.PUT("/role/:id", handlers.UpdateRole)
users.PUT("/nationalcode/:id", handlers.UpdateNationalCode)
users.PUT("/birthday/:id", handlers.UpdateBirthDay)
users.PUT("/firstname/:id", handlers.UpdateFirstName)
users.PUT("/lastname/:id", handlers.UpdateLastName)
users.PUT("/postcode/:id", handlers.UpdatePostCode)
users.DELETE("/:id", handlers.DeleteUser)
}
// create new user ===> post : users/
// get user by id ===> get : users/23
// get users by name ===> get : users/nima
// update username ===> put : users/username send json
// update email ===> put : users/email send json
// update password ===> put : users/password send json
// update role ===> put : users/role send json
// update nationalCode ===> put : users/nationalcode send json
// update birthday ===> put : users/birthday send json
// update firstname ===> put : users/firstname send json
// update lastname ===> put : users/lastname send json
// update postcode ===> put : users/postcode send json
// delete user ===> delete : users/23
func ProductRoutes(e *echo.Echo) {
products := e.Group("/products")
products.POST("/", handlers.CreateProduct)
products.GET("/:name", handlers.GetProductByName)
products.GET("/:id", handlers.GetProductByID)
products.GET("/category/:name", handlers.GetProductByCategory)
products.PUT("/productname/:id", handlers.UpdateProductName)
products.PUT("/description/:id", handlers.UpdateDescription)
products.PUT("/warranty/:id", handlers.UpdateWarranty)
products.PUT("/quantity/:id", handlers.UpdateQuantity)
products.PUT("/category/:id", handlers.UpdateCategory)
products.PUT("/price/:id", handlers.UpdatePrice)
products.DELETE("/:id", handlers.DeleteProduct)
}
func OrderRoutes(e *echo.Echo) {
orders := e.Group("/orders")
//orders.POST("/", handlers.CreateOrder)
orders.GET("/:id", handlers.GetUserOrders)
orders.DELETE("/:id", handlers.DeleteOrder)
}
func AddressRoutes(e *echo.Echo) {
address := e.Group("/address")
address.POST("/", handlers.CreateAddress)
address.GET("/:id", handlers.GetUserAddresses)
address.PUT("/:id", handlers.UpdateAddress)
address.DELETE("/:id", handlers.DeleteAddress)
}
func CommentRoutes(e *echo.Echo) {
comments := e.Group("/comments")
comments.POST("/", handlers.CreateComment)
comments.GET("/user/:id", handlers.GetUserComments)
comments.GET("/product/:id", handlers.GetProductComments)
comments.PUT("/:id", handlers.UpdateComment)
comments.DELETE("/:id", handlers.DeleteComment)
}
func SpecsRoutes(e *echo.Echo) {
specs := e.Group("/specs")
specs.POST("/", handlers.CreateSpecs)
specs.GET("/:id", handlers.GetSpecs)
specs.PUT("/type/:id", handlers.UpdateType)
specs.PUT("/value/:id", handlers.UpdateValue)
specs.DELETE("/:id", handlers.DeleteSpecs)
}
func PhoneRoutes(e *echo.Echo) {
phones := e.Group("/phones")
//phones.POST("/", handlers.CreatePhone)
phones.GET("/:id", handlers.GetUserPhoneNumbers)
phones.PUT("/phonenumber/:id", handlers.UpdatePhoneNumber)
phones.PUT("/cellphonenumber/:id", handlers.UpdateCellPhoneNumber)
phones.DELETE("/:id", handlers.DeletePhone)
}
func WishlistRoutes(e *echo.Echo) {
wishlist := e.Group("/wishlist")
wishlist.POST("/", handlers.CreateWishlist)
wishlist.GET("/:id", handlers.GetWishlist)
wishlist.DELETE("/:id", handlers.DeleteWishlist)
}
func CartRoutes(e *echo.Echo) {
cart := e.Group("/cart")
cart.POST("/", handlers.Create_cart_item)
cart.GET("/:id", handlers.GetCartItems)
cart.PUT("/:id", handlers.UpdateItemStatus)
cart.DELETE("/:id", handlers.Remove_cart_item)
}
func LoginLogout(e *echo.Echo) {
e.POST("/login", login.LoginByEmail)
e.GET("/logout", login.Logout)
e.GET("/test", login.Test)
admin := e.Group("/admin")
admin.Use(middlewares.AdminOnly())
}

View File

@ -0,0 +1,63 @@
package services
import (
"app/utils"
"net/http"
"time"
"github.com/labstack/echo/v4"
)
func LoginByEmail(c echo.Context) error {
var info struct {
Email string `json:"email"`
Password string `json:"password"`
}
if err := c.Bind(&info); err != nil {
return err
}
if info.Email == "" || info.Password == "" {
return c.String(http.StatusUnauthorized, "pls check username and password")
}
user, err := utils.GetUserByEmail(info.Email)
if err != nil {
return err
}
checkpw, err := utils.Match(info.Password, info.Email)
if err != nil {
return err
}
if !checkpw {
return c.String(http.StatusUnauthorized, "pls check username and password")
} else {
err = utils.CheckToken(c)
if err == echo.ErrUnauthorized {
utils.GenerateToken(c, *user)
}
return c.JSON(http.StatusOK, map[string]string{
"message": "Login successful",
})
}
}
func Logout(c echo.Context) error {
coockie := new(http.Cookie)
coockie.Name = "authorization"
coockie.Value = ""
// coockie.HttpOnly = true
// coockie.Secure = true
coockie.Expires = time.Now().Add(time.Hour * 24)
c.SetCookie(coockie)
return c.JSON(http.StatusOK, map[string]string{
"message": "Logout successful",
})
}

21
services/sms.go 100644
View File

@ -0,0 +1,21 @@
package services
import (
"net/http"
"github.com/kavenegar/kavenegar-go"
"github.com/labstack/echo/v4"
)
func Test(c echo.Context) error {
api := kavenegar.New("55446E4B7564625A703969476D68315636464871325A52586D6C6E4C6C445A4F4E2B4D753637716A4E30593D")
sender := "1000596446"
receptor := []string{"09356684212"}
if _, err := api.Message.Send(sender, receptor, "hello-go", nil); err != nil {
panic(err)
}
return c.String(http.StatusAccepted, "code sent")
}

View File

@ -0,0 +1,26 @@
package utils
import (
"app/database"
"app/models"
"errors"
)
var (
ErrEmailExists = errors.New("email already exists")
)
func CheckEmail(email string) (bool, error) {
db := database.Db()
var user models.User
var count int64
if err := db.Model(user).Where("email = ?", email).Count(&count).Error; err != nil {
return true, err
}
if count > 0 {
return true, ErrEmailExists
}
return false, nil
}

87
utils/checkHash.go 100644
View File

@ -0,0 +1,87 @@
package utils
import (
"crypto/subtle"
"encoding/base64"
"errors"
"fmt"
"strings"
"golang.org/x/crypto/argon2"
)
var (
ErrInvalidHash = errors.New("the encoded hash is not in the correct format")
ErrIncompatibleVersion = errors.New("incompatible version of argon2")
)
func Match(password string, email string) (bool, error) {
user, err := GetUserByEmail(email)
if err != nil {
return false, err
}
check, err := comparePasswordAndHash(password, user.Password)
if err != nil {
return false, err
}
return check, nil
}
func comparePasswordAndHash(password, encodedHash string) (match bool, err error) {
// Extract the parameters, salt and derived key from the encoded password
// hash.
p, salt, hash, err := decodeHash(encodedHash)
if err != nil {
return false, err
}
// Derive the key from the other password using the same parameters.
otherHash := argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength)
// Check that the contents of the hashed passwords are identical. Note
// that we are using the subtle.ConstantTimeCompare() function for this
// to help prevent timing attacks.
if subtle.ConstantTimeCompare(hash, otherHash) == 1 {
return true, nil
}
return false, nil
}
func decodeHash(encodedHash string) (p *params, salt, hash []byte, err error) {
vals := strings.Split(encodedHash, "$")
if len(vals) != 6 {
return nil, nil, nil, ErrInvalidHash
}
var version int
_, err = fmt.Sscanf(vals[2], "v=%d", &version)
if err != nil {
return nil, nil, nil, err
}
if version != argon2.Version {
return nil, nil, nil, ErrIncompatibleVersion
}
p = &params{}
_, err = fmt.Sscanf(vals[3], "m=%d,t=%d,p=%d", &p.memory, &p.iterations, &p.parallelism)
if err != nil {
return nil, nil, nil, err
}
salt, err = base64.RawStdEncoding.Strict().DecodeString(vals[4])
if err != nil {
return nil, nil, nil, err
}
p.saltLength = uint32(len(salt))
hash, err = base64.RawStdEncoding.Strict().DecodeString(vals[5])
if err != nil {
return nil, nil, nil, err
}
p.keyLength = uint32(len(hash))
return p, salt, hash, nil
}

36
utils/checkUser.go 100644
View File

@ -0,0 +1,36 @@
package utils
import (
"app/database"
"app/models"
"gorm.io/gorm"
)
func CheckUserByJwt(jwtID uint) (uint, bool, error) {
db := database.Db()
var jwt models.Jwt
result := db.First(&jwt, jwtID)
if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound {
return 0, false, nil
}
return 0, false, result.Error
}
return jwt.User_id, true, nil
}
func CheckUserByID(id uint) (bool, error) {
db := database.Db()
var jwt models.Jwt
result := db.Where("user_id = ?", id).First(&jwt)
if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound {
return false, nil
}
return false, result.Error
}
return true, nil
}

View File

@ -0,0 +1,38 @@
package utils
import (
"app/models"
"os"
"github.com/golang-jwt/jwt/v5"
"github.com/joho/godotenv"
"github.com/labstack/echo/v4"
)
func CheckToken(c echo.Context) error {
err := godotenv.Load("./config/.env")
if err != nil {
return err
}
secret := os.Getenv("SECRET")
cookie, err := c.Cookie("authorization")
if err != nil {
return echo.ErrUnauthorized
}
token, err := jwt.ParseWithClaims(cookie.Value, &models.JwtClaims{}, func(token *jwt.Token) (interface{}, error) {
// Provide the same key used for signing the token
return []byte(secret), nil
})
if err != nil {
// Handle error, failed to parse the token
return echo.ErrUnauthorized
}
if _, ok := token.Claims.(*models.JwtClaims); !ok || !token.Valid {
return echo.ErrUnauthorized
}
return nil
}

View File

@ -0,0 +1,72 @@
package utils
import (
"app/database"
"app/models"
"fmt"
"net/http"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/joho/godotenv"
"github.com/labstack/echo/v4"
)
func GenerateToken(c echo.Context, user models.User) (string, error) {
err := godotenv.Load("./config/.env")
if err != nil {
return "", err
}
secret := os.Getenv("SECRET")
db := database.Db()
isExists, err := CheckUserByID(user.User_id)
if err != nil {
return "", err
}
fmt.Println(isExists)
var jwtRecord models.Jwt
if !isExists {
jwtRecord.User_id = user.User_id
err := db.Create(&jwtRecord).Error
if err != nil {
return "", err
}
} else {
if err = db.Where("user_id = ? ", user.User_id).First(&jwtRecord).Error; err != nil {
return "", err
}
}
var tempJwt models.Jwt
if err = db.Where("user_id = ?", jwtRecord.User_id).First(&tempJwt).Error; err != nil {
return "", err
}
claims := &models.JwtClaims{
Jwt_id: tempJwt.Jwt_id,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 168)),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
sToken, err := token.SignedString([]byte(secret))
if err != nil {
return "", err
}
coockie := new(http.Cookie)
coockie.Name = "authorization"
coockie.Value = sToken
// coockie.HttpOnly = true
// coockie.Secure = true
coockie.Expires = time.Now().Add(time.Hour * 24)
c.SetCookie(coockie)
return sToken, nil
}

View File

@ -0,0 +1,15 @@
package utils
import (
"app/database"
"app/models"
)
func GetUserByEmail(email string) (*models.User, error) {
user := new(models.User)
db := database.Db()
if err := db.Where("is_removed = ?", false).Where("email = ?", email).First(&user).Error; err != nil {
return nil, err
}
return user, nil
}

View File

@ -0,0 +1,17 @@
package utils
import (
"app/database"
"app/models"
)
func GetByPhoneNumber(number string) (*models.User, error) {
db := database.Db()
user := new(models.User)
if err := db.Where("is_removed = ?", false).Where("cell_phone_number = ?", number).First(&user).Error; err != nil {
return nil, err
}
return user, nil
}

65
utils/hash.go 100644
View File

@ -0,0 +1,65 @@
package utils
import (
"crypto/rand"
"encoding/base64"
"fmt"
"golang.org/x/crypto/argon2"
)
type params struct {
memory uint32
iterations uint32
parallelism uint8
saltLength uint32
keyLength uint32
}
func HashPW(password string) (string, error) {
// Establish the parameters to use for Argon2.
p := &params{
memory: 128 * 1024,
iterations: 3,
parallelism: 2,
saltLength: 16,
keyLength: 32,
}
// Pass the plaintext password and parameters to our generateFromPassword
// helper function.
hash, err := generateFromPassword(password, p)
if err != nil {
return "", err
}
return hash, nil
}
func generateFromPassword(password string, p *params) (encodedHash string, err error) {
salt, err := generateRandomBytes(p.saltLength)
if err != nil {
return "", err
}
hash := argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength)
// Base64 encode the salt and hashed password.
b64Salt := base64.RawStdEncoding.EncodeToString(salt)
b64Hash := base64.RawStdEncoding.EncodeToString(hash)
// Return a string using the standard encoded hash representation.
encodedHash = fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", argon2.Version, p.memory, p.iterations, p.parallelism, b64Salt, b64Hash)
return encodedHash, nil
}
func generateRandomBytes(n uint32) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
if err != nil {
return nil, err
}
return b, nil
}

View File

@ -0,0 +1,40 @@
package utils
import (
"app/models"
"fmt"
"os"
"strconv"
"github.com/golang-jwt/jwt/v5"
"github.com/joho/godotenv"
)
func ParseToken(tokenString string) (string, error) {
err := godotenv.Load("./config/.env")
if err != nil {
return "", err
}
secret := os.Getenv("SECRET")
claims := new(models.JwtClaims)
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
// Provide the same key used for signing the token
return []byte(secret), nil
})
if err != nil {
// Handle error, failed to parse the token
return "", err
}
if !token.Valid {
// Handle invalid token
return "", fmt.Errorf("invalid token")
}
fmt.Println(claims)
return strconv.FormatUint(uint64(claims.Jwt_id), 10), nil
}

View File

@ -0,0 +1,19 @@
package utils
import (
"app/database"
"app/models"
)
func GetProductCount(id int64, cart_id uint) (uint, error) {
var count int64
db := database.Db()
var product models.Cart_items
// Query the count of products with the given name
if err := db.Model(&product).Where("product_id = ?", id).Where("is_removed = ?", false).Where("status = ? ", "pending").Where("cart_id = ?", cart_id).Count(&count).Error; err != nil {
return 0, err
}
return uint(count), nil
}