feat: excel importer
This commit is contained in:
@@ -50,6 +50,11 @@ export function GetById(id: number): Promise<$models.PostType | null> & { cancel
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function ImportFromExcel(): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1671814244) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function Update(item: $models.PostType): Promise<$models.PostType> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2773888269, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { Dialog } from 'primevue';
|
||||
import { useErrorStore } from './stores/error.store';
|
||||
import { Dialog } from "primevue";
|
||||
import { useErrorStore } from "./stores/error.store";
|
||||
import CommentScheme from "./comment/CommentScheme.vue";
|
||||
import PostScheme from "./post/PostScheme.vue";
|
||||
import PosttypeScheme from "./posttype/PosttypeScheme.vue";
|
||||
import AuthorScheme from "./author/AuthorScheme.vue";
|
||||
|
||||
const errorStore = useErrorStore()
|
||||
const errorStore = useErrorStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:visible="errorStore.show" maximizable class="w-[400px] h-[400px]">
|
||||
<template #header>
|
||||
Ошибка
|
||||
</template>
|
||||
<h1 class="text-red-500 text-2xl">{{ errorStore.message }}</h1>
|
||||
<Dialog
|
||||
v-model:visible="errorStore.show"
|
||||
maximizable
|
||||
class="w-[400px] h-[400px]"
|
||||
>
|
||||
<template #header> Ошибка </template>
|
||||
<h1 class="text-red-500 text-2xl">{{ errorStore.message }}</h1>
|
||||
</Dialog>
|
||||
<main class="w-screen h-screen">
|
||||
|
||||
<CommentScheme></CommentScheme>
|
||||
<PostScheme></PostScheme>
|
||||
<PosttypeScheme></PosttypeScheme>
|
||||
<AuthorScheme></AuthorScheme>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -22,112 +22,111 @@ const service = new Service();
|
||||
const items = ref<Post[]>([]);
|
||||
|
||||
const load = async () => {
|
||||
(scheme as any).Author.type!.nested!.values = await authorService.readAll();
|
||||
(scheme as any).Author.type!.nested!.values = await authorService.readAll();
|
||||
|
||||
(scheme as any).PostType.type!.nested!.values =
|
||||
await posttypeService.readAll();
|
||||
(scheme as any).PostType.type!.nested!.values =
|
||||
await posttypeService.readAll();
|
||||
|
||||
(scheme as any).Comments.type!.nested!.values =
|
||||
await commentService.readAll();
|
||||
(scheme as any).Comments.type!.nested!.values =
|
||||
await commentService.readAll();
|
||||
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
load();
|
||||
await load();
|
||||
});
|
||||
|
||||
const scheme: Scheme<Post> = reactive({
|
||||
entityId: "PostId",
|
||||
entityId: "PostId",
|
||||
|
||||
Id: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
Id: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Text: {
|
||||
russian: "Текст",
|
||||
type: {
|
||||
primitive: "string",
|
||||
Text: {
|
||||
russian: "Текст",
|
||||
type: {
|
||||
primitive: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Deadline: {
|
||||
russian: "Дедлайн",
|
||||
date: true,
|
||||
type: {
|
||||
primitive: "date",
|
||||
Deadline: {
|
||||
russian: "Дедлайн",
|
||||
date: true,
|
||||
type: {
|
||||
primitive: "date",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
CreatedAt: {
|
||||
readonly: true,
|
||||
date: true,
|
||||
type: {
|
||||
primitive: "date",
|
||||
CreatedAt: {
|
||||
russian: "Дата создания",
|
||||
type: {
|
||||
primitive: "date",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
AuthorId: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
AuthorId: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Author: {
|
||||
russian: "Автор",
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Name"],
|
||||
},
|
||||
Author: {
|
||||
russian: "Автор",
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Name"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
PostTypeId: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
PostTypeId: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
PostType: {
|
||||
russian: "Тип",
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Name"],
|
||||
},
|
||||
PostType: {
|
||||
russian: "Тип",
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Name"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Comments: {
|
||||
russian: "Комментарии",
|
||||
many: true,
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Text"],
|
||||
},
|
||||
Comments: {
|
||||
russian: "Комментарии",
|
||||
many: true,
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Text"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const getDefaults = () => getDefaultValues(scheme);
|
||||
|
||||
const validate: Validate<Post> = (entity) => {
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="w-screen h-screen">
|
||||
<Table :scheme :service :get-defaults :load :items :validate></Table>
|
||||
</main>
|
||||
<main class="w-screen h-screen">
|
||||
<Table :scheme :service :get-defaults :load :items :validate></Table>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -7,49 +7,51 @@ import type { Scheme } from "../types/scheme.type";
|
||||
import { PostType } from "../../bindings/app/internal/services";
|
||||
import { ref } from "vue";
|
||||
import type { Validate } from "../types/validate.type";
|
||||
import { ImportFromExcel } from "../../bindings/app/internal/services/posttypeservice.ts";
|
||||
|
||||
const service = new Service();
|
||||
|
||||
const items = ref<PostType[]>([]);
|
||||
|
||||
const load = async () => {
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
load();
|
||||
await load();
|
||||
await ImportFromExcel();
|
||||
});
|
||||
|
||||
const scheme: Scheme<PostType> = reactive({
|
||||
entityId: "PostTypeId",
|
||||
entityId: "PostTypeId",
|
||||
|
||||
Id: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
Id: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Name: {
|
||||
russian: "Название",
|
||||
type: {
|
||||
primitive: "string",
|
||||
Name: {
|
||||
russian: "Название",
|
||||
type: {
|
||||
primitive: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const getDefaults = () => getDefaultValues(scheme);
|
||||
|
||||
const validate: Validate<PostType> = (entity) => {
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="w-screen h-screen">
|
||||
<Table :scheme :service :get-defaults :load :items :validate></Table>
|
||||
</main>
|
||||
<main class="w-screen h-screen">
|
||||
<Table :scheme :service :get-defaults :load :items :validate></Table>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
9
go.mod
9
go.mod
@@ -5,9 +5,9 @@ go 1.22.4
|
||||
toolchain go1.23.4
|
||||
|
||||
require (
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.8.3
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.9
|
||||
github.com/xuri/excelize/v2 v2.9.0
|
||||
gorm.io/driver/sqlite v1.5.0
|
||||
gorm.io/driver/sqlite v1.5.7
|
||||
gorm.io/gen v0.3.26
|
||||
gorm.io/gorm v1.25.12
|
||||
gorm.io/plugin/dbresolver v1.5.3
|
||||
@@ -42,7 +42,7 @@ require (
|
||||
github.com/lmittmann/tint v1.0.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
@@ -52,7 +52,7 @@ require (
|
||||
github.com/samber/lo v1.38.1 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/skeema/knownhosts v1.2.2 // indirect
|
||||
github.com/wailsapp/go-webview2 v1.0.18 // indirect
|
||||
github.com/wailsapp/go-webview2 v1.0.19 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
|
||||
@@ -65,6 +65,7 @@ require (
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gorm.io/datatypes v1.2.5 // indirect
|
||||
gorm.io/driver/mysql v1.5.7 // indirect
|
||||
|
||||
16
go.sum
16
go.sum
@@ -96,8 +96,9 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
|
||||
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
@@ -134,12 +135,12 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/wailsapp/go-webview2 v1.0.18 h1:SSSCoLA+MYikSp1U0WmvELF/4c3x5kH8Vi31TKyZ4yk=
|
||||
github.com/wailsapp/go-webview2 v1.0.18/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
|
||||
github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU=
|
||||
github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.8.3 h1:9aCL0IXD60A5iscQ/ps6f3ti3IlaoG6LQe0RZ9JkueU=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.8.3/go.mod h1:9Ca1goy5oqxmy8Oetb8Tchkezcx4tK03DK+SqYByu5Y=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.9 h1:b8CfRrhPno8Fra0xFp4Ifyj+ogmXBc35rsQWvcrHtsI=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.9/go.mod h1:dSv6s722nSWaUyUiapAM1DHc5HKggNGY1a79shO85/g=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
|
||||
@@ -226,6 +227,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -238,8 +241,9 @@ gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U=
|
||||
gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A=
|
||||
gorm.io/driver/sqlite v1.5.0 h1:zKYbzRCpBrT1bNijRnxLDJWPjVfImGEn0lSnUY5gZ+c=
|
||||
gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k8I=
|
||||
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
|
||||
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
|
||||
gorm.io/driver/sqlserver v1.5.4 h1:xA+Y1KDNspv79q43bPyjDMUgHoYHLhXYmdFcYPobg8g=
|
||||
gorm.io/driver/sqlserver v1.5.4/go.mod h1:+frZ/qYmuna11zHPlh5oc2O6ZA/lS88Keb0XSH1Zh/g=
|
||||
gorm.io/gen v0.3.26 h1:sFf1j7vNStimPRRAtH4zz5NiHM+1dr6eA9aaRdplyhY=
|
||||
|
||||
@@ -1,44 +1,45 @@
|
||||
package dialogs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
var currentWindow *application.WebviewWindow
|
||||
|
||||
func Init(window *application.WebviewWindow) {
|
||||
if window == nil {
|
||||
panic("currentWindow is nil")
|
||||
}
|
||||
currentWindow = window
|
||||
}
|
||||
|
||||
func checkInit() {
|
||||
if currentWindow == nil {
|
||||
panic("Initialize dialogs package before use")
|
||||
}
|
||||
}
|
||||
|
||||
func InfoDialog(title string, message string) {
|
||||
checkInit()
|
||||
application.InfoDialog().AttachToWindow(currentWindow).SetTitle(title).SetMessage(message).Show()
|
||||
application.InfoDialog().SetTitle(title).SetMessage(message).Show()
|
||||
}
|
||||
|
||||
func WarningDialog(title string, message string) {
|
||||
checkInit()
|
||||
application.WarningDialog().AttachToWindow(currentWindow).SetTitle(title).SetMessage(message).Show()
|
||||
application.WarningDialog().SetTitle(title).SetMessage(message).Show()
|
||||
}
|
||||
|
||||
func ErrorDialog(title string, message string) {
|
||||
checkInit()
|
||||
application.ErrorDialog().AttachToWindow(currentWindow).SetTitle(title).SetMessage(message).Show()
|
||||
application.ErrorDialog().SetTitle(title).SetMessage(message).Show()
|
||||
}
|
||||
|
||||
func SaveFileDialog(title string, filename string) (string, error) {
|
||||
checkInit()
|
||||
selection, err := application.SaveFileDialog().AttachToWindow(currentWindow).SetFilename(filename).PromptForSingleSelection()
|
||||
selection, err := application.SaveFileDialog().SetFilename(filename).PromptForSingleSelection()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return selection, nil
|
||||
}
|
||||
|
||||
func OpenFileDialog(title string) (string, error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("Recovered in f", r)
|
||||
}
|
||||
}()
|
||||
dialog := application.OpenFileDialog()
|
||||
dialog.SetTitle(title)
|
||||
dialog.CanChooseDirectories(false)
|
||||
dialog.AddFilter("Электронные таблицы (.xlsx)", "*.xlsx")
|
||||
dialog.AddFilter("Электронные таблицы (.xls)", "*.xls")
|
||||
path, err := dialog.PromptForSingleSelection()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
|
||||
53
internal/extras/excel/import.go
Normal file
53
internal/extras/excel/import.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package excel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
type Importer struct {
|
||||
SheetName string
|
||||
Loader func(rowIndex int, row []string) error
|
||||
StartFromRowIdx int
|
||||
}
|
||||
|
||||
func ImportEntitiesFromSpreadsheet(path string, importers ...Importer) error {
|
||||
for _, importer := range importers {
|
||||
err := ImportEntitiesFromSpreadsheet(path, importer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ImportFromSpreadsheet(filepath string, importer Importer) error {
|
||||
f, err := excelize.OpenFile(filepath)
|
||||
defer func() {
|
||||
err := f.Close()
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("Failed to close file: %s", err))
|
||||
}
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rows, err := f.GetRows(importer.SheetName)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, row := range rows {
|
||||
err := importer.Loader(i, row)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -13,7 +13,7 @@ type Post struct {
|
||||
Id uint `gorm:"primaryKey" ui:"hidden"`
|
||||
Text string `ui:"label:Текст"`
|
||||
Deadline int64 `ui:"label:Дедлайн;datatype:datetime;"`
|
||||
CreatedAt int64 `gorm:"autoCreateTime" ui:"readonly;datatype:datetime;"`
|
||||
CreatedAt int64 `gorm:"autoCreateTime" ui:"label:Время создания; readonly; datatype:datetime;"`
|
||||
AuthorId uint `ui:"hidden" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
Author Author `ui:"label:Автор; field:Name;"`
|
||||
PostTypeId uint `ui:"hidden"`
|
||||
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
type Migrator struct{}
|
||||
@@ -77,9 +78,9 @@ func Migrate(entities ...any) error {
|
||||
err = db.AutoMigrate(entities...)
|
||||
|
||||
if err != nil {
|
||||
slog.Info("Error occurred while migrations: %s. Recreate database...", err)
|
||||
slog.Info(fmt.Sprintf("Error occurred while migrations: %s, Recreate database...", err))
|
||||
if err = createDatabase(entities...); err != nil {
|
||||
slog.Error("Error occurred again: %s. Panic!", err)
|
||||
slog.Error(fmt.Sprintf("Error occurred again: %s. Panic!", err))
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@@ -87,7 +88,7 @@ func Migrate(entities ...any) error {
|
||||
var hashAfterMigration string
|
||||
hashAfterMigration, err = CalculateFileSha256Checksum(database.Path)
|
||||
if err != nil {
|
||||
slog.Error("Failed to calc hash: %s", err)
|
||||
slog.Error(fmt.Sprintf("Failed to calc hash: %s", err))
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -95,7 +96,7 @@ func Migrate(entities ...any) error {
|
||||
slog.Info("Hashes before and after migrations are different. Recreate database...")
|
||||
err = createDatabase(entities...)
|
||||
if err != nil {
|
||||
slog.Error("Failed to create new database: %s", err)
|
||||
slog.Error(fmt.Sprintf("Failed to create new database: %s", err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,13 @@ package services
|
||||
import (
|
||||
"app/internal/dal"
|
||||
"app/internal/database"
|
||||
"app/internal/dialogs"
|
||||
"app/internal/extras/excel"
|
||||
"app/internal/models"
|
||||
"errors"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
@@ -59,3 +64,30 @@ func (service *PostTypeService) Count() (int64, error) {
|
||||
amount, err := dal.PostType.Count()
|
||||
return amount, err
|
||||
}
|
||||
|
||||
func (service *PostTypeService) ImportFromExcel() error {
|
||||
signal.Ignore(syscall.SIGSEGV)
|
||||
filepath, err := dialogs.OpenFileDialog("Импорт данных")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = excel.ImportFromSpreadsheet(filepath, excel.Importer{
|
||||
SheetName: "Тип поста",
|
||||
Loader: func(rowIndex int, row []string) error {
|
||||
id, err := strconv.Atoi(row[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
service.Create(PostType{
|
||||
Id: uint(id),
|
||||
Name: row[1],
|
||||
})
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
8
main.go
8
main.go
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"app/internal/dialogs"
|
||||
"app/internal/services"
|
||||
"embed"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
@@ -14,7 +13,7 @@ var assets embed.FS
|
||||
func main() {
|
||||
app := application.New(application.Options{
|
||||
Name: "nto_starterkit",
|
||||
Description: "A demo of using raw HTML & CSS",
|
||||
Description: "NTO toolkit template",
|
||||
Services: append([]application.Service{services.MigratorService}, services.ExportedServices...),
|
||||
Assets: application.AssetOptions{
|
||||
Handler: application.AssetFileServerFS(assets),
|
||||
@@ -29,16 +28,15 @@ func main() {
|
||||
// 'Mac' options tailor the window when running on macOS.
|
||||
// 'BackgroundColour' is the background colour of the window.
|
||||
// 'URL' is the URL that will be loaded into the webview.
|
||||
window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Завод \"Белочка\"",
|
||||
Mac: application.MacWindow{
|
||||
InvisibleTitleBarHeight: 50,
|
||||
Backdrop: application.MacBackdropTranslucent,
|
||||
TitleBar: application.MacTitleBarHiddenInset,
|
||||
},
|
||||
URL: "/",
|
||||
URL: "/",
|
||||
})
|
||||
dialogs.Init(window)
|
||||
|
||||
err := app.Run()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user