feat: 국방, 임관메시지 에디터에 TipTap 적용
This commit is contained in:
+4
-4
@@ -7,8 +7,8 @@ include "func.php";
|
||||
// $btn, $msg, $scoutmsg, $rate, $bill, $secretlimit
|
||||
|
||||
$btn = Util::getPost('btn');
|
||||
$msg = Util::getPost('msg');
|
||||
$scoutmsg = Util::getPost('scoutMsg');
|
||||
//$msg = Util::getPost('msg');
|
||||
//$scoutmsg = Util::getPost('scoutMsg');
|
||||
$rate = Util::getPost('rate', 'int');
|
||||
$bill = Util::getPost('bill', 'int');
|
||||
$secretlimit = Util::getPost('secretlimit', 'int');
|
||||
@@ -34,14 +34,14 @@ if ($permission < 0) {
|
||||
$nationID = $me['nation'];
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
|
||||
if ($btn == "국가방침 수정") {
|
||||
/*if ($btn == "국가방침 수정") {
|
||||
$msg = mb_substr($msg, 0, 16384);
|
||||
//$msg = StringUtil::
|
||||
$nationStor->notice = WebUtil::htmlPurify($msg);
|
||||
} elseif ($btn == "임관 권유문 수정") {
|
||||
$scoutmsg = mb_substr($scoutmsg, 0, 1000);
|
||||
$nationStor->scout_msg = WebUtil::htmlPurify($scoutmsg);
|
||||
} elseif ($btn == "세율") {
|
||||
} else*/if ($btn == "세율") {
|
||||
$rate = Util::valueFit($rate, 5, 30);
|
||||
$db->update('nation', [
|
||||
'rate' => $rate,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Nation;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Validator;
|
||||
use sammo\WebUtil;
|
||||
|
||||
use function sammo\checkSecretPermission;
|
||||
|
||||
class SetNotice extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', [
|
||||
'msg',
|
||||
])->rule('lengthMax', 'msg', 16384);
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$msg = $this->args['msg'];
|
||||
$userID = $session->userID;
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
$permission = checkSecretPermission($me, false);
|
||||
if($permission < 0){
|
||||
return "권한이 부족합니다.";
|
||||
}
|
||||
if ($me['officer_level'] < 5 && $permission != 4){
|
||||
return "권한이 부족합니다.";
|
||||
}
|
||||
|
||||
$nationID = $me['nation'];
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationStor->notice = WebUtil::htmlPurify($msg);
|
||||
|
||||
return [
|
||||
'result' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Nation;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Validator;
|
||||
use sammo\WebUtil;
|
||||
|
||||
use function sammo\checkSecretPermission;
|
||||
|
||||
class SetScoutMsg extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', [
|
||||
'msg',
|
||||
])->rule('lengthMax', 'msg', 1000);
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$msg = $this->args['msg'];
|
||||
$userID = $session->userID;
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
$permission = checkSecretPermission($me, false);
|
||||
if($permission < 0){
|
||||
return "권한이 부족합니다.";
|
||||
}
|
||||
if ($me['officer_level'] < 5 && $permission != 4){
|
||||
return "권한이 부족합니다.";
|
||||
}
|
||||
|
||||
$nationID = $me['nation'];
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationStor->scout_msg = WebUtil::htmlPurify($msg);
|
||||
|
||||
return [
|
||||
'result' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
+84
-14
@@ -1,53 +1,123 @@
|
||||
<template>
|
||||
<div>국 가 방 침 & 임관 권유 메시지</div>
|
||||
<div id="noticeForm">흠</div>
|
||||
<!--<b-button>국가방침 수정</b-button><b-button>취소</b-button>-->
|
||||
<!--<div id="noticeForm">
|
||||
<div id="noticeForm">
|
||||
<div class="bg1" style="display: flex; justify-content: space-around">
|
||||
<div style="flex: 1 1 auto">국가 방침</div>
|
||||
<div>
|
||||
<b-button>국가방침 수정</b-button><b-button>취소</b-button>
|
||||
<b-button
|
||||
@click="enableEditNationMsg"
|
||||
v-if="editable && !inEditNationMsg"
|
||||
>국가방침 수정</b-button
|
||||
>
|
||||
<b-button @click="saveNationMsg" v-if="editable && inEditNationMsg"
|
||||
>저장</b-button
|
||||
>
|
||||
<b-button v-if="editable && inEditNationMsg" @click="rollbackNationMsg"
|
||||
>취소</b-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit_form viewer"></div>
|
||||
<TipTap v-model="nationMsg" :editable="inEditNationMsg" />
|
||||
</div>
|
||||
|
||||
<div id="scoutMsgForm">
|
||||
<div class="bg1" style="display: flex; justify-content: space-around">
|
||||
<div style="flex: 1 1 auto">임관 권유</div>
|
||||
<div>
|
||||
<b-button>임관 권유문 수정</b-button><b-button>취소</b-button>
|
||||
<b-button
|
||||
@click="enableEditScoutMsg"
|
||||
v-if="editable && !inEditScoutMsg"
|
||||
>임관 권유문 수정</b-button
|
||||
>
|
||||
<b-button @click="saveScoutMsg" v-if="editable && inEditScoutMsg"
|
||||
>저장</b-button
|
||||
>
|
||||
<b-button v-if="editable && inEditScoutMsg" @click="rollbackScoutMsg"
|
||||
>취소</b-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div style="border-bottom: solid gray 0.5px">
|
||||
870px x 200px를 넘어서는 내용은 표시되지 않습니다.
|
||||
</div>
|
||||
<div style="width: 870px; margin-left: auto">
|
||||
<div class="edit_form viewer"></div>
|
||||
<TipTap v-model="scoutMsg" :editable="inEditScoutMsg" />
|
||||
</div>
|
||||
</div>!-->
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import "@scss/dipcenter.scss";
|
||||
import "@scss/common_legacy.scss";
|
||||
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
import TipTap from "./components/TipTap.vue";
|
||||
import { defineComponent, reactive, ref } from "vue";
|
||||
import { sammoAPI } from "./util/sammoAPI";
|
||||
import { isString } from "lodash";
|
||||
declare const editable: boolean;
|
||||
declare const nationMsg: string;
|
||||
declare const scoutMsg: string;
|
||||
|
||||
export default defineComponent({
|
||||
name: "PartialDipcenter",
|
||||
components: {},
|
||||
components: {
|
||||
TipTap,
|
||||
},
|
||||
data() {
|
||||
console.log(editable, ",", nationMsg, ",", scoutMsg);
|
||||
return {
|
||||
editable,
|
||||
oldNationMsg: nationMsg,
|
||||
oldScoutMsg: scoutMsg,
|
||||
nationMsg,
|
||||
scoutMsg,
|
||||
inEditNationMsg: false,
|
||||
inEditScoutMsg: false,
|
||||
};
|
||||
},
|
||||
/*methods: {},*/
|
||||
methods: {
|
||||
enableEditNationMsg() {
|
||||
this.inEditNationMsg = true;
|
||||
},
|
||||
rollbackNationMsg() {
|
||||
this.inEditNationMsg = false;
|
||||
this.nationMsg = this.oldNationMsg;
|
||||
},
|
||||
async saveNationMsg() {
|
||||
const msg = this.nationMsg;
|
||||
try {
|
||||
await sammoAPI("Nation/SetNotice", {
|
||||
msg,
|
||||
});
|
||||
this.oldNationMsg = msg;
|
||||
this.inEditNationMsg = false;
|
||||
} catch (e) {
|
||||
if (isString(e)) {
|
||||
alert(e);
|
||||
}
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
enableEditScoutMsg() {
|
||||
this.inEditScoutMsg = true;
|
||||
},
|
||||
rollbackScoutMsg() {
|
||||
this.inEditScoutMsg = false;
|
||||
this.scoutMsg = this.oldScoutMsg;
|
||||
},
|
||||
async saveScoutMsg() {
|
||||
const msg = this.scoutMsg;
|
||||
try {
|
||||
await sammoAPI("Nation/SetScoutMsg", {
|
||||
msg,
|
||||
});
|
||||
this.oldScoutMsg = msg;
|
||||
this.inEditScoutMsg = false;
|
||||
} catch (e) {
|
||||
if (isString(e)) {
|
||||
alert(e);
|
||||
}
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<b-button-toolbar key-nav v-if="editable && editor" class="bg-dark">
|
||||
<!-- 뒤로, 앞으로 -->
|
||||
<b-button-group class="mx-1">
|
||||
<b-button
|
||||
@click="editor.chain().focus().toggleBold().run()"
|
||||
:class="{ 'is-active': editor.isActive('bold') }"
|
||||
><i class="bi bi-type-bold" v-b-tooltip.hover title="진하게"></i
|
||||
></b-button>
|
||||
<b-button
|
||||
@click="editor.chain().focus().toggleItalic().run()"
|
||||
:class="{ 'is-active': editor.isActive('italic') }"
|
||||
><i class="bi bi-type-italic" v-b-tooltip.hover title="기울이기"></i
|
||||
></b-button>
|
||||
<!-- 밑줄, 효과 지우기 -->
|
||||
</b-button-group>
|
||||
|
||||
<b-button-group class="mx-1">
|
||||
<!-- 글꼴, 크기 -->
|
||||
</b-button-group>
|
||||
|
||||
<b-button-group class="mx-1">
|
||||
<b-button
|
||||
@click="editor.chain().focus().toggleStrike().run()"
|
||||
:class="{ 'is-active': editor.isActive('strike') }"
|
||||
><i
|
||||
class="bi bi-type-strikethrough"
|
||||
v-b-tooltip.hover
|
||||
title="가로선"
|
||||
></i
|
||||
></b-button>
|
||||
<!-- 윗첨자, 아랫첨자 -->
|
||||
</b-button-group>
|
||||
|
||||
<b-button-group class="mx-1">
|
||||
<!-- 마지막으로 사용한 색 -->
|
||||
<!-- 배경색, 글자색 -->
|
||||
</b-button-group>
|
||||
|
||||
<b-button-group class="mx-1">
|
||||
<!-- 이미지추가 -->
|
||||
<!-- 링크 -->
|
||||
<!-- 영상링크 -->
|
||||
<!-- 표 -->
|
||||
<!-- 구분선 삽입 -->
|
||||
</b-button-group>
|
||||
|
||||
|
||||
<b-button-group class="mx-1">
|
||||
<!-- 글머리 기호 -->
|
||||
<!-- 번호 매기기 -->
|
||||
<!-- 문단정렬(왼, 가, 오, 양)(내어, 들여) -->
|
||||
</b-button-group>
|
||||
|
||||
|
||||
<b-button-group class="mx-1">
|
||||
<!-- 줄간격 (1.0, 1.2, 1.4, 1.5, 1.6, 1.8, 2.0, 3.0) -->
|
||||
</b-button-group>
|
||||
|
||||
|
||||
<b-button-group class="mx-1">
|
||||
<!-- 원본 코드 -->
|
||||
</b-button-group>
|
||||
</b-button-toolbar>
|
||||
<editor-content :editor="editor" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
//import "@scss/common/bootstrap5.scss";
|
||||
import { defineComponent } from "vue";
|
||||
import { Editor, EditorContent } from "@tiptap/vue-3";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import {BButtonGroup, BButtonToolbar, BButton} from "bootstrap-vue-3";
|
||||
|
||||
const compoment = defineComponent({
|
||||
components: {
|
||||
EditorContent,
|
||||
BButtonGroup,
|
||||
BButtonToolbar,
|
||||
BButton,
|
||||
},
|
||||
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
editable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: null as unknown as InstanceType<typeof Editor>,
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
modelValue(value: string) {
|
||||
const isSame = this.editor.getHTML() === value;
|
||||
|
||||
if (isSame) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editor.commands.setContent(value, false);
|
||||
},
|
||||
editable(value: boolean) {
|
||||
this.editor.options.editable = value;
|
||||
if(value == true){
|
||||
this.editor.commands.focus();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
extensions: [StarterKit],
|
||||
editable: this.editable,
|
||||
content: this.modelValue,
|
||||
onUpdate: () => {
|
||||
this.$emit("update:modelValue", this.editor.getHTML());
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
this.editor.destroy();
|
||||
},
|
||||
});
|
||||
export default compoment;
|
||||
</script>
|
||||
@@ -19,9 +19,14 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@tiptap/extension-image": "^2.0.0-beta.24",
|
||||
"@tiptap/extension-link": "^2.0.0-beta.33",
|
||||
"@tiptap/starter-kit": "^2.0.0-beta.156",
|
||||
"@tiptap/vue-3": "^2.0.0-beta.83",
|
||||
"@types/bootstrap": "^5.1.6",
|
||||
"@types/downloadjs": "^1.4.2",
|
||||
"@types/linkifyjs": "^2.1.4",
|
||||
"@types/quill": "^2.0.9",
|
||||
"@types/select2": "^4.0.54",
|
||||
"@vueup/vue-quill": "^1.0.0-beta.7",
|
||||
"async-validator": "^4.0.7",
|
||||
|
||||
Reference in New Issue
Block a user