Browse Source

predzaschita

Alec 3 years ago
parent
commit
4e8b5925f8

+ 94 - 0
back/infa.go

@@ -0,0 +1,94 @@
+package back
+
+import "errors"
+
+// InformationMass
+
+type informationMass struct {
+	Infa string `json:"Link"`
+
+	Rows []string
+}
+
+func prepareInfa() []string {
+	var e error
+	var elist []string
+
+	queries["Insert@Infa@"], e = db.Prepare(`INSERT INTO "InformationMass" ("infa", "published") VALUES($1, CURRENT_TIMESTAMP)`)
+	if e != nil {
+		elist = append(elist, e.Error())
+	}
+
+	queries["Select@Infa@"], e = db.Prepare(`SELECT "infa" FROM "InformationMass" ORDER BY "published" DESC`)
+	if e != nil {
+		elist = append(elist, e.Error())
+	}
+
+	queries["Insert@Record@"], e = db.Prepare(`INSERT INTO "Record"("Name", "Passport", "Phone", "Cause") VALUES ($1, $2, $3, $4) RETURNING "ID"`)
+	if e != nil {
+		elist = append(elist, "[Insert@Record@] - "+e.Error())
+	}
+
+	queries["Insert@TimeRecord@"], e = db.Prepare(`INSERT INTO "TimeRecord"("Date", "Time", "Record") VALUES($1, $2, $3)`)
+	if e != nil {
+		elist = append(elist, "[Insert@TimeRecord@] - "+e.Error())
+	}
+
+	queries["Update@TimeRecord@"], e = db.Prepare(`UPDATE "TimeRecord" SET "Record"=$1 WHERE "Date"=$2 AND "Time"=$3`)
+	if e != nil {
+		elist = append(elist, "[Insert@TimeRecord@] - "+e.Error())
+	}
+
+	queries["Select@TimeRecord@Times"], e = db.Prepare(`SELECT "Time" FROM "TimeRecord" WHERE "Date"=$1 AND "Record" IS NULL`)
+	if e != nil {
+		elist = append(elist, "[Select@TimeRecord@Times] - "+e.Error())
+	}
+
+	queries["Select#Order#"], e = db.Prepare(`SELECT o."ID", o."Name", o."Passport", o."Phone", o."Cause", a."Date", a."Time" FROM "Record" AS o INNER JOIN "TimeRecord" AS a ON o."ID"=a."Record"
+	ORDER BY a."Date" ASC, a."Time"`)
+	if e != nil {
+		elist = append(elist, "Select#Order#"+e.Error())
+	}
+
+	return elist
+}
+
+func (m *informationMass) Insert() error {
+	stmt, ok := queries["Insert@Infa@"]
+	if !ok {
+		return errors.New("Запрос Insert@Infa@ не найден")
+	}
+
+	_, e := stmt.Exec(m.Infa)
+	if e != nil {
+		return e
+	}
+
+	return nil
+}
+
+func (m *informationMass) Select() error {
+	stmt, ok := queries["Select@Infa@"]
+	if !ok {
+		return errors.New("Запрос Select@Infa@ не найден")
+	}
+
+	rows, e := stmt.Query()
+	if e != nil {
+		return e
+	}
+	defer rows.Close()
+
+	var infa string
+
+	for rows.Next() {
+		e = rows.Scan(&infa)
+		if e != nil {
+			return e
+		}
+
+		m.Rows = append(m.Rows, infa)
+	}
+
+	return nil
+}

+ 1 - 0
back/pg.go

@@ -35,6 +35,7 @@ func prerareQueries() {
 	ebox = append(ebox, prepareQueriesMaterial()...)
 	ebox = append(ebox, prepareQueriesDocument()...)
 	ebox = append(ebox, prepareQueriesSession()...)
+	ebox = append(ebox, prepareInfa()...)
 
 	if len(ebox) > 0 {
 		logger.Println("ERROR PREPARATION QUERIES")

+ 376 - 3
back/router.go

@@ -1,8 +1,11 @@
 package back
 
 import (
+	"database/sql"
+	"errors"
 	"fmt"
 	"strconv"
+	"time"
 
 	"github.com/gin-gonic/contrib/sessions"
 	"github.com/gin-gonic/contrib/static"
@@ -60,6 +63,9 @@ func init() {
 		Setting.HTML+"404.html",
 		Setting.HTML+"position.html",
 		Setting.HTML+"BigBoss.html",
+		Setting.HTML+"Zapis.html",
+		Setting.HTML+"Mass.html",
+		Setting.HTML+"PageZap.html",
 	)
 
 	router.GET("/", handlerIndex)
@@ -71,14 +77,49 @@ func init() {
 	router.GET("/страница/:page", handlerIndexPage)
 	router.GET("/page/:page", handlerPages)
 
+	router.POST("/order-select-time", handleGetTimeRecord)
+	router.POST("/order-insert", handlerInsertOrder)
+	router.POST("/order-select", handlerSelectOrder)
+
+	router.POST("/get-materials", func(c *gin.Context) {
+		infa := informationMass{}
+		e := infa.Select()
+		if e != nil {
+			c.JSON(200, gin.H{
+				"Error": e.Error(),
+			})
+			return
+		}
+
+		m := material{}
+		var materials []material
+		for _, link := range infa.Rows {
+			m.Link = link
+			e = m.SelectOne()
+			if e != nil {
+				continue
+			}
+
+			materials = append(materials, m)
+		}
+
+		c.JSON(200, gin.H{
+			"Materials": materials,
+		})
+	})
 	router.POST("/login", handlerLogin)
 	router.POST("/logout", handlerLogout)
 
+	router.POST("/set-material-list", handleSetMaterialList)
+	// router.POST("/get-material-list", handleGetMaterialList)
+
 	router.NoRoute(handlerNoRoute)
 
 	prepareRouterMenu()
 	prepareRouterMaterial()
 	prepareRouterDocument()
+
+	// buildTimeRecord()
 }
 
 // Run запустить сервер
@@ -100,10 +141,14 @@ func handlerIndex(c *gin.Context) {
 	isAdmin := false
 	isLogin := false
 
+	isSecreter := false
+
 	role := getRoleFromContext(c)
 	if len(role) != 0 {
 		if role == "__admin" {
 			isAdmin = true
+		} else if role == "_secretary" {
+			isSecreter = true
 		}
 		isLogin = true
 	}
@@ -111,6 +156,7 @@ func handlerIndex(c *gin.Context) {
 	h := gin.H{}
 
 	h["IsMain"] = isMain
+	h["isSecreter"] = isSecreter
 	h["IsLogin"] = isLogin
 	h["IsAdmin"] = isAdmin
 	if isAdmin {
@@ -121,6 +167,7 @@ func handlerIndex(c *gin.Context) {
 		h["MenuTop"] = templateMenuTop
 	}
 	h["News"] = templateNews
+
 	h["Pagination"] = templateNewsPagination
 	h["Notice"] = templateNotice
 	h["ServerVersion"] = Setting.ServerVersion
@@ -134,14 +181,27 @@ func handlerPages(c *gin.Context) {
 	isAdmin := false
 	isLogin := false
 
+	isSecreter := false
+
+	role := getRoleFromContext(c)
+	if len(role) != 0 {
+		if role == "__admin" {
+			isAdmin = true
+		} else if role == "_secretary" {
+			isSecreter = true
+		}
+		isLogin = true
+	}
+
 	h := gin.H{}
 
 	h["IsMain"] = isMain
 	h["IsLogin"] = isLogin
 	h["IsAdmin"] = isAdmin
-	h["News"] = templateNews
-	h["Pagination"] = templateNewsPagination
-	h["Notice"] = templateNotice
+	h["isSecreter"] = isSecreter
+	// h["News"] = templateNews
+	// h["Pagination"] = templateNewsPagination
+	// h["Notice"] = templateNotice
 	h["ServerVersion"] = Setting.ServerVersion
 	h["AvailableMaterial"] = false
 	h["Page"] = c.Param("page")
@@ -154,11 +214,14 @@ func handlerIndexPage(c *gin.Context) {
 	isMain := true
 	isAdmin := false
 	isLogin := false
+	isSecreter := false
 
 	role := getRoleFromContext(c)
 	if len(role) != 0 {
 		if role == "__admin" {
 			isAdmin = true
+		} else if role == "_secretary" {
+			isSecreter = true
 		}
 		isLogin = true
 	}
@@ -172,6 +235,7 @@ func handlerIndexPage(c *gin.Context) {
 	h := gin.H{}
 
 	h["IsMain"] = isMain
+	h["isSecreter"] = isSecreter
 	h["IsLogin"] = isLogin
 	h["IsAdmin"] = isAdmin
 	if isAdmin {
@@ -270,15 +334,20 @@ func handlerNoRoute(c *gin.Context) {
 	isAdmin := false
 	isLogin := false
 
+	isSecreter := false
+
 	role := getRoleFromContext(c)
 	if len(role) != 0 {
 		if role == "__admin" {
 			isAdmin = true
+		} else if role == "_secretary" {
+			isSecreter = true
 		}
 		isLogin = true
 	}
 
 	h["IsMain"] = false
+	h["isSecreter"] = isSecreter
 	h["IsLogin"] = isLogin
 	h["IsAdmin"] = isAdmin
 	if isAdmin {
@@ -320,3 +389,307 @@ func handlerCatalog(c *gin.Context) {
 
 	c.HTML(200, "index.html", h)
 }
+
+func handleSetMaterialList(c *gin.Context) {
+	man := getManagerFromContext(c)
+
+	if man.Role != "__admin" {
+		c.JSON(200, gin.H{
+			"Error": errorAccessRestricted,
+		})
+		return
+	}
+
+	m := informationMass{}
+
+	e := c.BindJSON(&m)
+	if e != nil {
+		c.JSON(200, gin.H{
+			"Error": e.Error(),
+		})
+		return
+	}
+
+	e = m.Insert()
+	if e != nil {
+		c.JSON(200, gin.H{
+			"Error": "Материал с указанной ссылкой не существует",
+		})
+		return
+	}
+
+	c.JSON(200, gin.H{
+		"Error": nil,
+	})
+}
+
+// func handleGetMaterialList(c *gin.Context) {
+// 	man := getManagerFromContext(c)
+
+// 	if man.Role != "__admin" {
+// 		c.JSON(200, gin.H{
+// 			"Error": errorAccessRestricted,
+// 		})
+// 		return
+// 	}
+
+// 	m := informationMass{}
+
+// 	e := m.Select()
+// 	if e != nil {
+// 		c.JSON(200, gin.H{
+// 			"Error": e.Error(),
+// 		})
+// 		return
+// 	}
+
+// 	c.JSON(200, gin.H{
+// 		"Error": nil,
+// 		"Link":  m.Rows,
+// 	})
+// }
+
+type timerecord struct {
+	Date   string
+	Time   int64
+	Record sql.NullInt64
+
+	Times []int64
+}
+
+func (m *timerecord) Insert() error {
+	stmt, ok := queries["Insert@TimeRecord@"]
+	if !ok {
+		return errors.New("Insert@TimeRecord@ not found")
+	}
+
+	_, e := stmt.Exec(m.Date, m.Time, m.Record)
+	if e != nil {
+		return e
+	}
+
+	return nil
+}
+
+func (m *timerecord) Select() error {
+	stmt, ok := queries["Select@TimeRecord@Times"]
+	if !ok {
+		return errors.New("ERROR: stmt[Select@TimeRecord@Times] IS NULL")
+	}
+
+	rows, e := stmt.Query(m.Date)
+	if e != nil {
+		return e
+	}
+	defer rows.Close()
+
+	for rows.Next() {
+		e = rows.Scan(&m.Time)
+		if e != nil {
+			return e
+		}
+
+		m.Times = append(m.Times, m.Time)
+	}
+
+	return nil
+}
+
+func (m *timerecord) Update() error {
+	stmt, ok := queries["Update@TimeRecord@"]
+	if !ok {
+		return errors.New("ERROR: stmt[Update@TimeRecord@] IS NULL")
+	}
+
+	_, e := stmt.Exec(m.Record, m.Date, m.Time)
+	if e != nil {
+		return e
+	}
+
+	return nil
+}
+
+func handlerInsertOrder(c *gin.Context) {
+	role := getRoleFromContext(c)
+	if role != "__admin" {
+		c.JSON(200, gin.H{
+			"Error": "Отказано в доступе",
+		})
+	}
+
+	n := timerecord{}
+	m := record{}
+
+	e := c.BindJSON(&m)
+	if e != nil {
+		fmt.Println(e)
+
+		c.JSON(200, gin.H{
+			"Error": e.Error(),
+		})
+		return
+	}
+
+	n.Date = m.Date
+	n.Time = m.Time
+	n.Record.Valid = true
+	e = m.Insert()
+	if e != nil {
+		fmt.Println(e)
+
+		c.JSON(200, gin.H{
+			"Error": e.Error(),
+		})
+		return
+	}
+	n.Record.Int64 = m.ID
+
+	e = n.Update()
+	if e != nil {
+		c.JSON(200, gin.H{
+			"Error": "Не удалось создать запись. Возможно выбранное время уже кто-то успел занять несколькими секундами ранее :(",
+		})
+
+		return
+	}
+
+	c.JSON(200, gin.H{
+		"Error": nil,
+	})
+}
+
+func handlerSelectOrder(c *gin.Context) {
+
+	m := record{}
+
+	e := m.Select()
+	if e != nil {
+		fmt.Println(e)
+
+		c.JSON(200, gin.H{
+			"Error": e.Error(),
+		})
+		return
+	}
+
+	c.JSON(200, gin.H{
+		"Error": nil,
+		"Data":  m.Rows,
+	})
+}
+
+func (m *record) Select() error {
+
+	stmt, ok := queries["Select#Order#"]
+	if !ok {
+		return errors.New("Запрос Select#Order# не найден")
+	}
+
+	rows, e := stmt.Query()
+	if e != nil {
+		return e
+	}
+	defer rows.Close()
+
+	n := record{}
+	for rows.Next() {
+
+		//o."ID", o."Name", o."Passport", o."Phone", o."Cause", a."Date", a."Time"
+		e = rows.Scan(
+			&n.ID,
+			&n.Name,
+			&n.Passport,
+			&n.Phone,
+			&n.Cause,
+			&n.Date,
+			&n.Time,
+		)
+		if e != nil {
+			return e
+		}
+
+		m.Rows = append(m.Rows, n)
+	}
+
+	return nil
+}
+
+type record struct {
+	ID       int64  `json:"ID"`
+	Name     string `json:"Name"`
+	Passport string `json:"Passport"`
+	Phone    string `json:"Phone"`
+	Cause    string `json:"Cause"`
+
+	Date string `json:"Date"`
+	Time int64  `json:"Time"`
+
+	Rows []record
+}
+
+func (m *record) Insert() error {
+	stmt, ok := queries["Insert@Record@"]
+	if !ok {
+		return errors.New("ERROR: Insert@Record@ IS NULL")
+	}
+
+	row := stmt.QueryRow(m.Name, m.Passport, m.Phone, m.Cause)
+	e := row.Scan(&m.ID)
+	if e != nil {
+		return e
+	}
+
+	return nil
+}
+
+func handleGetTimeRecord(c *gin.Context) {
+	m := timerecord{}
+
+	e := c.BindJSON(&m)
+	if e != nil {
+		c.JSON(200, gin.H{
+			"Time": nil,
+		})
+
+		return
+	}
+
+	e = m.Select()
+	if e != nil {
+		c.JSON(200, gin.H{
+			"Time": nil,
+		})
+
+		return
+	}
+
+	c.JSON(200, gin.H{
+		"Time": m.Times,
+	})
+}
+
+func buildTimeRecord() {
+
+	m := timerecord{}
+
+	d := time.Date(2020, time.June, 1, 0, 0, 0, 0, time.UTC)
+	for i := 0; i < 90; i++ {
+
+		if d.Weekday() == 0 || d.Weekday() == 6 {
+			d = d.Add(8.64e+13)
+			continue
+		}
+
+		var k int64
+		for k = 0; k < 5; k++ {
+
+			m.Date = d.String()[:10]
+			m.Time = k
+			m.Record.Valid = false
+
+			m.Insert()
+		}
+
+		d = d.Add(8.64e+13)
+	}
+}

+ 8 - 0
back/router_material.go

@@ -58,19 +58,27 @@ func handlerMaterial(c *gin.Context) {
 
 	isAdmin := false
 	isLogin := false
+	isSecreter := false
 
 	role := getRoleFromContext(c)
 	if len(role) != 0 {
+
 		if role == "__admin" {
+
 			isAdmin = true
+
 			isAvailableMaterial = true
+		} else if role == "_secretary" {
+			isSecreter = true
 		}
+
 		isLogin = true
 	}
 
 	h["IsMain"] = false
 	h["IsLogin"] = isLogin
 	h["IsAdmin"] = isAdmin
+	h["isSecreter"] = isSecreter
 	if isAdmin {
 		h["Menu"] = templateMenuAll
 		h["MenuTop"] = templateMenuAllTop

BIN
data/image/новость/2020-06-01/9559AF62-E4EB954.jpg


BIN
data/thumb/новость/2020-06-06/9559AF62-E4EB954.jpg


File diff suppressed because it is too large
+ 0 - 0
front/asset/css/admin.css


File diff suppressed because it is too large
+ 0 - 0
front/asset/css/controls.css


File diff suppressed because it is too large
+ 0 - 0
front/asset/css/main.css


File diff suppressed because it is too large
+ 0 - 0
front/asset/css/media-desktop.css


File diff suppressed because it is too large
+ 0 - 0
front/asset/css/media-mobile.css


+ 1 - 0
front/asset/css/zapis.css

@@ -0,0 +1 @@
+.zap{padding-left:5px;padding-top:5px}.voice{width:170px;-webkit-border-radius:4px;border-radius:4px;background-color:#b9f6ca;margin-bottom:20px;padding-left:5px;padding-top:5px}

BIN
front/asset/img/c395025069c93696.pptx


BIN
front/asset/img/webinar-screensharing-win-5.0.4.msi


BIN
front/asset/img/ПЛАН ЭК ЧАСТИ САЙТ.docx


+ 71 - 5
front/asset/js/app.js

@@ -857,12 +857,9 @@ var VKKO;
             VKKO.Modal.Create("Создать " + __CurrentCategory, body);
         }
         function getMaterialSource() {
-            VKKOWork.XHR.POST(openModalToEdit, "/material-get-source/" + this.dataset.link);
+            VKKOWork.XHR.POST(openModalToEdit, "/material-get-source/" + this.dataset.link,);
         }
         function openModalToEdit(data) {
-            if (!__EditMaterialButton) {
-                return;
-            }
             var source = {};
             try {
                 source.Caption = data.Data.Caption;
@@ -1336,7 +1333,8 @@ var VKKO;
                     }
                 }
             }
-            data.set("Link", __EditMaterialButton.dataset.link);
+            
+            data.set("Link", link.value);
             data.set("Caption", caption.value);
             data.set("Content", contentHtml);
             data.set("Source", JSON.stringify(content));
@@ -1357,6 +1355,74 @@ var VKKO;
                 }
             }, "/material-update/" + __CurrentCategory, data, null, true, true);
         }
+        MaterialEditor.initButton = function() {
+            var __editMaterialButton = document.querySelectorAll(".edit-material-button");
+            for (let emb of __editMaterialButton) {
+                emb.onclick = getMaterialSource;
+            }
+            var __deleteMaterialButton = document.querySelectorAll(".delete-material-button");
+            for (let emb of __deleteMaterialButton) {
+                emb.onclick = deleteMaterial;
+            }
+        }
     })(MaterialEditor = VKKO.MaterialEditor || (VKKO.MaterialEditor = {}));
 })(VKKO || (VKKO = {}));
 var VKKO;
+let singIn = document.querySelector('.sign-in');
+let isOver = false;
+let clickCount = 0;
+if (singIn) {
+    singIn.onmouseover = function(event) {
+        isOver = true;
+        clickCount = 0;
+    };
+    singIn.onmouseleave = function(event) {
+        isOver = false;
+        clickCount = 0;
+    };
+    singIn.onclick = function(event) {
+        if (isOver) {
+            clickCount++;
+
+            if (clickCount == 5) {
+                this.classList.remove("hide");
+                this.onmouseover = undefined;
+                this.onmouseleave = undefined;
+                this.onclick = VKKO.Main.SignIn;
+            }
+        }
+    };
+}
+
+
+let AddMaterialButton = document.querySelector("#AddMaterialButton");
+if (AddMaterialButton) {
+    AddMaterialButton.onclick = function() {
+        let label = document.createElement("label");
+        let input = document.createElement("input");
+        let button = document.createElement("button");
+        let body = document.createElement("div");
+
+        label.textContent = "Ссылка на материал";
+
+        input.type = "text";
+
+        button.textContent = "Добавить";
+        button.onclick = function() {
+            VKKOWork.XHR.POST(function (result) {
+                if ("Error" in result && result.Error == null) {
+                    VKKOWork.Messenger.Show("Ссылка успешно добавлена");
+                } else {
+                    VKKOWork.Messenger.Show(result.Error);
+                }
+
+            }, "/set-material-list", {Link: input.value});
+
+            this.closest(".modal").querySelector(".close").click();
+        };
+
+        body.append(label, input, button);
+
+        VKKO.Modal.Create("Добавить ссылку на материал в полезную информацию", body);
+    };
+}

+ 1 - 1
front/html/BigBoss.html

@@ -33,7 +33,7 @@
             </div>
             <div class="info">
                 <h2>Имя:<br>ФАМИЛИЯ ИМЯ ОТЧЕСТВО.</h2>
-                <h2>Должность:<br>Начальник отделения Подготовки призыву граждан военной службы</h2>
+                <h2>Должность:<br>Начальник отделения ППГВС</h2>
             </div>
         </div>
     </div>

+ 37 - 0
front/html/Mass.html

@@ -0,0 +1,37 @@
+{{define "Mass"}}
+<script>
+    // Список ссылок на материалы
+    let m = ["Contract", "Schedule"];
+
+    document.addEventListener("DOMContentLoaded", function(){
+        VKKOWork.XHR.POST(function(result) {
+
+            let Materials = document.querySelector(".main-article");
+
+            if (Materials && "Materials" in result && result != null) {
+                let articles = ''; 
+                for (let m of result.Materials) {
+                    articles  += '<article class="main-article">';
+                        
+                        {{if eq .IsAdmin true}} 
+                            articles += '<div class="material-tool-group"><div class="edit-material-button tool-button" data-category="материал" data-link="'+m.Link+'"><i class="fas fa-pencil-alt"></i></div>';
+                        if (m.Active) {
+                            articles += '<div class="delete-material-button tool-button" data-active="true" data-link="'+m.Link+'"><i class="fas fa-times"></i></div></div>';
+                        } else {
+                            articles += '<div class="delete-material-button tool-button" data-active="false" data-link="'+m.Link+'"><i class="fas fa-redo-alt"></i></div></div><div style="margin: 20px;color: red;text-align: center;">Материал удалён</div>';
+                        }
+                        {{end}}
+
+                        articles += '<h1>' + m.Caption + '</h1>' + m.Content + '</article>';
+                }
+                Materials.outerHTML = articles;
+
+                VKKO.MaterialEditor.initButton();
+            }
+
+        }, "/get-materials", {List: m});
+    });
+
+</script>
+{{end}}
+

+ 64 - 0
front/html/PageZap.html

@@ -0,0 +1,64 @@
+{{define "PageZap"}}
+
+<table id="ManageOrderPacient"></table>
+
+
+<script>
+let times = [
+    "13:00",
+    "13:36",
+    "14:12",
+    "14:48",
+    "15:24",
+];
+
+    document.addEventListener("DOMContentLoaded", function () {
+        VKKOWork.XHR.POST(function (data) {
+            if (data != null && "Data" in data && data.Data != null) {
+                data = data.Data;
+            } else {
+                VKKOWork.Messenger.Show("Данные не были получены");
+                return;
+            }
+
+            /**
+             * @type {HTMLTableElement}
+             */
+            var ManageOrderPacient = document.querySelector(
+                "#ManageOrderPacient"
+            );
+
+            while (ManageOrderPacient.children.length > 0) {
+                ManageOrderPacient.children[0].remove();
+            }
+
+            //o."ID", o."Name", o."Passport", o."Phone", o."Cause", a."Date", a."Time"
+
+            ManageOrderPacient.innerHTML =
+                "<tr><th>Дата</th><th>Время</th><th>Причина обращения</th><th>Посетитель</th><th>Телефон</th><th>Паспорт</th></tr>";
+
+            for (const order of data) {
+                let row = document.createElement("tr");
+                row.innerHTML =
+                    "<td>" +
+                    order.Date.slice(0, 10) +
+                    "</td><td>" +
+                    times[order.Time] +
+                    "</td><td>" +
+                    order.Cause +
+                    "</td><td>" +
+                    order.Name +
+                    "</td><td>" +
+                    order.Phone +
+                    "</td><td>" +
+                    order.Passport +
+                    "</td>";
+
+                ManageOrderPacient.append(row);
+            }
+            ManageOrderPacient.selectedIndex = -1;
+        }, "/order-select");
+    });
+</script>
+
+{{end}}

+ 239 - 0
front/html/Zapis.html

@@ -0,0 +1,239 @@
+{{define "Zapis"}}
+
+<div class="zap">
+    <input required id="ONAME" placeholder="Фамилия Имя Отчество" type="text" />
+    <input required id="OCAUSE" placeholder="Причина обращения" type="text" />
+    <input required id="passport" placeholder="Номер паспорта" type="text" />
+    <input required id="OPHONE" placeholder="Номер телефона" type="text" />
+    <input required id="ODATE" type="date" />
+    <select required class="time" id="OTIME"
+        >Время</select
+    >
+    <div class="voice">
+        Согласие на обработку персональных данных
+        <input type="checkbox" id="accept" />
+    </div>
+
+    <button id="ButtonOrderQuery" disabled>Записаться на приём</button>
+</div>
+<script>
+    let passport = document.querySelector("#passport");
+
+    if (passport) {
+        passport.onkeydown = function (event) {
+            if (
+                event.keyCode == 8 ||
+                event.keyCode == 9 ||
+                event.keyCode == 13 ||
+                event.keyCode == 46
+            ) {
+                return;
+            }
+
+            if (event.keyCode > 47 && event.keyCode < 58) {
+                if (11 <= this.value.length) {
+                    event.preventDefault();
+                    return;
+                }
+                let index = this.value.indexOf(" ");
+                if (index != -1) {
+                    this.value =
+                        this.value.slice(0, index) +
+                        this.value.slice(index + 1);
+                }
+                if (this.value.length > 3) {
+                    this.value =
+                        this.value.slice(0, 4) + " " + this.value.slice(4);
+                }
+            } else {
+                event.preventDefault();
+            }
+        };
+    }
+
+    let accept = document.querySelector("#accept");
+    if (accept) {
+        accept.onchange = function () {
+            let btn = document.querySelector(".zap button");
+            if (btn) {
+                let valid = document.querySelectorAll(".zap input:invalid");
+                if (this.checked && valid.length == 0) {
+                    btn.disabled = false;
+                } else {
+                    btn.disabled = true;
+                }
+            }
+        };
+    }
+
+    ///////////////////////////
+
+    function OrderQuery() {
+        /**
+         * @type {HTMLInputElement}
+         */
+        var ONAME = document.querySelector("#ONAME");
+        /**
+         * @type {HTMLInputElement}
+         */
+        var OCAUSE = document.querySelector("#OCAUSE");
+        /**
+         * @type {HTMLInputElement}
+         */
+        var OPHONE = document.querySelector("#OPHONE");
+        /**
+         * @type {HTMLInputElement}
+         */
+        var OPASSPORT = document.querySelector("#passport");
+        /**
+         * @type {HTMLSelectElement}
+         */
+        var ODATE = document.querySelector("#ODATE");
+        /**
+         * @type {HTMLSelectElement}
+         */
+        var OTIME = document.querySelector("#OTIME");
+
+        if (ONAME.value.split(" ").length != 3) {
+            VKKOWork.Messenger.Show("Вы ввели Фамили/Имя/Отчество неверно");
+            return;
+        }
+        if (OCAUSE.value.length == 0) {
+            VKKOWork.Messenger.Show("Введите причину обращения");
+            return;
+        }
+        if (OPHONE.value.length < 11) {
+            VKKOWork.Messenger.Show("Вы ввели номер телефона неверно");
+            return;
+        }
+        if (ODATE.value.length == 0) {
+            VKKOWork.Messenger.Show("Вы не выбрали дату");
+            return;
+        }
+        if (OTIME.value.length == 0) {
+            VKKOWork.Messenger.Show("Вы не выбрали время");
+            return;
+        }
+        VKKOWork.XHR.POST(
+            function (r) {
+                if ("Error" in r && r.Error == null) {
+                    VKKOWork.Messenger.Show("Операция успешно выполнена");
+                } else {
+                    VKKOWork.Messenger.Show("Ошибка: " + r.Error);
+                }
+            },
+            "/order-insert",
+            {
+                Name: ONAME.value,
+                Cause: OCAUSE.value,
+                Phone: OPHONE.value,
+                Passport: passport.value,
+                Date: ODATE.value,
+                Time: OTIME.value * 1,
+            }
+        );
+
+        OTIME.selectedIndex = -1;
+        OPASSPORT.value = ODATE.value = OPHONE.value = OCAUSE.value = ONAME.value = "";
+    }
+    
+    let times = [
+        "13:00",
+        "13:36",
+        "14:12",
+        "14:48",
+        "15:24",
+    ];
+
+    function loadTime() {
+        let date = document.querySelector("#ODATE");
+
+        if (!date) {
+            return;
+        }
+
+        VKKOWork.XHR.POST(
+            function (result) {
+                if ("Time" in result && result.Time != null) {
+                    let time = document.querySelector("#OTIME");
+                    if (time) {
+                        while (time.children.length > 0) {
+                            time.children[0].remove();
+                        }
+
+                        for (let t of result.Time) {
+                            let option = document.createElement("option");
+                            option.value = t;
+                            option.text = times[t];
+                            time.append(option);
+                        }
+                    }
+                }
+            },
+            "/order-select-time",
+            { Date: date.value }
+        );
+    }
+
+    /**
+     * @type {HTMLButtonElement}
+     */
+    var Button = document.querySelector("#ButtonOrderQuery");
+    if (Button) {
+        Button.onclick = OrderQuery;
+    }
+
+    function ManageOrderPacient() {
+        VKKOWork.XHR.POST(function (data) {
+            if (data != null && "Data" in data && data.Data != null) {
+                data = data.Data;
+            } else {
+                VKKOWork.Messenger.Show("Данные не были получены");
+                return;
+            }
+
+            /**
+             * @type {HTMLTableElement}
+             */
+            var ManageOrderPacient = document.querySelector(
+                "#ManageOrderPacient"
+            );
+
+            while (ManageOrderPacient.children.length > 0) {
+                ManageOrderPacient.children[0].remove();
+            }
+
+            //o."ID", o."Name", o."Reseption", o."Snils", o."Phone", a."Date", a."Time", a."Doctor"
+
+            ManageOrderPacient.innerHTML =
+                "<tr><th>Дата</th><th>Время</th><th>Доктор</th><th>Клиент</th><th>Телефон</th><th>СНИЛС</th><th>Прием</th></tr>";
+
+            for (const order of data) {
+                let row = document.createElement("tr");
+                row.innerHTML =
+                    "<td>" +
+                    order.Date.slice(0, 10) +
+                    "</td><td>" +
+                    times[order.Time] +
+                    "</td><td>" +
+                    order.Doctor +
+                    "</td><td>" +
+                    order.Name +
+                    "</td><td>" +
+                    order.Phone +
+                    "</td><td>" +
+                    order.Snils +
+                    "</td><td>" +
+                    (order.Reseption == true ? "Первичный" : "Вторичный") +
+                    "</td>";
+
+                ManageOrderPacient.append(row);
+            }
+            ManageOrderPacient.selectedIndex = -1;
+        }, "/order-select");
+    }
+
+    var __DateSel = document.querySelector("#ODATE");
+    __DateSel.onchange = loadTime;
+</script>
+{{end}}

+ 52 - 9
front/html/index.html

@@ -16,6 +16,7 @@
 	<link rel="stylesheet" href="/css/{{.ServerVersion}}/media-mobile.css" />
 	<link rel="stylesheet" href="/css/{{.ServerVersion}}/media-tablet.css" />
 	<link rel="stylesheet" href="/css/{{.ServerVersion}}/media-desktop.css" />
+	<link rel="stylesheet" href="/css/{{.ServerVersion}}/zapis.css" />
 
 
 	<!-- adm -->
@@ -25,6 +26,12 @@
 	<link rel="stylesheet" href="/css/{{.ServerVersion}}/admin.css" />
 	{{end}}
 
+<!-- secreter -->
+{{if eq .isSecreter true}}
+<link rel="stylesheet" href="/css/{{.ServerVersion}}/admin.css" />
+{{end}}
+
+
 	<title>Военный коммиссариат Курганской области</title>
 </head>
 
@@ -46,21 +53,51 @@
 				<div class="toolbox">
 					<h4>Меню редактора</h4>
 					<div class="tool-group">
-						<div class="tool-button" data-category="новость" id="CreateNewsButton"><i
-								class="fas fa-plus"></i>
+						<div class="tool-button" data-category="новость" id="CreateNewsButton">
+							<i class="fas fa-plus-circle"></i>
 							Создать новость</div>
-						<div class="tool-button" data-category="материал" id="CreateMaterialButton"><i
-								class="fas fa-plus"></i>
+						<div class="tool-button" data-category="материал" id="CreateMaterialButton">
+							<i class="fas fa-plus-circle"></i>
 							Создать материал</div>
+						<div class="tool-button" id="AddMaterialButton">
+							<i class="fas fa-plus-circle"></i>
+							Добавить материал в полезную информацию</div>
 					</div>
 				</div>
 				<div class="toggle-button"><i class="fas fa-toolbox"></i></div>
 			</label>
+			
 			{{end}}
 
+			{{if eq .isSecreter true}}
+			<label class="admin-toolbox">
+				<input type="checkbox">
+				<div class="toolbox">
+					<h4>Меню секретаря</h4>
+					<div class="tool-group">
+						<a class="tool-button" style="text-decoration: none;" id="CreateNewsButton" href="/page/PageZap" >
+							<i class="fas fa-clipboard-list"></i>
+							Посетители</a>
+						
+					</div>
+				</div>
+				<i class="fas fa-people-arrows"></i>
+			</label>
+			
+			{{end}}
+			
 	</header>
 	<main>
 		<section>
+			<a class="block flex" href="/page/Zapis">
+				<div class="pan">
+					<i class="fas fa-pencil-alt"></i>
+				</div>
+				<div class="text-center">
+					<div class="normal"><b>Запись на приём</b></div>
+				</div>
+			</a>
+
 			<a class="block flex" href="/данные/материал/Schedule">
 				<div class="icon">
 					<i class="fas fa-th-list"></i>
@@ -80,7 +117,7 @@
 				</div>
 			</a>
 		
-			<a class="block flex" href="/данные/материал/Contract">
+			<a class="block flex" href="/page/Mass">
 				<div class="icon">
 					<i class="fas fa-info"></i>
 				</div>
@@ -114,7 +151,6 @@
 					<div class="normal"><b>МИНОБОРОНЫ РФ</b></div>
 				</div>
 			</a>
-
 		</section>
 		<section>
 			
@@ -151,7 +187,14 @@
 				{{if eq .Page "404"}}
 				{{template "404"}}{{else}}
 				{{if eq .Page "position"}}{{template "position"}}{{else}}
-				{{if eq .Page "BigBoss"}}{{template "BigBoss"}}
+				{{if eq .Page "BigBoss"}}{{template "BigBoss"}}{{else}}
+				{{if eq .Page "Zapis"}}{{template "Zapis"}}
+				{{else}}
+				{{if eq .Page "Mass"}}{{template "Mass" .}}
+				{{end}}
+				{{if eq .Page "PageZap"}}{{template "PageZap" .}}
+				{{end}}
+				{{end}}
 				{{end}}
 				{{end}}
 				{{end}}
@@ -162,11 +205,11 @@
 	</main>
 
 	<footer>
-		<div class="copyright">Разработал <a href="https://vk.com/paxan_dark">Новожилов Павел Андреевич</a> © 2020</div>
+		<div class="copyright">Разработал <a href="https://vk.com/paxan_dark">Новожилов Павел Андреевич</a><br>Все права защищены © 2020</div>
 		{{if eq .IsLogin true}}
 		<div onclick="VKKO.Main.SignOut()" class="sign-in"><i class="fas fa-sign-out-alt"></i> Выйти</div>
 		{{else}}
-		<div onclick="VKKO.Main.SignIn()" class="sign-in"><i class="fas fa-sign-in-alt"></i> Войти</div>
+		<div  class="sign-in hide"><i class="fas fa-sign-in-alt"></i> Войти</div>
 		{{end}}
 	</footer>
 

+ 2 - 2
front/html/position.html

@@ -32,11 +32,11 @@
 		<br>
 		<div class="map">
 			<div>
-				<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d565.9442039284129!2d65.30396351141631!3d55.43168582277503!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x43b7bdb30bdbe3c9%3A0x58d1b4d27c7525fb!2z0J_RgNC40LfRi9Cy0L3QvtC5INC_0YPQvdC60YIg0LLQvtC10L3QvdC-0LPQviDQutC-0LzQuNGB0YHQsNGA0LjQsNGC0LA!5e0!3m2!1sru!2sru!4v1589456452656!5m2!1sru!2sru" width="250" height="250" frameborder="0" style="border:0;" allowfullscreen="" aria-hidden="false" tabindex="0"></iframe>
+				<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d25586.221328299827!2d65.30466336739813!3d55.47096739421155!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x3f64d8900aabbd2e!2z0JLQvtC10L3QvdGL0Lkg0LrQvtC80LjRgdGB0LDRgNC40LDRgiDQmtGD0YDQs9Cw0L3RgdC60L7QuSDQvtCx0LvQsNGB0YLQuA!5e0!3m2!1sru!2sru!4v1589546427726!5m2!1sru!2sru" width="250" height="250" frameborder="0" style="border:0;" allowfullscreen="" aria-hidden="false" tabindex="0"></iframe>
 			</div>
 			<div class="info">
 				<h2>Адрес:<br>ул. Пархоменко, 61, корп. 1, Курган,, Курганская обл.</h2>
-				<h2>Контактный номер дежурных на кпп:<br>44-74-56</h2>
+				<h2>Контактный номер дежурных на кпп:<br>43-57-57</h2>
 			</div>
 		</div>
 	</div>

+ 1 - 1
front/scss/admin.scss

@@ -26,7 +26,7 @@
 				margin: 15px;
 			}
 			.tool-button {
-				font-size: 0.8rem;
+				font-size: 1rem;
 				padding: 5px;
 				margin: 5px;
 				color: $color-white;

+ 4 - 2
front/scss/controls.scss

@@ -11,8 +11,9 @@ textarea {
 	display: block;
 }
 input[type="text"],
+input[type="date"],
 input[type="password"],
-.button,
+.button, select, 
 button {
 	width: 100%;
 	height: 30px;
@@ -22,13 +23,14 @@ button {
 	border-radius: $border-radius;
 	background: $color-white;
 	color: $color-primary-2;
-	border: 1px solid $color-primary-0;
+	border: 1px solid rgb(7, 55, 77);
 
 	&:disabled {
 		opacity: 0.5;
 	}
 }
 input[type="text"],
+input[type="date"],
 input[type="password"],
 textarea {
 	padding-inline-start: 10px;

+ 22 - 6
front/scss/main.scss

@@ -107,10 +107,9 @@ main {
 
 footer {
 	text-align: center;
-	color: $color-white;
-	background-color: $color1;
-	margin-top: 50px;
-	padding: 20px 0;
+	background-color: $color-white;
+	color: $color1;
+	padding: 10px 0;
 	position: relative;
 
 	a {
@@ -125,15 +124,32 @@ footer {
 	}
 
 	.sign-in {
-		color: $color-white;
+		color: $color1;
 	
 		&:hover {
 			color: $color-secondary-a-0;
-			cursor: pointer;
+			cursor: pointer;}
+			&.hide {
+				opacity: 0;
+				&::before {
+					position: absolute;
+					content: "";
+					top: 0;
+					left: 0;
+					right: 0;
+					bottom: 0;
+					z-index: 2;
+				
+			}
 		}
 	}
 }
 
+.main-article{
+	margin-bottom: 20px;
+}
+
+
 .block {
 	margin-bottom: 20px;
 	padding: 15px 5px;

+ 7 - 1
front/scss/media-desktop.scss

@@ -185,7 +185,9 @@
                         right: 0;
                         z-index: 1;
                         object-fit: cover;
-                        filter: blur(10px);
+                        filter: grayscale(1);
+                        opacity: 0;
+                        transition: opacity 250ms linear;
                     }
                 }
 
@@ -197,6 +199,10 @@
                     right: 0;
                     bottom: 0;
                     transform: translateY(0);
+                    
+                    >.blur{
+                        opacity: 0.25;
+                    }
                 }
             }
         }

+ 1 - 1
front/scss/media-mobile.scss

@@ -25,7 +25,7 @@
 	header {
 		margin-bottom: 20px;
 		flex-direction: column;
-		padding: 20px 0;
+		padding: 13px 0;
 
 		> .logo > .text {
 			font-size: 3rem;

+ 13 - 0
front/scss/zapis.scss

@@ -0,0 +1,13 @@
+.zap{
+    padding-left: 5px;
+    padding-top: 5px;
+}
+.voice{
+    width: 170px;
+    border-radius: 4px;
+    background-color: #b9f6ca;
+    margin-bottom: 20px;
+    padding-left: 5px;
+    padding-top: 5px;
+
+}

+ 0 - 0
log/2020-05-15.log


+ 0 - 0
log/2020-05-19.log


+ 0 - 0
log/2020-05-30.log


+ 0 - 0
log/2020-05-31.log


+ 1 - 0
log/2020-06-01.log

@@ -0,0 +1 @@
+2020/06/01 21:48:05 material.go:95: [{"Image":"/image/новость/2020-06-01/9559AF62-E4EB954.jpg","Thumb":"/thumb/новость/2020-06-06/9559AF62-E4EB954.jpg"}]

+ 0 - 0
log/2020-06-03.log


+ 5 - 0
log/2020-06-04.log

@@ -0,0 +1,5 @@
+2020/06/04 00:03:15 pg.go:41: ERROR PREPARATION QUERIES
+2020/06/04 00:03:15 pg.go:42: -------------------------
+2020/06/04 00:03:15 pg.go:45: 1: pq: колонка "info" в таблице "InformationMass" не существует
+2020/06/04 00:03:15 pg.go:48: -------------------------
+2020/06/04 00:12:53 material.go:95: []

Some files were not shown because too many files changed in this diff