Фикс ошибок
This commit is contained in:
parent
7e706a3981
commit
a1dc96088c
34 changed files with 1584 additions and 1180 deletions
|
@ -1,4 +1,5 @@
|
|||
package api
|
||||
|
||||
//go:generate merger -i parts/common.yaml -i parts/game.yaml -i parts/admin.yaml -i parts/user.yaml -i parts/schemas.yaml -i parts/responses.yaml -o openapi.yaml
|
||||
//go:generate oapi-codegen -generate server,spec -package api -o ./server.go ./openapi.yaml
|
||||
//go:generate oapi-codegen -generate types -package api -o ./types.go ./openapi.yaml
|
||||
|
|
774
api/openapi.yaml
774
api/openapi.yaml
|
@ -1,237 +1,245 @@
|
|||
openapi: "3.1.0"
|
||||
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: nQuest
|
||||
|
||||
servers:
|
||||
- url: /api
|
||||
|
||||
paths:
|
||||
# User routes
|
||||
/user:
|
||||
get:
|
||||
components:
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/userResponse"
|
||||
403:
|
||||
$ref: "#/components/responses/errorResponse"
|
||||
/user/login:
|
||||
post:
|
||||
security: []
|
||||
requestBody:
|
||||
errorResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
required: [email, password]
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/userResponse"
|
||||
400:
|
||||
$ref: "#/components/responses/errorResponse"
|
||||
/user/register:
|
||||
post:
|
||||
security: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
password2:
|
||||
type: string
|
||||
required: [username, email, password, password2]
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/userResponse"
|
||||
400:
|
||||
$ref: "#/components/responses/errorResponse"
|
||||
/user/logout:
|
||||
post:
|
||||
responses:
|
||||
204:
|
||||
description: "success logout"
|
||||
400:
|
||||
$ref: "#/components/responses/errorResponse"
|
||||
|
||||
# Game routes
|
||||
/games:
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameListResponse"
|
||||
/engine/{uid}:
|
||||
get:
|
||||
operationId: gameEngine
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/taskResponse"
|
||||
/engine/{uid}/code:
|
||||
post:
|
||||
operationId: enterCode
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
message:
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/taskResponse"
|
||||
/file/{uid}:
|
||||
get:
|
||||
operationId: getFile
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
200:
|
||||
description: file
|
||||
content:
|
||||
"application/octet-stream":
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
|
||||
# Admin routes
|
||||
/admin/file/{quest}/upload:
|
||||
post:
|
||||
operationId: adminUploadFile
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
parameters:
|
||||
- name: quest
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
- message
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
type: string
|
||||
format: binary
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/uploadResponse"
|
||||
/admin/file/{quest}:
|
||||
get:
|
||||
operationId: adminListFiles
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
parameters:
|
||||
- name: quest
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/filesListResponse"
|
||||
|
||||
/admin/games:
|
||||
get:
|
||||
operationId: adminListGames
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameListResponse"
|
||||
post:
|
||||
operationId: adminEditGame
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
requestBody:
|
||||
description: ""
|
||||
filesListResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/gameEdit"
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameAdminResponse"
|
||||
/admin/games/{uid}:
|
||||
get:
|
||||
operationId: adminGetGame
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
items:
|
||||
$ref: '#/components/schemas/fileItem'
|
||||
type: array
|
||||
description: ""
|
||||
gameAdminResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
$ref: '#/components/schemas/gameEdit'
|
||||
description: ""
|
||||
gameListResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/components/schemas/gameView'
|
||||
type: array
|
||||
description: ""
|
||||
gameResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/gameView'
|
||||
description: ""
|
||||
taskResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/taskView'
|
||||
description: ""
|
||||
uploadResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
uuid:
|
||||
format: uuid
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameAdminResponse"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
userView:
|
||||
type: string
|
||||
required:
|
||||
- uuid
|
||||
type: object
|
||||
description: ""
|
||||
userResponse:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/userView'
|
||||
description: ""
|
||||
schemas:
|
||||
codeEdit:
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
format: uuid
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
type: object
|
||||
codeView:
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
type: object
|
||||
fileItem:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
username:
|
||||
type: string
|
||||
originalName:
|
||||
type: string
|
||||
size:
|
||||
type: integer
|
||||
required:
|
||||
- id
|
||||
- originalName
|
||||
- size
|
||||
type: object
|
||||
gameEdit:
|
||||
properties:
|
||||
description:
|
||||
type: string
|
||||
icon:
|
||||
format: uuid
|
||||
type: string
|
||||
id:
|
||||
format: uuid
|
||||
type: string
|
||||
points:
|
||||
type: integer
|
||||
tasks:
|
||||
items:
|
||||
$ref: '#/components/schemas/taskEdit'
|
||||
type: array
|
||||
title:
|
||||
type: string
|
||||
type:
|
||||
$ref: '#/components/schemas/gameType'
|
||||
visible:
|
||||
type: boolean
|
||||
required:
|
||||
- visible
|
||||
- title
|
||||
- description
|
||||
- type
|
||||
- tasks
|
||||
- points
|
||||
type: object
|
||||
gameType:
|
||||
enum:
|
||||
- virtual
|
||||
- city
|
||||
type: string
|
||||
gameView:
|
||||
properties:
|
||||
authors:
|
||||
items:
|
||||
$ref: '#/components/schemas/userView'
|
||||
type: array
|
||||
createdAt:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
icon:
|
||||
format: uuid
|
||||
type: string
|
||||
id:
|
||||
format: uuid
|
||||
type: string
|
||||
points:
|
||||
type: integer
|
||||
taskCount:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
type:
|
||||
$ref: '#/components/schemas/gameType'
|
||||
visible:
|
||||
type: boolean
|
||||
required:
|
||||
- id
|
||||
- title
|
||||
- description
|
||||
- type
|
||||
- points
|
||||
- taskCount
|
||||
- createdAt
|
||||
- authors
|
||||
type: object
|
||||
taskEdit:
|
||||
properties:
|
||||
codes:
|
||||
items:
|
||||
$ref: '#/components/schemas/codeEdit'
|
||||
type: array
|
||||
id:
|
||||
format: uuid
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- title
|
||||
- text
|
||||
- codes
|
||||
type: object
|
||||
taskView:
|
||||
properties:
|
||||
codes:
|
||||
items:
|
||||
$ref: '#/components/schemas/codeView'
|
||||
type: array
|
||||
message:
|
||||
enum:
|
||||
- ok_code
|
||||
- invalid_code
|
||||
- old_code
|
||||
- next_level
|
||||
- game_complete
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
required:
|
||||
- title
|
||||
- text
|
||||
- codes
|
||||
type: object
|
||||
userView:
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
experience:
|
||||
type: integer
|
||||
level:
|
||||
type: integer
|
||||
expToCurrentLevel:
|
||||
type: integer
|
||||
expToNextLevel:
|
||||
type: integer
|
||||
experience:
|
||||
type: integer
|
||||
games:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/gameView"
|
||||
role:
|
||||
$ref: '#/components/schemas/gameView'
|
||||
type: array
|
||||
id:
|
||||
format: uuid
|
||||
type: string
|
||||
level:
|
||||
type: integer
|
||||
role:
|
||||
enum:
|
||||
- user
|
||||
- creator
|
||||
- admin
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- username
|
||||
|
@ -242,221 +250,201 @@ components:
|
|||
- expToNextLevel
|
||||
- games
|
||||
- role
|
||||
gameView:
|
||||
type: object
|
||||
securitySchemes:
|
||||
cookieAuth:
|
||||
in: cookie
|
||||
name: session
|
||||
type: apiKey
|
||||
info:
|
||||
title: nQuest
|
||||
version: 1.0.0
|
||||
openapi: 3.1.0
|
||||
paths:
|
||||
/admin/file/{quest}:
|
||||
get:
|
||||
operationId: adminListFiles
|
||||
parameters:
|
||||
- in: path
|
||||
name: quest
|
||||
required: true
|
||||
schema:
|
||||
format: uuid
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/filesListResponse'
|
||||
security:
|
||||
- cookieAuth:
|
||||
- creator
|
||||
- admin
|
||||
/admin/file/{quest}/upload:
|
||||
post:
|
||||
operationId: adminUploadFile
|
||||
parameters:
|
||||
- in: path
|
||||
name: quest
|
||||
required: true
|
||||
schema:
|
||||
format: uuid
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
properties:
|
||||
id:
|
||||
file:
|
||||
format: binary
|
||||
type: string
|
||||
format: uuid
|
||||
visible:
|
||||
type: boolean
|
||||
title:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
type:
|
||||
$ref: "#/components/schemas/gameType"
|
||||
points:
|
||||
type: integer
|
||||
taskCount:
|
||||
type: integer
|
||||
createdAt:
|
||||
type: string
|
||||
authors:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/userView"
|
||||
icon:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- id
|
||||
- title
|
||||
- description
|
||||
- type
|
||||
- points
|
||||
- taskCount
|
||||
- createdAt
|
||||
- authors
|
||||
taskView:
|
||||
schema: null
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
enum:
|
||||
- ok_code
|
||||
- invalid_code
|
||||
- old_code
|
||||
- next_level
|
||||
- game_complete
|
||||
title:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
codes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/codeView"
|
||||
required:
|
||||
- title
|
||||
- text
|
||||
- codes
|
||||
codeView:
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
gameEdit:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/uploadResponse'
|
||||
security:
|
||||
- cookieAuth:
|
||||
- creator
|
||||
- admin
|
||||
/admin/games:
|
||||
get:
|
||||
operationId: adminListGames
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/gameListResponse'
|
||||
post:
|
||||
operationId: adminEditGame
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/gameEdit'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/gameAdminResponse'
|
||||
security:
|
||||
- cookieAuth:
|
||||
- creator
|
||||
- admin
|
||||
/admin/games/{uid}:
|
||||
get:
|
||||
operationId: adminGetGame
|
||||
parameters:
|
||||
- in: path
|
||||
name: uid
|
||||
required: true
|
||||
schema:
|
||||
format: uuid
|
||||
visible:
|
||||
type: boolean
|
||||
title:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
type:
|
||||
$ref: "#/components/schemas/gameType"
|
||||
tasks:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/taskEdit"
|
||||
points:
|
||||
type: integer
|
||||
icon:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/gameAdminResponse'
|
||||
security:
|
||||
- cookieAuth:
|
||||
- creator
|
||||
- admin
|
||||
/engine/{uid}:
|
||||
get:
|
||||
operationId: gameEngine
|
||||
parameters:
|
||||
- in: path
|
||||
name: uid
|
||||
required: true
|
||||
schema:
|
||||
format: uuid
|
||||
required:
|
||||
- visible
|
||||
- title
|
||||
- description
|
||||
- type
|
||||
- tasks
|
||||
- points
|
||||
taskEdit:
|
||||
type: object
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/taskResponse'
|
||||
/engine/{uid}/code:
|
||||
post:
|
||||
operationId: enterCode
|
||||
parameters:
|
||||
- in: path
|
||||
name: uid
|
||||
required: true
|
||||
schema:
|
||||
format: uuid
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
title:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
codes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/codeEdit"
|
||||
required:
|
||||
- title
|
||||
- text
|
||||
- codes
|
||||
codeEdit:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
gameType:
|
||||
type: string
|
||||
enum:
|
||||
- virtual
|
||||
- city
|
||||
fileItem:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
originalName:
|
||||
type: string
|
||||
size:
|
||||
type: integer
|
||||
required:
|
||||
- id
|
||||
- originalName
|
||||
- size
|
||||
responses:
|
||||
userResponse:
|
||||
description: ""
|
||||
200:
|
||||
$ref: '#/components/responses/taskResponse'
|
||||
/games:
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/gameListResponse'
|
||||
/user:
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/userResponse'
|
||||
403:
|
||||
$ref: '#/components/responses/errorResponse'
|
||||
/user/login:
|
||||
post:
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/userView"
|
||||
errorResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
message:
|
||||
email:
|
||||
type: string
|
||||
required: [code, message]
|
||||
gameListResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/gameView"
|
||||
gameResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/gameView"
|
||||
gameAdminResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/gameEdit"
|
||||
taskResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/taskView"
|
||||
uploadResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
uuid:
|
||||
password:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- uuid
|
||||
filesListResponse:
|
||||
description: ""
|
||||
- email
|
||||
- password
|
||||
type: object
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/userResponse'
|
||||
400:
|
||||
$ref: '#/components/responses/errorResponse'
|
||||
security: []
|
||||
/user/logout:
|
||||
post:
|
||||
responses:
|
||||
204:
|
||||
description: success logout
|
||||
400:
|
||||
$ref: '#/components/responses/errorResponse'
|
||||
/user/register:
|
||||
post:
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/fileItem"
|
||||
securitySchemes:
|
||||
cookieAuth:
|
||||
type: apiKey
|
||||
in: cookie
|
||||
name: session
|
||||
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
password2:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- username
|
||||
- email
|
||||
- password
|
||||
- password2
|
||||
type: object
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/userResponse'
|
||||
400:
|
||||
$ref: '#/components/responses/errorResponse'
|
||||
security: []
|
||||
security:
|
||||
- cookieAuth: []
|
||||
servers:
|
||||
- url: /api
|
||||
|
|
74
api/parts/admin.yaml
Normal file
74
api/parts/admin.yaml
Normal file
|
@ -0,0 +1,74 @@
|
|||
paths:
|
||||
/admin/file/{quest}/upload:
|
||||
post:
|
||||
operationId: adminUploadFile
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
parameters:
|
||||
- name: quest
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
type: string
|
||||
format: binary
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/uploadResponse"
|
||||
/admin/file/{quest}:
|
||||
get:
|
||||
operationId: adminListFiles
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
parameters:
|
||||
- name: quest
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/filesListResponse"
|
||||
|
||||
/admin/games:
|
||||
get:
|
||||
operationId: adminListGames
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameListResponse"
|
||||
post:
|
||||
operationId: adminEditGame
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/gameEdit"
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameAdminResponse"
|
||||
/admin/games/{uid}:
|
||||
get:
|
||||
operationId: adminGetGame
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
security:
|
||||
- cookieAuth: [creator, admin]
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameAdminResponse"
|
19
api/parts/common.yaml
Normal file
19
api/parts/common.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
openapi: "3.1.0"
|
||||
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: nQuest
|
||||
|
||||
servers:
|
||||
- url: /api
|
||||
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
cookieAuth:
|
||||
type: apiKey
|
||||
in: cookie
|
||||
name: session
|
||||
|
||||
security:
|
||||
- cookieAuth: []
|
43
api/parts/game.yaml
Normal file
43
api/parts/game.yaml
Normal file
|
@ -0,0 +1,43 @@
|
|||
paths:
|
||||
/games:
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/gameListResponse"
|
||||
/engine/{uid}:
|
||||
get:
|
||||
operationId: gameEngine
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/taskResponse"
|
||||
/engine/{uid}/code:
|
||||
post:
|
||||
operationId: enterCode
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/taskResponse"
|
||||
|
66
api/parts/responses.yaml
Normal file
66
api/parts/responses.yaml
Normal file
|
@ -0,0 +1,66 @@
|
|||
components:
|
||||
responses:
|
||||
userResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/userView"
|
||||
errorResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
message:
|
||||
type: string
|
||||
required: [code, message]
|
||||
gameListResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/gameView"
|
||||
gameResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/gameView"
|
||||
gameAdminResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/gameEdit"
|
||||
taskResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/taskView"
|
||||
uploadResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- uuid
|
||||
filesListResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/fileItem"
|
186
api/parts/schemas.yaml
Normal file
186
api/parts/schemas.yaml
Normal file
|
@ -0,0 +1,186 @@
|
|||
components:
|
||||
schemas:
|
||||
userView:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
username:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
experience:
|
||||
type: integer
|
||||
level:
|
||||
type: integer
|
||||
expToCurrentLevel:
|
||||
type: integer
|
||||
expToNextLevel:
|
||||
type: integer
|
||||
games:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/gameView"
|
||||
role:
|
||||
type: string
|
||||
enum:
|
||||
- user
|
||||
- creator
|
||||
- admin
|
||||
required:
|
||||
- id
|
||||
- username
|
||||
- email
|
||||
- experience
|
||||
- level
|
||||
- expToCurrentLevel
|
||||
- expToNextLevel
|
||||
- games
|
||||
- role
|
||||
gameView:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
visible:
|
||||
type: boolean
|
||||
title:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
type:
|
||||
$ref: "#/components/schemas/gameType"
|
||||
points:
|
||||
type: integer
|
||||
taskCount:
|
||||
type: integer
|
||||
createdAt:
|
||||
type: string
|
||||
authors:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/userView"
|
||||
icon:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- id
|
||||
- title
|
||||
- description
|
||||
- type
|
||||
- points
|
||||
- taskCount
|
||||
- createdAt
|
||||
- authors
|
||||
taskView:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
enum:
|
||||
- ok_code
|
||||
- invalid_code
|
||||
- old_code
|
||||
- next_level
|
||||
- game_complete
|
||||
title:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
codes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/codeView"
|
||||
required:
|
||||
- title
|
||||
- text
|
||||
- codes
|
||||
codeView:
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
gameEdit:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
visible:
|
||||
type: boolean
|
||||
title:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
type:
|
||||
$ref: "#/components/schemas/gameType"
|
||||
tasks:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/taskEdit"
|
||||
points:
|
||||
type: integer
|
||||
icon:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- visible
|
||||
- title
|
||||
- description
|
||||
- type
|
||||
- tasks
|
||||
- points
|
||||
taskEdit:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
title:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
codes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/codeEdit"
|
||||
required:
|
||||
- id
|
||||
- title
|
||||
- text
|
||||
- codes
|
||||
codeEdit:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
gameType:
|
||||
type: string
|
||||
enum:
|
||||
- virtual
|
||||
- city
|
||||
fileItem:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
originalName:
|
||||
type: string
|
||||
size:
|
||||
type: integer
|
||||
required:
|
||||
- id
|
||||
- originalName
|
||||
- size
|
57
api/parts/user.yaml
Normal file
57
api/parts/user.yaml
Normal file
|
@ -0,0 +1,57 @@
|
|||
paths:
|
||||
/user:
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/userResponse"
|
||||
403:
|
||||
$ref: "#/components/responses/errorResponse"
|
||||
/user/login:
|
||||
post:
|
||||
security: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
required: [email, password]
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/userResponse"
|
||||
400:
|
||||
$ref: "#/components/responses/errorResponse"
|
||||
/user/register:
|
||||
post:
|
||||
security: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
password2:
|
||||
type: string
|
||||
required: [username, email, password, password2]
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/userResponse"
|
||||
400:
|
||||
$ref: "#/components/responses/errorResponse"
|
||||
/user/logout:
|
||||
post:
|
||||
responses:
|
||||
204:
|
||||
description: "success logout"
|
||||
400:
|
||||
$ref: "#/components/responses/errorResponse"
|
|
@ -43,9 +43,6 @@ type ServerInterface interface {
|
|||
// (POST /engine/{uid}/code)
|
||||
EnterCode(ctx echo.Context, uid openapi_types.UUID) error
|
||||
|
||||
// (GET /file/{uid})
|
||||
GetFile(ctx echo.Context, uid openapi_types.UUID) error
|
||||
|
||||
// (GET /games)
|
||||
GetGames(ctx echo.Context) error
|
||||
|
||||
|
@ -179,24 +176,6 @@ func (w *ServerInterfaceWrapper) EnterCode(ctx echo.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// GetFile converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetFile(ctx echo.Context) error {
|
||||
var err error
|
||||
// ------------- Path parameter "uid" -------------
|
||||
var uid openapi_types.UUID
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "uid", ctx.Param("uid"), &uid, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter uid: %s", err))
|
||||
}
|
||||
|
||||
ctx.Set(CookieAuthScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.GetFile(ctx, uid)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetGames converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetGames(ctx echo.Context) error {
|
||||
var err error
|
||||
|
@ -283,7 +262,6 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||
router.GET(baseURL+"/admin/games/:uid", wrapper.AdminGetGame)
|
||||
router.GET(baseURL+"/engine/:uid", wrapper.GameEngine)
|
||||
router.POST(baseURL+"/engine/:uid/code", wrapper.EnterCode)
|
||||
router.GET(baseURL+"/file/:uid", wrapper.GetFile)
|
||||
router.GET(baseURL+"/games", wrapper.GetGames)
|
||||
router.GET(baseURL+"/user", wrapper.GetUser)
|
||||
router.POST(baseURL+"/user/login", wrapper.PostUserLogin)
|
||||
|
@ -295,27 +273,26 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"H4sIAAAAAAAC/8xZS2/cNhD+KwXbo2JtHifdUsM1ghpBmzq9GAuDlsZrxhIpkyPHW0P/vRhS0kor6uGN",
|
||||
"ssnJWnI4j28enKGfWayyXEmQaFj0zDSYXEkD9gdorfSnaoUWYiURJNInz/NUxByFkuEXoyStmfgOMk5f",
|
||||
"uVY5aBSOT6wSexy3ObCICYmwAc3KgGVgDN+0Nw1qITesLAOm4aEQGhIWXTkWO/p1UNOrmy8QIyvpQAIm",
|
||||
"1iInnVjEiP+tSMFcCIMHWSEQMmvAbxpuWcR+DXdghY7MhCTiA0JG4iqduNZ8O6TShmfwPsmEPEilMU2I",
|
||||
"81kicEzy98WCJPwr4OtcLJCb+8VhIKZOCb/QIk8VTxYI66IQCf29VTrjyCK3EExEsiWaG7+FAb04QMR0",
|
||||
"GKAyqNg0qWtjaiqpa2v3GHr2DwHNCuuDFtgNa8tS+pUeIU2K94TMsiVgSouNkDz9yDO/Tkb8562QezBY",
|
||||
"7h1m1VEfNE056Gk96aHYbUzaNdP8XInqeunfAJStZnaBIWpX4vYLTMBQYOpH1y1Ml65LoisD9iiMuOnw",
|
||||
"ulEqBS57Dqkpa+nd6Kok10Y2QAx567LSE2SROe4aC56ygMUCt61jO9OaittzMi/wTun50O6qQh/aWANH",
|
||||
"SN7jYQl/5HA6VYXEge0fECPOiLHwqAxqa9/GPGh86QucJiW8FXC+/5tK7/H/TMcgPPkjZAj2PaRqkCyf",
|
||||
"oNJ/yObhqv8ym4divtWa1vmo7q+rPlTIR56KpP6p0uZTwhNep/AIlLYUMNckNwUEb/4eDbImvXuQQcZF",
|
||||
"6tUBnvJLdVpoDRIvrEnepLJkH+Fpgga0ABkPDAKElFmgz5wdq+mwrlqlHbcTdHVCKvri1L573Umk0n/J",
|
||||
"+6pCQx5UXugAVSvpc0QP9RrCSn1PgxkwA3GhBW7/IRjrfFH3At4XeGfBpxbQLVEoW0OYAWNa5SpiPBd/",
|
||||
"QtXTC3mrrLEuXJn8uwBDkfgI2riW8vXJ6mRlu6AcJM8Fi9jbk9cnKyp8HO+sGqGF1M5S4fMDsShpeQM2",
|
||||
"OShabaP7IWERs8MTzTF/0HBnuWieAQJddleVEcR5Z8JDpdTOAagLCFr98lQ7ug66o/Gb1WooSBu6sD99",
|
||||
"tr1glW3jf9UPsXJNJzzohG6KsdmszBBKny0R4XRMmCyb31Wy3ZtYsiJFkXONIbF5lXD0DFVkZEfSjZBc",
|
||||
"b70TgmeEermT9sbBb/JQU8XGA/e8ztQXK9sb4a3RIxFAN/q5qzDDjlnmyaE81KDua8i3OyB8LkQyUT/O",
|
||||
"oYZlOi1cqB+5diwGDMiNkDCBCWFxZgl/XkQ6j0Uu3jrGhfXE70+HM4mgT12TdiQLD8u3Wc8Y895HDkxK",
|
||||
"H9Lu8hkPIsDZV813iqABkFWMgK8MauBZF+zpa6b3RGZvqAqV8YJfFZnlSj2JtN3oiMTPrls94CJsvzWW",
|
||||
"AXu3ejt9qPsvgpaKYao2Qg6n41/KWFUvLNlS2TI8y+TcmK9KJ9O5VHfizYnF8qqP8OrlCHcugXUHb1Xg",
|
||||
"LMCJrqf/u97LIDNFHIMxv1SsD9V4p6OGjTDo4ndcy0815Q+NjN3mG+/u/HHPM+k1cttSfu5YG+1A1lSU",
|
||||
"DejHuuwXOmURC2nkK9fl/wEAAP//MtUIV2ocAAA=",
|
||||
"H4sIAAAAAAAC/8xYS3OkNhD+KyklR2JmHyduG5fj2oprK9l4c3FNuWRoj7UGCUvNrCcu/nuqJWBgEA+P",
|
||||
"iXdPHkPTj6+/bnXricUqy5UEiYZFT0yDyZU0YP8BrZX+XD2hB7GSCBLpJ8/zVMQchZLhV6MkPTPxHWSc",
|
||||
"fuVa5aBROD2xSuznuMuBRUxIhA1oVgYsA2P4pv3SoBZyw8oyYBoeCqEhYdGVU7GXXwe1vLr5CjGykj5I",
|
||||
"wMRa5OQTixjpvxUpmAth8KgoBEJmA/hFwy2L2M/hHqzQiZmQTHxEyMhc5RPXmu+GXNrwDD4kmZBHuTTm",
|
||||
"CWk+SwSOWf5/sSAL/wj4NhcL5OZ+cRhIqXPCb7TIU8WTBWhdFCKhv7dKZxxZ5B4EE0y2QnP5WxjQiwNE",
|
||||
"SocBKoNKTVO6llNTRV1He6DQ8/4Y0KyxPmiBfWFjWcq/0mOkKfGekVmxBExpsRGSp5945vfJiH+9HfIA",
|
||||
"Bqu9o6z61AdN0w56Xk9mKHYvJuOaGX6uRHW89E8AqlYzu8GQtGtxhw0mYCgw9aPrHky3rkuSKwO2FUbc",
|
||||
"dHTdKJUCl72E1JK19S67Kst1kA0QQ9m6rPwEWWROu8aCpyxgscBd67N9aE3H7SWZF3in9Hxo912hD22s",
|
||||
"gSMkH/C4gn9lOp2qQuLA6+/AERfEGD2qgNretzEPmlz6iNOUhLcDzs9/0+k9+Z+ZGIRHP0OGYB9DyioL",
|
||||
"qiCGAh9u/c8LfIj4rfm0Lkp1f10No0JueSqS+l+VNj8lPOJ1Clug2iXWXJPdFBC8RfxS3GZD1tR4DzLI",
|
||||
"uEi9PsBjfqlOC61B4oUNyVtZVuwTPE7IgBYg44FtgJAyCwybswmbDvuqVdpJO0FXV6WiX5xmeG86SVT6",
|
||||
"T3of4RvxoMpCB6jaSV8ieqjXEFbue6bMgBmICy1w9zfBWNeLuhfwocA7Cz7Nge4RUdkGwgwY0+pZEeO5",
|
||||
"+AOqwV7IW2WDdXRl8q8CDDFxC9q4ufLNyepkZUehHCTPBYvYu5M3JyvqfhzvrBuhhdQuVOHTA6ko6fEG",
|
||||
"bHEQW+20+zFhEbMbFC0zv9OGZ7VongECnXhXVRCkeR/CQ+XUPgGoCwhaQ/PUTLoOuvvx29VqiKSNXNhf",
|
||||
"QdtZsM628b/qU6xc0xcedEK3ythqVmYIpS9WiHB6TZismt9UsjtYW7IiRZFzjSGp+TXh6NmsKMiOpRsh",
|
||||
"ud551wTPHvX8JB3shC/KUNPFxol7Xlfqs53t7fE26BEG0LF+7jrMcGKWuXcojw2oeyXy8gSET4VIJvrH",
|
||||
"OdSwTJeFo/or947FgAG5ERImMCEszqzgj4tI58bI8a0TXFiv/f5yOJMI+tQNaa8U4XH1NusuY94lyZFF",
|
||||
"6UN6vLVV5bRcUyOTdu4asfjFzWVHtPz21VoZsPerd9MfdW/EWy6GqdoIOUy8P5Wxrl5YsaV4MTy159yY",
|
||||
"b0on06ypZ87mi8UY1Ed49XyEO+1u3cFbFTgLcJLr+f++dxHGTBHHYMxPlepjPd77qGEjDDr+jnv5uZb8",
|
||||
"rszYv3zrfTt/sfHsNI3dtpUfm2ujZ+2a2rsBva0PkEKnLGIhLTfluvwvAAD//8w97C1ZGwAA",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
|
|
@ -85,7 +85,7 @@ type GameView struct {
|
|||
// TaskEdit defines model for taskEdit.
|
||||
type TaskEdit struct {
|
||||
Codes []CodeEdit `json:"codes"`
|
||||
Id *openapi_types.UUID `json:"id,omitempty"`
|
||||
Id openapi_types.UUID `json:"id"`
|
||||
Text string `json:"text"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
|
|
@ -29,5 +29,6 @@ module.exports = {
|
|||
'react'
|
||||
],
|
||||
rules: {
|
||||
indent: ['error', 4]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ const Quest = () => {
|
|||
{tasks.map(renderTaskForm(remove))}
|
||||
<Form.Item wrapperCol={buttonLayout}>
|
||||
<Button type='primary' onClick={() => add()} block>
|
||||
<PlusOutlined/> Добавить уровень
|
||||
<PlusOutlined /> Добавить уровень
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</>
|
||||
|
@ -132,12 +132,12 @@ const Quest = () => {
|
|||
action={`/api/admin/file/${quest.id}/upload`}
|
||||
listType='picture'
|
||||
maxCount={10}
|
||||
itemRender={renderFile}
|
||||
itemRender={(e, file) => renderFile(e, file, quest)}
|
||||
>
|
||||
<Button icon={<UploadOutlined />}>Загрузка</Button>
|
||||
</Upload>
|
||||
Ранее загруженные файлы:
|
||||
<List dataSource={files} renderItem={renderFileItem} />
|
||||
<List dataSource={files} renderItem={x => renderFileItem(x, quest)} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Modal
|
||||
|
@ -165,8 +165,7 @@ const Quest = () => {
|
|||
</List.Item>
|
||||
)} />
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
</>)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
|
@ -184,7 +183,7 @@ const renderTaskForm = remove => task => (
|
|||
cancelText='Нет'
|
||||
>
|
||||
<Button danger>
|
||||
<CloseOutlined/> Удалить уровень
|
||||
<CloseOutlined /> Удалить уровень
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
]}
|
||||
|
@ -204,7 +203,7 @@ const renderTaskForm = remove => task => (
|
|||
{codes.map(renderCodeForm(codesOpts.remove))}
|
||||
<Form.Item wrapperCol={{ offset: 6, span: 14 }}>
|
||||
<Button key='addCode' type='primary' onClick={() => codesOpts.add()} block>
|
||||
<PlusOutlined/> Добавить код
|
||||
<PlusOutlined /> Добавить код
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</>
|
||||
|
@ -227,7 +226,7 @@ const renderCodeForm = remove => code => (
|
|||
// cancelText='Нет'
|
||||
// >
|
||||
<Button key="delete" danger onClick={() => remove(code.name)}>
|
||||
<CloseOutlined/> Удалить код
|
||||
<CloseOutlined /> Удалить код
|
||||
</Button>
|
||||
// </Popconfirm>
|
||||
]}
|
||||
|
@ -244,21 +243,24 @@ const renderCodeForm = remove => code => (
|
|||
</Card>
|
||||
)
|
||||
|
||||
const renderFile = (e, file) => (
|
||||
<div key={file ? file.uid : null}>
|
||||
const renderFile = (e, file, quest) => {
|
||||
console.log(file)
|
||||
return (
|
||||
<div key={file ? file.uid : null}>
|
||||
{e}
|
||||
{file && file.response && file.response.uuid
|
||||
? <>Код для вставки: <pre>![](/api/file/{file.response.uuid})</pre></>
|
||||
? <>Код для вставки: <pre>![](/file/{quest.id}/{file.originFileObj.name})</pre></>
|
||||
: null}
|
||||
</div>
|
||||
)
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const renderFileItem = (file) => (
|
||||
const renderFileItem = (file, quest) => (
|
||||
<List.Item>
|
||||
<List.Item.Meta
|
||||
avatar={<Avatar src={`/api/file/${file.id}`} />}
|
||||
avatar={<Avatar src={`/file/${quest.id})/${file.originalName}`} />}
|
||||
title={file.originalName}
|
||||
description={<>Код для вставки: <pre>![](/api/file/{file.id})</pre></>}
|
||||
description={<>Код для вставки: <pre>![](/file/{quest.id}/{file.originalName})</pre></>}
|
||||
/>
|
||||
</List.Item>
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const manifest = {
|
|||
workbox: {
|
||||
cleanupOutdatedCaches: true
|
||||
},
|
||||
base: 'assets',
|
||||
manifest: {
|
||||
name: 'NQuest',
|
||||
short_name: 'NQuest',
|
||||
|
@ -80,6 +81,12 @@ export default defineConfig({
|
|||
changeOrigin: true,
|
||||
secure: false,
|
||||
ws: false
|
||||
},
|
||||
'/file': {
|
||||
target: 'http://localhost:8000',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
ws: false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
8
main.go
8
main.go
|
@ -127,12 +127,12 @@ func main() {
|
|||
|
||||
api.RegisterHandlersWithBaseURL(codegen, handler, "/api")
|
||||
|
||||
e.FileFS("/", "index.html", distIndexHtml)
|
||||
e.FileFS("/*", "index.html", distIndexHtml)
|
||||
e.StaticFS("/", distDirFS)
|
||||
|
||||
// --[ System ]--
|
||||
e.GET("/metrics", echoprometheus.NewHandler())
|
||||
|
||||
e.StaticFS("/file", afero.NewIOFS(storage))
|
||||
e.StaticFS("/*", distDirFS)
|
||||
|
||||
e.Logger.Debugf("backend version %s", Version)
|
||||
e.Logger.Fatal(e.Start(cfg.Listen))
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ func (a *Admin) AdminEditGame(ctx echo.Context) error {
|
|||
})
|
||||
}
|
||||
tasks = append(tasks, api.TaskEdit{
|
||||
Id: &t.ID,
|
||||
Id: t.ID,
|
||||
Codes: codes,
|
||||
Text: t.Text,
|
||||
Title: t.Title,
|
||||
|
@ -98,7 +98,7 @@ func (a *Admin) AdminGetGame(ctx echo.Context, uid uuid.UUID) error {
|
|||
})
|
||||
}
|
||||
tasks = append(tasks, api.TaskEdit{
|
||||
Id: &t.ID,
|
||||
Id: t.ID,
|
||||
Codes: codes,
|
||||
Text: t.Text,
|
||||
Title: t.Title,
|
||||
|
@ -163,12 +163,8 @@ func (*Admin) mapCreateGameRequest(req *api.GameEdit, user *models.User) *models
|
|||
IconID: req.Icon,
|
||||
}
|
||||
for order, te := range req.Tasks {
|
||||
id := uuid.New()
|
||||
if te.Id != nil {
|
||||
id = *te.Id
|
||||
}
|
||||
task := &models.Task{
|
||||
ID: id,
|
||||
ID: te.Id,
|
||||
Title: te.Title,
|
||||
Text: te.Text,
|
||||
Codes: make([]*models.Code, 0, len(te.Codes)),
|
||||
|
|
|
@ -40,16 +40,6 @@ func (u *File) AdminUploadFile(c echo.Context, quest uuid.UUID) error {
|
|||
})
|
||||
}
|
||||
|
||||
// (GET /file/{uid})
|
||||
func (u *File) GetFile(c echo.Context, uid uuid.UUID) error {
|
||||
f, rdr, err := u.FileService.GetFile(c.Request().Context(), uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Stream(200, f.ContentType, rdr)
|
||||
}
|
||||
|
||||
func (u *File) AdminListFiles(c echo.Context, quest uuid.UUID) error {
|
||||
fl, err := u.FileService.GetFilesByQuest(c.Request().Context(), quest)
|
||||
if err != nil {
|
||||
|
|
|
@ -10,6 +10,7 @@ type Task struct {
|
|||
Title string
|
||||
Text string
|
||||
MaxTime int
|
||||
Game *Game
|
||||
GameID uuid.UUID
|
||||
Codes []*Code `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
TaskOrder uint
|
||||
|
|
|
@ -3,7 +3,6 @@ package service
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -53,21 +52,6 @@ func (u *File) Upload(
|
|||
return file.ID, u.DB.WithContext(ctx).Create(file).Error
|
||||
}
|
||||
|
||||
func (u *File) GetFile(ctx context.Context, uid uuid.UUID) (*models.File, io.ReadCloser, error) {
|
||||
f := new(models.File)
|
||||
if err := u.DB.WithContext(ctx).First(f, uid).Error; err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
filePath := fmt.Sprintf("%s/%s", f.QuestID.String(), f.Filename)
|
||||
file, err := u.store.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return f, file, nil
|
||||
}
|
||||
|
||||
func (u *File) GetFilesByQuest(ctx context.Context, quest uuid.UUID) ([]*models.File, error) {
|
||||
list := make([]*models.File, 0)
|
||||
|
||||
|
|
|
@ -68,7 +68,14 @@ func (gs *Game) ListByAuthor(ctx context.Context, author *models.User) ([]*model
|
|||
}
|
||||
|
||||
func (gs *Game) UpsertGame(ctx context.Context, game *models.Game) (*models.Game, error) {
|
||||
return game, gs.DB.Debug().
|
||||
|
||||
ids := []uuid.UUID{}
|
||||
for _, t := range game.Tasks {
|
||||
ids = append(ids, t.ID)
|
||||
}
|
||||
gs.DB.Delete([]models.Task{}, `game_id = ? and id not in (?)`, game.ID, ids)
|
||||
|
||||
err := gs.DB.
|
||||
Session(&gorm.Session{FullSaveAssociations: true}).
|
||||
Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
|
@ -76,6 +83,11 @@ func (gs *Game) UpsertGame(ctx context.Context, game *models.Game) (*models.Game
|
|||
"title", "description",
|
||||
}),
|
||||
}).
|
||||
Create(&game).
|
||||
Create(game).
|
||||
Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return game, gs.DB.Save(game).Error
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue