252 lines
8.1 KiB
Vue
252 lines
8.1 KiB
Vue
<template>
|
|
<div class="field is-grouped">
|
|
<div class="control mr-6">
|
|
<div class="buttons has-addons">
|
|
<button
|
|
:class="`button ${v.code === tab ? 'is-primary is-selected has-text-white' : ''}`"
|
|
v-for="v in tabs"
|
|
@click="changeTab(v)"
|
|
>
|
|
{{ v.name }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="control">
|
|
<div class="buttons has-addons">
|
|
<button
|
|
:class="`button ${v.code === option ? 'is-dark is-selected has-text-white' : ''}`"
|
|
v-for="v in options"
|
|
@click="changeOption(v)"
|
|
>
|
|
{{ v.name }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<template v-if="option === 'your'">
|
|
<template v-if="tab === 'message'">
|
|
<div class="field is-grouped" v-for="(v, i) in message">
|
|
<div class="control is-expanded">
|
|
<textarea class="textarea" placeholder="" rows="3" v-model="v.text"></textarea>
|
|
</div>
|
|
<div class="control">
|
|
<a class="mr-3" @click="add()">
|
|
<SvgIcon v-bind="{ name: 'add1.png', type: 'primary', size: 20 }"></SvgIcon>
|
|
</a>
|
|
<a @click="remove(v, i)">
|
|
<SvgIcon v-bind="{ name: 'bin1.svg', type: 'danger', size: 20 }"></SvgIcon>
|
|
</a>
|
|
<p class="mt-2">
|
|
<a @click="copyContent(v.text)">
|
|
<SvgIcon v-bind="{ name: 'copy.svg', type: 'primary', size: 22 }"></SvgIcon>
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="mt-5">
|
|
<button class="button is-primary has-text-white" @click="update()">Cập nhật</button>
|
|
</div>
|
|
</template>
|
|
<template v-else-if="tab === 'image'">
|
|
<div class="field is-grouped mb-0">
|
|
<div class="control is-expanded"></div>
|
|
<div class="control">
|
|
<FileUpload v-bind="{ position: 'left' }" @files="getImages"></FileUpload>
|
|
</div>
|
|
</div>
|
|
<div class="field is-grouped is-grouped-multiline" v-if="image.length > 0">
|
|
<div class="control mb-2" v-for="(v, i) in image">
|
|
<ChipImage
|
|
style="width: 128px"
|
|
@remove="removeImage(v, i)"
|
|
v-bind="{ show: ['copy', 'download', 'delete'], file: v, image: `${$getpath()}static/files/${v.file}` }"
|
|
>
|
|
</ChipImage>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else-if="tab === 'file'">
|
|
<div class="field is-grouped mb-0">
|
|
<div class="control is-expanded"></div>
|
|
<div class="control">
|
|
<FileUpload v-bind="{ position: 'left', type: 'file' }" @files="getFiles"></FileUpload>
|
|
</div>
|
|
</div>
|
|
<FileShow @remove="removeFile" v-bind="{ files: file, show: { delete: 1 } }"></FileShow>
|
|
</template>
|
|
<template v-else-if="tab === 'link'">
|
|
<div class="field is-grouped" v-for="(v, i) in link">
|
|
<div class="control is-expanded">
|
|
<input class="input" placeholder="" v-model="v.link" />
|
|
</div>
|
|
<div class="control">
|
|
<a class="mr-3" @click="copyContent(v.link)">
|
|
<SvgIcon v-bind="{ name: 'copy.svg', type: 'primary', size: 20 }"></SvgIcon>
|
|
</a>
|
|
<a class="mr-3" :href="v.link" target="_blank">
|
|
<SvgIcon v-bind="{ name: 'open.svg', type: 'primary', size: 20 }"></SvgIcon>
|
|
</a>
|
|
<a class="mr-3" @click="addLink()">
|
|
<SvgIcon v-bind="{ name: 'add1.png', type: 'primary', size: 18 }"></SvgIcon>
|
|
</a>
|
|
<a @click="removeLink(v, i)">
|
|
<SvgIcon v-bind="{ name: 'bin1.svg', type: 'danger', size: 18 }"></SvgIcon>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="mt-5">
|
|
<button class="button is-primary has-text-white" @click="update()">Cập nhật</button>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
<template v-else-if="option === 'system'">
|
|
<template v-if="tab === 'message'">
|
|
<div v-if="message">
|
|
<div class="px-2 py-2 mb-2" style="border: 1px solid #e8e8e8" v-for="(v, i) in message">
|
|
<span class="mr-3">{{ v.text }}</span>
|
|
<a @click="copyContent(v.text)">
|
|
<SvgIcon v-bind="{ name: 'copy.svg', type: 'primary', size: 20 }"></SvgIcon>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else-if="tab === 'image'">
|
|
<div class="field is-grouped is-grouped-multiline" v-if="image.length > 0">
|
|
<div class="control mb-2" v-for="(v, i) in image">
|
|
<ChipImage
|
|
style="width: 128px"
|
|
v-bind="{ show: ['copy', 'download'], file: v, image: `${$getpath()}static/files/${v.file}` }"
|
|
>
|
|
</ChipImage>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else-if="tab === 'file'">
|
|
<FileShow v-bind="{ files: file }"></FileShow>
|
|
</template>
|
|
<template v-else-if="tab === 'link'">
|
|
<div class="px-2 py-2 mb-2" style="border: 1px solid #e8e8e8" v-for="(v, i) in link">
|
|
<a :href="v.link" target="_blank" class="mr-3">{{ v.link }}</a>
|
|
<a @click="copyContent(v.link)">
|
|
<SvgIcon v-bind="{ name: 'copy.svg', type: 'primary', size: 20 }"></SvgIcon>
|
|
</a>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
</template>
|
|
<script setup>
|
|
const {
|
|
$id,
|
|
$copy,
|
|
$copyToClipboard,
|
|
$getdata,
|
|
$resetNull,
|
|
$findapi,
|
|
$insertapi,
|
|
$updateapi,
|
|
$remove,
|
|
$deleteapi,
|
|
$empty,
|
|
} = useNuxtApp();
|
|
import ChipImage from "~/components/media/ChipImage.vue";
|
|
import FileShow from "~/components/media/FileShow.vue";
|
|
const tabs = [
|
|
{ code: "message", name: "Tin nhắn" },
|
|
{ code: "image", name: "Hình ảnh" },
|
|
{ code: "file", name: "Tài liệu" },
|
|
{ code: "link", name: "Liên kết" },
|
|
];
|
|
const options = [
|
|
{ code: "system", name: "Của hệ thống" },
|
|
{ code: "your", name: "Của bạn" },
|
|
];
|
|
var props = defineProps({
|
|
pagename: String,
|
|
row: Object,
|
|
});
|
|
var message = ref();
|
|
var image = ref();
|
|
var file = ref();
|
|
var link = ref();
|
|
var tab = ref("message");
|
|
var record = await $getdata("useraction", { user: 1, action: props.row.id }, undefined, true);
|
|
var option = ref(record ? "your" : "system");
|
|
function getValue() {
|
|
if (option.value === "your") {
|
|
message.value = record ? $copy(record.message || [{ code: $id() }]) : [{ code: $id() }];
|
|
image.value = record ? $copy(record.image) : [];
|
|
file.value = record ? $copy(record.file) : [];
|
|
link.value = record ? $copy(record.link || [{ code: $id() }]) : [{ code: $id() }];
|
|
return;
|
|
}
|
|
message.value = $copy(props.row.message || []);
|
|
image.value = $copy(props.row.image || []);
|
|
file.value = $copy(props.row.file || []);
|
|
link.value = $copy(props.row.link || []);
|
|
}
|
|
// get values
|
|
getValue();
|
|
// next
|
|
function changeTab(v) {
|
|
tab.value = v.code;
|
|
}
|
|
function changeOption(v) {
|
|
option.value = v.code;
|
|
getValue();
|
|
}
|
|
function getFiles(files) {
|
|
let copy = $copy(file.value);
|
|
copy = copy.concat(files);
|
|
file.value = copy;
|
|
if (option.value === "your") update();
|
|
}
|
|
function getImages(images) {
|
|
let copy = $copy(image.value);
|
|
copy = copy.concat(images);
|
|
image.value = copy;
|
|
if (option.value === "your") update();
|
|
}
|
|
function copyContent(text) {
|
|
$copyToClipboard(text);
|
|
}
|
|
function add() {
|
|
message.value.push({ code: $id() });
|
|
}
|
|
function remove(i) {
|
|
message.value.splice(i, 1);
|
|
}
|
|
function addLink() {
|
|
link.value.push({ code: $id() });
|
|
}
|
|
function removeLink(i) {
|
|
link.value.splice(i, 1);
|
|
}
|
|
async function update() {
|
|
let data = record ? $resetNull(record) : null;
|
|
if (!data) data = { user: 1, action: props.row.id };
|
|
let arr = message.value.filter((v) => !$empty(v.text));
|
|
data.message = arr.length === 0 ? null : arr;
|
|
data.image = image.value;
|
|
data.file = file.value;
|
|
let arr1 = link.value.filter((v) => !$empty(v.link));
|
|
data.link = arr1.length === 0 ? null : arr1;
|
|
let api = $findapi("useraction");
|
|
record = data.id
|
|
? await $updateapi("useraction", data, api.params.values)
|
|
: await $insertapi("useraction", data, api.params.values);
|
|
getValue();
|
|
}
|
|
async function removeImage(v, i) {
|
|
let rs = await $deleteapi("file", v.id);
|
|
$remove(image.value, i);
|
|
if (option.value === "your") update();
|
|
}
|
|
async function removeFile(data) {
|
|
let v = data.v;
|
|
let i = data.i;
|
|
let rs = await $deleteapi("file", v.id);
|
|
$remove(file.value, i);
|
|
if (option.value === "your") update();
|
|
}
|
|
</script>
|