2023-11-16-1
This commit is contained in:
@@ -65,7 +65,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,createVNode} from 'vue'
|
||||
import { defineComponent,ref,createVNode,computed} from 'vue'
|
||||
import HeaderComponent from "@/component/HomePage/Header.vue";
|
||||
import HistoryDetail from "@/component/Detail/HistoryDetail.vue";
|
||||
import { Https } from "@/tool/https";
|
||||
@@ -83,23 +83,25 @@ export default defineComponent({
|
||||
setup() {
|
||||
let rangePickerValue:any = ref([])
|
||||
let renameData:any = ref({}) //修改名字选中的数据
|
||||
const columns:any = ref([
|
||||
{ title: useI18n().t('HistoryPage.CollectionsName'), align:'center', ellipsis: true, width: 150, dataIndex: 'name', key: 'collectionName' },
|
||||
{ title: useI18n().t('HistoryPage.UptateTime'), align:'center', ellipsis: true,width: 150, dataIndex: 'updateDate', key: 'updateTime',customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time
|
||||
}},
|
||||
{ title: useI18n().t('HistoryPage.SketchCounts'), align:'center', ellipsis: true, width: 150, dataIndex: 'sketchCount', key: 'sketchCounts' },
|
||||
{
|
||||
title: useI18n().t('HistoryPage.Operations'),
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
// slots:{customRender:'action'}
|
||||
Operations:true,
|
||||
},
|
||||
]);
|
||||
const columns:any = computed(()=>{
|
||||
return [
|
||||
{ title: useI18n().t('HistoryPage.CollectionsName'), align:'center', ellipsis: true, width: 150, dataIndex: 'name', key: 'collectionName' },
|
||||
{ title: useI18n().t('HistoryPage.UptateTime'), align:'center', ellipsis: true,width: 150, dataIndex: 'updateDate', key: 'updateTime',customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time
|
||||
}},
|
||||
{ title: useI18n().t('HistoryPage.SketchCounts'), align:'center', ellipsis: true, width: 150, dataIndex: 'sketchCount', key: 'sketchCounts' },
|
||||
{
|
||||
title: useI18n().t('HistoryPage.Operations'),
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
// slots:{customRender:'action'}
|
||||
Operations:true,
|
||||
},
|
||||
]
|
||||
});
|
||||
let collectionList:any = ref([])
|
||||
let {t} = useI18n()
|
||||
return {
|
||||
|
||||
@@ -89,22 +89,37 @@
|
||||
</div>
|
||||
<div class="content_search_block">
|
||||
<input class="search_input" :placeholder="$t('LibraryPage.inputContent1')" v-model="searchPictureName" @keydown.enter="getLibraryList()">
|
||||
<a-cascader
|
||||
@click.stop="dropdownVisibleChange"
|
||||
ref="cascader"
|
||||
v-model:value="value.labelValue"
|
||||
style="width: 60%"
|
||||
:field-names="{ label: 'classificationName', value: 'id', children: 'childList'}"
|
||||
multiple
|
||||
@change="setLabel1"
|
||||
max-tag-count="responsive"
|
||||
:options="options"
|
||||
placeholder="Please select"
|
||||
:show-search="{ filter }"
|
||||
:open="labelOpen.labelOpen"
|
||||
dropdownClassName="libraryPageCascader"
|
||||
>
|
||||
</a-cascader>
|
||||
<div class="search_cascader">
|
||||
<a-cascader
|
||||
@click.stop="dropdownVisibleChange"
|
||||
ref="cascader"
|
||||
v-model:value="value.labelValue"
|
||||
style="width: 100%"
|
||||
:field-names="{ label: 'label', value: 'value', children: 'childList'}"
|
||||
multiple
|
||||
@change="setLabel1"
|
||||
:changeOnSelect="false"
|
||||
max-tag-count="responsive"
|
||||
:options="options"
|
||||
placeholder="Please select"
|
||||
:show-search="{ filter }"
|
||||
:open="false"
|
||||
dropdownClassName="libraryPageCascader"
|
||||
>
|
||||
</a-cascader>
|
||||
<div v-show="labelOpen.labelOpen" @click.stop="" class="search_cascader_checkbox">
|
||||
<a-checkbox-group
|
||||
v-model:value="value.labelValue"
|
||||
:options="options"
|
||||
/>
|
||||
<br>
|
||||
<a-checkbox-group
|
||||
v-model:value="value.labelValue"
|
||||
:options="options.childList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="search_icon_block" @click="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div> -->
|
||||
<div class="generage_btn search_icon_block" @click="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div>
|
||||
|
||||
@@ -126,7 +141,7 @@
|
||||
<span class="icon iconfont icon-tianxie operate_icon"></span>
|
||||
</div>
|
||||
<div class="img_operate_block" @click.stop="showRenameModal(img,'single')">
|
||||
<span class="icon iconfont icon-zhongmingming operate_icon"></span>
|
||||
<span class="icon iconfont icon-biaoqian operate_icon"></span>
|
||||
</div>
|
||||
<div class="img_operate_block" @click.stop="deleteSinglePic(img,index)">
|
||||
<span class="icon iconfont icon-shanchu operate_icon"></span>
|
||||
@@ -189,7 +204,7 @@
|
||||
</div>
|
||||
|
||||
<div class="input_box" :class="{active:inputShow}">
|
||||
<input class="search_input" @input="ifMaximumLength" :maxlength='inputShow?0:9999' :class="{active:checkbox[0].type}" :readonly="checkbox[0].type" :placeholder="$t('LibraryPage.inputContent2')" v-model="captionGeneration">
|
||||
<input class="search_input" @input="ifMaximumLength" :maxlength='inputShow?0:9999' :class="{active:checkbox[0].type}" @keydown.enter="getgenerate" :readonly="checkbox[0].type" :placeholder="$t('LibraryPage.inputContent2')" v-model="captionGeneration">
|
||||
<div class="generage_btn started_btn" @click.stop="getgenerate">{{ $t('LibraryPage.Generate') }}</div>
|
||||
<span>{{ $t('LibraryPage.maximumLength') }}</span>
|
||||
</div>
|
||||
@@ -250,12 +265,12 @@
|
||||
</div>
|
||||
|
||||
<div class="content_body_table scroll_style">
|
||||
<div class="content_img_item" v-for="(img,index) in generateList" :key="img.id" @click="selectImgItem(img)">
|
||||
<div class="content_img_item" v-for="(img,index) in generateList" :key="img.id">
|
||||
<div :class="['content_img_item_block', selectImgList.indexOf(img.id) > -1 ? 'select_item_img' :'']">
|
||||
<img v-lazy="img.imgUrl" :key="img.imgUrl" :class="['content_img', ['Moodboard','Printboard'].indexOf(selectCode) > -1 ? 'board_content_img' :'']"/>
|
||||
<div class="img_item_hover">
|
||||
<div class="img_operate_content">
|
||||
<div class="img_operate_block" @click.stop="editPlacementClick(img)">
|
||||
<div class="img_operate_block">
|
||||
<i v-if="!img.like" class="fi fi-rr-heart operate_icon" @click.stop="likeFile(img,'like')"></i>
|
||||
<i v-else class="fi fi-sr-heart operate_icon" @click.stop="likeFile(img,'noLike')"></i>
|
||||
</div>
|
||||
@@ -330,7 +345,7 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { LoadingOutlined } from "@ant-design/icons-vue";
|
||||
import { defineComponent,h ,ref,createVNode,nextTick,provide} from 'vue'
|
||||
import { defineComponent,h ,ref,createVNode,nextTick,provide,computed} from 'vue'
|
||||
import HeaderComponent from "@/component/HomePage/Header.vue";
|
||||
import ModelPlacement from '@/component/LibraryPage/ModelPlacement.vue';
|
||||
import setLabel from '@/component/LibraryPage/setLabel.vue';
|
||||
@@ -354,15 +369,17 @@ export default defineComponent({
|
||||
},
|
||||
setup() {
|
||||
|
||||
let menuList = ref([
|
||||
{title:useI18n().t('LibraryPage.Moodboard'),code:'Moodboard',icon:'fi fi-rr-grid',showChildren:false,children:[]},
|
||||
{title:useI18n().t('LibraryPage.Prints'),code:'Printboard',icon:'fi fi-rs-objects-column',showChildren:false,children:[]},
|
||||
// {title:'Sketches',code:'SketchboardFirst',icon:'fi icon iconfont icon-a-waitao_changkuanwaitao11x',showChildren:false,children:[{title:'Apparel',code:'Sketchboard'}]},
|
||||
{title:useI18n().t('LibraryPage.Sketches'),code:'Sketchboard',icon:'fi icon iconfont icon-a-waitao_changkuanwaitao11x',showChildren:false,children:[]},
|
||||
// {title:'Market Sketch',code:'MarketingSketch',icon:'icon-fuwushichang',showChildren:false,children:[]},
|
||||
{title:useI18n().t('LibraryPage.Mannequins'),code:'Models',icon:'fi fi-rs-people',showChildren:false,children:[]},
|
||||
let menuList = computed(()=>{
|
||||
return [
|
||||
{title:useI18n().t('LibraryPage.Moodboard'),code:'Moodboard',icon:'fi fi-rr-grid',showChildren:false,children:[]},
|
||||
{title:useI18n().t('LibraryPage.Prints'),code:'Printboard',icon:'fi fi-rs-objects-column',showChildren:false,children:[]},
|
||||
// {title:'Sketches',code:'SketchboardFirst',icon:'fi icon iconfont icon-a-waitao_changkuanwaitao11x',showChildren:false,children:[{title:'Apparel',code:'Sketchboard'}]},
|
||||
{title:useI18n().t('LibraryPage.Sketches'),code:'Sketchboard',icon:'fi icon iconfont icon-a-waitao_changkuanwaitao11x',showChildren:false,children:[]},
|
||||
// {title:'Market Sketch',code:'MarketingSketch',icon:'icon-fuwushichang',showChildren:false,children:[]},
|
||||
{title:useI18n().t('LibraryPage.Mannequins'),code:'Models',icon:'fi fi-rs-people',showChildren:false,children:[]},
|
||||
|
||||
])
|
||||
]
|
||||
})
|
||||
let selectImgList:any = ref([])
|
||||
let selectCode:any = ref('Moodboard')
|
||||
let searchPictureName = ref('')
|
||||
@@ -414,7 +431,7 @@ export default defineComponent({
|
||||
name:useI18n().t('LibraryPage.model')+'1'
|
||||
})
|
||||
let {t} = useI18n()
|
||||
const options = ref([
|
||||
const options:any = ref([
|
||||
]);
|
||||
let type:any = {
|
||||
selectCode:selectCode,
|
||||
@@ -432,6 +449,8 @@ export default defineComponent({
|
||||
labelOpen:false,
|
||||
editLabelOpen:false,
|
||||
})
|
||||
let isTest = ref()
|
||||
|
||||
return {
|
||||
menuList,
|
||||
selectImgList,
|
||||
@@ -467,6 +486,7 @@ export default defineComponent({
|
||||
filter,
|
||||
t,
|
||||
labelOpen,
|
||||
isTest,
|
||||
}
|
||||
},
|
||||
data(this_) {
|
||||
@@ -488,6 +508,7 @@ export default defineComponent({
|
||||
},
|
||||
async mounted(){
|
||||
let userInfo:any = getCookie("userInfo")
|
||||
this.isTest = getCookie('isTest') || ''
|
||||
this.userInfo = JSON.parse(userInfo);
|
||||
this.uploadUrl = getUploadUrl()
|
||||
this.getLibraryList()
|
||||
@@ -539,11 +560,14 @@ export default defineComponent({
|
||||
})
|
||||
},
|
||||
likeFile(item:any,str:string){
|
||||
let designType = this.selectCode == 'Sketchboard' || this.selectCode == 'MarketingSketch' ? this.designType : ''
|
||||
|
||||
if(str == 'like'){
|
||||
let data = {
|
||||
generateDetailId:item.id,
|
||||
level1Type:this.selectCode,
|
||||
level2Type: item.category,
|
||||
level2Type: designType,
|
||||
gender:this.sex,
|
||||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.generateLike, data).then(
|
||||
@@ -569,22 +593,24 @@ export default defineComponent({
|
||||
if(menu.children?.length){ //证明是有子菜单
|
||||
menu.showChildren = !menu.showChildren
|
||||
}else{
|
||||
this.selectCode = menu.code
|
||||
if(menu.code != this.upload.level1Type){
|
||||
this.selectCode = menu.code
|
||||
this.currentPage = 1,
|
||||
this.total = 0,
|
||||
this.searchPictureName = ''
|
||||
this.imgList = [],
|
||||
this.sex = 'Female',
|
||||
this.designType = 'Outwear',
|
||||
this.selectImgList = []
|
||||
this.selectSingleImg = {}
|
||||
this.getLibraryList()
|
||||
this.getClass()
|
||||
this.uploadGenerate = 'Upload'
|
||||
this.captionGeneration = ''
|
||||
this.selectGenerateList = []
|
||||
this.generateList = []
|
||||
}
|
||||
this.upload.level1Type = menu.code
|
||||
this.currentPage = 1,
|
||||
this.total = 0,
|
||||
this.searchPictureName = ''
|
||||
this.imgList = [],
|
||||
this.sex = 'Female',
|
||||
this.designType = 'Outwear',
|
||||
this.selectImgList = []
|
||||
this.selectSingleImg = {}
|
||||
this.getLibraryList()
|
||||
this.getClass()
|
||||
this.uploadGenerate = 'Upload'
|
||||
this.captionGeneration = ''
|
||||
this.selectGenerateList = []
|
||||
this.generateList = []
|
||||
}
|
||||
},
|
||||
|
||||
@@ -671,9 +697,17 @@ export default defineComponent({
|
||||
// ).catch((res)=>{
|
||||
// this.closeRenameModal()
|
||||
// });
|
||||
console.log(this.value);
|
||||
|
||||
let labelArr:any = []
|
||||
this.value.editLabelValue.forEach((item:any)=>{
|
||||
// if(item.length > 1){
|
||||
// labelArr.push(item[item.length-1])
|
||||
// }else{
|
||||
|
||||
// }
|
||||
labelArr.push(item[item.length-1])
|
||||
|
||||
})
|
||||
let designType = this.selectCode == 'Sketchboard' || this.selectCode == 'MarketingSketch' ? this.designType : ''
|
||||
let data2 = {
|
||||
@@ -686,16 +720,16 @@ export default defineComponent({
|
||||
"updateTime": "",
|
||||
"userId": 0
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.relationLibrary, data2).then(
|
||||
(rv: any) => {
|
||||
console.log(rv);
|
||||
this.getLibraryList()
|
||||
this.closeRenameModal()
|
||||
// Https.axiosPost(Https.httpUrls.relationLibrary, data2).then(
|
||||
// (rv: any) => {
|
||||
// console.log(rv);
|
||||
// this.getLibraryList()
|
||||
// this.closeRenameModal()
|
||||
|
||||
}
|
||||
).catch((res)=>{
|
||||
this.closeRenameModal()
|
||||
});
|
||||
// }
|
||||
// ).catch((res)=>{
|
||||
// this.closeRenameModal()
|
||||
// });
|
||||
},
|
||||
|
||||
//打开修改名称弹窗
|
||||
@@ -706,10 +740,48 @@ export default defineComponent({
|
||||
this.newPicName = ''
|
||||
return
|
||||
}
|
||||
let classData = {
|
||||
"classificationIdList": [],
|
||||
"classificationName": "",
|
||||
"createTime": "",
|
||||
"deleteConfirm": 0,
|
||||
"id": 0,
|
||||
"isDeleted": 0,
|
||||
"libraryIdList": [data.id],
|
||||
"parentId": 0,
|
||||
"type": "",
|
||||
"updateTime": "",
|
||||
"userId": 0
|
||||
}
|
||||
if(type === 'single'){
|
||||
this.selectSingleImg = data
|
||||
this.newPicName = data.name
|
||||
Https.axiosPost(Https.httpUrls.getRelClassificationIdList, classData).then(
|
||||
(rv: any) => {
|
||||
let arr:any = []
|
||||
this.options.forEach((item:any)=>{
|
||||
rv.forEach((rvItem:any) => {
|
||||
if(item.id == rvItem){
|
||||
arr.push(item.id)
|
||||
}else{
|
||||
item.childList.forEach((optionsItem:any) => {
|
||||
if(optionsItem.id == rvItem){
|
||||
arr.push([optionsItem.parentId,optionsItem.id])
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
this.value.editLabelValue = arr
|
||||
}
|
||||
).catch((res)=>{
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this.renameType = type
|
||||
this.labelOpen.labelOpen = false
|
||||
this.renameVisivle = true
|
||||
@@ -718,11 +790,12 @@ export default defineComponent({
|
||||
|
||||
},
|
||||
uploadGenerateOpen(str:any){
|
||||
if(this.uploadGenerate == str){
|
||||
this.uploadGenerate = str
|
||||
}else{
|
||||
this.uploadGenerate = str
|
||||
if(this.uploadGenerate == 'Generate'){
|
||||
if(str != 'Generate'){
|
||||
this.getLibraryList()
|
||||
}
|
||||
}
|
||||
this.uploadGenerate = str
|
||||
},
|
||||
//删除单个图片
|
||||
deleteSinglePic(data:any,index:any){
|
||||
@@ -989,6 +1062,12 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
getgenerate(){
|
||||
if(this.isTest){//试用用户禁止使用
|
||||
message.warning(
|
||||
this.t('isTest.available')
|
||||
);
|
||||
return
|
||||
}
|
||||
let generateType = this.checkbox.filter((v:any)=>v.type)[0].name
|
||||
let generageImg = this.selectGenerateList.filter((v:any)=>v.checked)[0]
|
||||
let data = {
|
||||
@@ -1040,6 +1119,8 @@ export default defineComponent({
|
||||
arr = {
|
||||
id:v.generateItemId,
|
||||
imgUrl:v.generateItemUrl,
|
||||
like:v.isLiked
|
||||
|
||||
}
|
||||
this.generateList.push(arr)
|
||||
})
|
||||
@@ -1054,37 +1135,40 @@ export default defineComponent({
|
||||
dropdownVisibleChange(){
|
||||
this.labelOpen.labelOpen = true
|
||||
document.addEventListener('click',this.setClick)
|
||||
nextTick().then(()=>{
|
||||
let cascader = document.getElementsByClassName('libraryPageCascader')[0]
|
||||
let cascaderChild = cascader.children[0].children[0]
|
||||
cascader.addEventListener('click',(event)=>{
|
||||
event.stopPropagation()
|
||||
})
|
||||
if(cascader.children[0].children[0].children.length > 1){
|
||||
}else{
|
||||
// nextTick().then(()=>{
|
||||
// let cascader = document.getElementsByClassName('libraryPageCascader')[0]
|
||||
// let cascaderChild = cascader.children[0].children[0]
|
||||
// cascader.addEventListener('click',(event)=>{
|
||||
// event.stopPropagation()
|
||||
// })
|
||||
// if(cascader.children[0].children[0].children.length > 1){
|
||||
// }else{
|
||||
|
||||
let button1:any = document.createElement("span")
|
||||
button1.classList.add('started_btn','cascader_btn1')
|
||||
let button2:any = document.createElement("span")
|
||||
button2.classList.add('started_btn','cascader_btn2')
|
||||
let divMax:any = document.createElement("div")
|
||||
divMax.classList.add('cascader_btn_max')
|
||||
button1.textContent = 'redact'
|
||||
// button2.textContent = '删除'
|
||||
button1.addEventListener('click',this.addLabel,false)
|
||||
// button2.addEventListener('click',this.removeLabel,false)
|
||||
divMax.appendChild(button1)
|
||||
// divMax.appendChild(button2)
|
||||
cascaderChild?.insertAdjacentElement("afterbegin", divMax);
|
||||
// let button1:any = document.createElement("span")
|
||||
// button1.classList.add('started_btn','cascader_btn1')
|
||||
// let button2:any = document.createElement("span")
|
||||
// button2.classList.add('started_btn','cascader_btn2')
|
||||
// let divMax:any = document.createElement("div")
|
||||
// divMax.classList.add('cascader_btn_max')
|
||||
// button1.textContent = 'redact'
|
||||
// // button2.textContent = '删除'
|
||||
// button1.addEventListener('click',this.addLabel,false)
|
||||
// // button2.addEventListener('click',this.removeLabel,false)
|
||||
// divMax.appendChild(button1)
|
||||
// // divMax.appendChild(button2)
|
||||
// cascaderChild?.insertAdjacentElement("afterbegin", divMax);
|
||||
|
||||
// cascader.addEventListener('click',this.cascaderClick)
|
||||
}
|
||||
})
|
||||
// // cascader.addEventListener('click',this.cascaderClick)
|
||||
// }
|
||||
// })
|
||||
},
|
||||
// cascaderClick(e:Event){
|
||||
// console.log(e.target)
|
||||
// },
|
||||
setLabel1(value:any,selectedOptions:any){
|
||||
setLabel1(value:any){
|
||||
console.log(value);
|
||||
console.log(this.value.labelValue);
|
||||
// this.value.labelValue = [[31,32],[31,33],[31,35],[31,40],[31,41],[31,42]]
|
||||
let myCascader:any = this.$refs.cascader
|
||||
},
|
||||
setClick(){
|
||||
@@ -1136,6 +1220,16 @@ export default defineComponent({
|
||||
(rv: any) => {
|
||||
console.log(rv);
|
||||
this.options = rv
|
||||
rv.forEach((rvItem:any,rvIndex:number) => {
|
||||
this.options[rvIndex].value = rvItem.id
|
||||
this.options[rvIndex].label = rvItem.classificationName
|
||||
rvItem.childList.forEach((childItem:any,index:number) => {
|
||||
this.options[rvIndex].childList[index].value = childItem.id
|
||||
this.options[rvIndex].childList[index].label = childItem.classificationName
|
||||
});
|
||||
});
|
||||
console.log(this.options);
|
||||
|
||||
|
||||
}
|
||||
).catch((res)=>{
|
||||
@@ -1301,7 +1395,23 @@ export default defineComponent({
|
||||
color: #C2C2C2;
|
||||
}
|
||||
}
|
||||
|
||||
.search_cascader{
|
||||
width: 60%;
|
||||
display: flex;
|
||||
position: relative;
|
||||
.search_cascader_checkbox{
|
||||
position: absolute;
|
||||
top: 3rem;
|
||||
background: #fff;
|
||||
z-index: 2;
|
||||
border: 1px solid;
|
||||
.ant-checkbox-group{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.search_icon_block{
|
||||
width: 5.2rem;
|
||||
height: 2.8rem;
|
||||
@@ -1580,6 +1690,9 @@ export default defineComponent({
|
||||
.operate_icon{
|
||||
font-size: 1.8rem;
|
||||
color: #fff;
|
||||
&.fi-sr-heart{
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +453,9 @@ export default defineComponent({
|
||||
if (rv) {
|
||||
this.createTimer();
|
||||
let token = rv.token;
|
||||
let isTest = true
|
||||
setCookie("token", token);
|
||||
setCookie("isTest", isTest);
|
||||
setCookie("userInfo", JSON.stringify(rv));
|
||||
this.turnToHomePage();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user