update
This commit is contained in:
132
src/components/PreviewTaskModal/PreviewTaskModal.vue
Normal file
132
src/components/PreviewTaskModal/PreviewTaskModal.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<script setup>
|
||||
import {reactive, ref, watch} from 'vue';
|
||||
import Api from "../../api/index.ts";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
|
||||
const emits = defineEmits(['success']);
|
||||
const {id} = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
});
|
||||
const visible = ref(false);
|
||||
const detail = reactive({});
|
||||
const activeKey = ref(1);
|
||||
|
||||
watch(
|
||||
() => visible.value,
|
||||
(val) => {
|
||||
if (val) Api.admin.getTaskChildrenInfo(id).then(({data}) => {
|
||||
Object.assign(detail, data);
|
||||
console.log('我看看我看看', data);
|
||||
});
|
||||
},
|
||||
{deep: true}
|
||||
)
|
||||
|
||||
const passTaskChildren = async () => {
|
||||
const {code, msg} = await Api.admin.passTaskChildren(id);
|
||||
if (code === 1) Message.success(msg);
|
||||
emits('success');
|
||||
}
|
||||
|
||||
const refuseTaskChildren = async () => {
|
||||
const {code, msg} = await Api.admin.refuseTaskChildren(id);
|
||||
if (code === 1) Message.success(msg);
|
||||
emits('success');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-link :hoverable="false" @click="visible=true">预览</a-link>
|
||||
<div @click="visible=true">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<a-modal
|
||||
title-align="start"
|
||||
title="预览"
|
||||
v-model:visible="visible">
|
||||
<a-tabs v-model:active-key="activeKey" type="rounded" v-if="detail.id !== undefined && detail.id !== null">
|
||||
<a-tab-pane v-for="(item, index) in detail.content" :title="`素材${index+1}`" :key="index">
|
||||
<a-form
|
||||
layout="vertical">
|
||||
<a-form-item label="标题">
|
||||
<a-input :model-value="item.title"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="正文">
|
||||
<a-textarea
|
||||
auto-size
|
||||
:max-length="1000"
|
||||
show-word-limit
|
||||
:model-value="item.content">
|
||||
</a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label="话题">
|
||||
<div id="tag-list" class="w-full bg-[var(--color-neutral-2)] p-[4px]">
|
||||
<a-tag v-for="v in item.tags_arr">#{{ v }}</a-tag>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="素材">
|
||||
<div class="flex flex-wrap gap-[16px]">
|
||||
<a-image
|
||||
v-for="v in item.materia_arr"
|
||||
width="60px"
|
||||
height="60px"
|
||||
:src="v">
|
||||
</a-image>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="评论区内容">
|
||||
<div class="flex flex-col gap-[8px] w-full">
|
||||
<div class="w-full flex gap-[10px] items-center" v-for="v in detail.comment">
|
||||
{{ v.id }}.
|
||||
<div class="flex-grow bg-[var(--color-neutral-2)] p-[4px] h-[40px] flex items-center">
|
||||
<div class="text-[#4E5969] text-[14px] mr-[4px]" v-if="v.pid !== 0">
|
||||
<icon-redo/>
|
||||
回复{{ v.pid }}:
|
||||
</div>
|
||||
<a-image
|
||||
v-if="v.image"
|
||||
class="mr-[12px]"
|
||||
width="30px"
|
||||
height="30px"
|
||||
:src="v.image">
|
||||
</a-image>
|
||||
第三个很好用,大家可以在网上搜同款
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<template #footer>
|
||||
<div class="flex items-center gap-[8px]">
|
||||
<a-checkbox-group>
|
||||
<template v-for="(item, index) in detail.content" :key="item">
|
||||
<a-checkbox v-show="activeKey === index" :value="item">选中</a-checkbox>
|
||||
</template>
|
||||
</a-checkbox-group>
|
||||
|
||||
<a-button @click="passTaskChildren" type="primary" class="ml-auto">通过</a-button>
|
||||
<a-button @click="refuseTaskChildren">拒绝</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#tag-list {
|
||||
:deep(.arco-tag) {
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgb(229, 230, 235);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
73
src/components/XImage/Index.vue
Normal file
73
src/components/XImage/Index.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
import {Modal} from "@arco-design/web-vue";
|
||||
|
||||
const emits = defineEmits(['delete']);
|
||||
const {width, height, aspect} = defineProps({
|
||||
width: {
|
||||
type: String,
|
||||
default: '80px'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '80px'
|
||||
},
|
||||
aspect: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
});
|
||||
const previewVisible = ref(false);
|
||||
const deleteImage = () => {
|
||||
Modal.info({
|
||||
title: "删除确认",
|
||||
content: "确认删除这张素材吗?",
|
||||
hideCancel: false,
|
||||
onOk: () => {
|
||||
emits('delete');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="x-image-box" :style="{aspectRatio: aspect ? '1 / 1' : ''}">
|
||||
<a-image
|
||||
fit="contain"
|
||||
v-model:preview-visible="previewVisible"
|
||||
@preview-visible-change="(v)=>previewVisible=v"
|
||||
v-bind="$attrs"
|
||||
:width="width"
|
||||
:height="height">
|
||||
</a-image>
|
||||
|
||||
<div class="mask">
|
||||
<icon-eye @click="previewVisible=true" class="icon" style="color: #fff"/>
|
||||
<icon-delete @click="deleteImage" class="icon" style="color: #fff"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.x-image-box {
|
||||
@apply cursor-pointer relative box-border rounded-[6px] overflow-hidden;
|
||||
outline: 1px solid #E5E6EB;
|
||||
width: v-bind(width);
|
||||
height: v-bind(height);
|
||||
|
||||
&:hover .mask {
|
||||
background-color: rgba(0, 0, 0, .4);
|
||||
|
||||
.icon {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.mask {
|
||||
@apply size-full absolute left-0 top-0 duration-500 flex justify-center items-center gap-[10px];
|
||||
.icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,74 +1,56 @@
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
import {BASEURL} from "../../utils/request.js";
|
||||
import {useUserStore} from "../../pinia/UserStore/index.js";
|
||||
import XImage from "../XImage/Index.vue";
|
||||
import Api from "../../api/index.js";
|
||||
|
||||
const UserStore = useUserStore();
|
||||
const file = ref();
|
||||
const url = defineModel();
|
||||
const {size, api} = defineProps({
|
||||
size: {
|
||||
type: String,
|
||||
default: '60px'
|
||||
},
|
||||
api: {
|
||||
type: Function,
|
||||
default: Api.system.uploadFile,
|
||||
}
|
||||
});
|
||||
const files = defineModel('files');
|
||||
const emits = defineEmits(['success']);
|
||||
|
||||
const onChange = (_, currentFile) => {
|
||||
if (currentFile.value.response && currentFile.value.response?.data) url.value = currentFile.value.response?.data;
|
||||
file.value = {
|
||||
...currentFile,
|
||||
// url: URL.createObjectURL(currentFile.file),
|
||||
};
|
||||
};
|
||||
const onProgress = (currentFile) => {
|
||||
file.value = currentFile;
|
||||
};
|
||||
const beforeUpload = (file) => {
|
||||
api(file).then(({data}) => {
|
||||
files.value.push(data);
|
||||
emits('success', data);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
{{ url }}
|
||||
<a-upload
|
||||
:action="BASEURL + '/admin/upload/upload'"
|
||||
:fileList="file ? [file] : []"
|
||||
:show-file-list="false"
|
||||
:headers="{
|
||||
'Access-Token': UserStore.token
|
||||
}"
|
||||
@change="onChange"
|
||||
@progress="onProgress"
|
||||
>
|
||||
<template #upload-button>
|
||||
<div
|
||||
:class="`arco-upload-list-item${
|
||||
file && file.status === 'error' ? ' arco-upload-list-item-error' : ''
|
||||
}`"
|
||||
>
|
||||
<div
|
||||
class="arco-upload-list-picture custom-upload-avatar"
|
||||
v-if="file && file.url"
|
||||
>
|
||||
<img :src="file.url"/>
|
||||
<div class="arco-upload-list-picture-mask">
|
||||
<IconEdit/>
|
||||
</div>
|
||||
<a-progress
|
||||
v-if="file.status === 'uploading' && file.percent < 100"
|
||||
:percent="file.percent"
|
||||
type="circle"
|
||||
size="mini"
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
left: '50%',
|
||||
top: '50%',
|
||||
transform: 'translateX(-50%) translateY(-50%)',
|
||||
}"
|
||||
/>
|
||||
<div class="flex flex-wrap gap-[15px]">
|
||||
<a-upload :style="{width: size,height: size}" @before-upload="beforeUpload" multiple>
|
||||
<template #upload-button>
|
||||
<div class="upload-button test">
|
||||
<IconPlus/>
|
||||
上传
|
||||
</div>
|
||||
<div class="arco-upload-picture-card" v-else>
|
||||
<div class="arco-upload-picture-card-text">
|
||||
<IconPlus/>
|
||||
<div style="margin-top: 10px; font-weight: 600">Upload</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-upload>
|
||||
</template>
|
||||
</a-upload>
|
||||
|
||||
<x-image
|
||||
@delete="files.splice(index,1)"
|
||||
:width="size"
|
||||
:height="size"
|
||||
:key="index"
|
||||
:src="v"
|
||||
v-for="(v, index) in files">
|
||||
</x-image>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.upload-button {
|
||||
width: v-bind(size);
|
||||
height: v-bind(size);
|
||||
border: 1px dashed rgb(229, 230, 235);
|
||||
@apply flex flex-col justify-center items-center bg-[#F2F3F5] hover:bg-[#ddd] duration-300;
|
||||
}
|
||||
</style>
|
||||
|
||||
30
src/components/upload/UploadButton.vue
Normal file
30
src/components/upload/UploadButton.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<script setup>
|
||||
import Api from "../../api/index.js";
|
||||
|
||||
const {api} = defineProps({
|
||||
api: {
|
||||
type: Function,
|
||||
default: Api.system.uploadFile,
|
||||
}
|
||||
});
|
||||
const emits = defineEmits(['success']);
|
||||
|
||||
const beforeUpload = (file) => {
|
||||
api(file).then(({data}) => {
|
||||
emits('success', data);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-upload @before-upload="beforeUpload" v-bind="$attrs">
|
||||
<template #upload-button>
|
||||
<slot name="upload-button"></slot>
|
||||
</template>
|
||||
</a-upload>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user