123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- <template>
- <div class="upload-video">
- <div class="upload-box">
- <input
- class="upload-input"
- ref="chooseFile"
- type="file"
- @change="addFile"
- multiple
- accept=".jpg,.png"
- />
- <i class="iconfont icon-empty"></i>
- <p>点击或将文件拖拽到这里上传</p>
- <p class="gray-font">
- 建议最佳:横版大图:宽高比16:9,1280*720≤尺寸≤2560*1440,
- </p>
- <p class="gray-font">竖版大图:宽高比9:16,720*1280≤尺寸≤1440*2560,</p>
- <p class="gray-font">小图:宽高比1.52,456*300≤尺寸≤1368*900,</p>
- <p class="gray-font">
- 支持JPG,PNG等图片格式。命名格式:推广书籍名称-需求方-文案
- </p>
- </div>
- <div class="upload-list">
- <div class="list-item" v-for="(item, index) in fileList" :key="index">
- <i class="iconfont icon-paper-clip"></i>
- <p>
- {{ item.name }}
- <i class="iconfont icon-guanbi" @click="deleteItem(index)"></i
- ><a-progress
- :showInfo="false"
- :percent="item.percent"
- status="active"
- />
- </p>
- </div>
- </div>
- <p class="gray-font footer-num">已选择:{{ fileList.length }}/20</p>
- </div>
- </template>
- <script lang="ts">
- import { defineComponent, reactive, toRefs, ref, watch, h } from "vue";
- import { uploadImage } from "@/api";
- import { message, notification } from "ant-design-vue";
- import { LoadingOutlined, CheckOutlined } from "@ant-design/icons-vue";
- const UploadVideo = defineComponent({
- components: {},
- props: ["searchForm"],
- setup() {
- const formRef = ref();
- const state = reactive({
- fileList: ref<any[]>([]),
- });
- return { ...toRefs(state) };
- },
- mounted() {},
- methods: {
- // 选择视频后
- addFile(event: any) {
- event.target.files.forEach((item: any) => {
- this.getImgInfo(item).then((imgInfo: any) => {
- let { width, height } = imgInfo;
- // 校验文件尺寸大小比例
- // if (
- // height / width !== 16 / 9 &&
- // height / width !== 9 / 16 &&
- // height / width !== 1.52 &&
- // width / height !== 1.52
- // )
- // return message.warning(
- // `图片:${item.name} 宽高比例不符合要求比例,请修改后重新上传`
- // );
- // 校验文件是否已存在于fileList
- let flag = true;
- if (this.fileList.length > 0) {
- this.fileList.forEach((itm) => {
- if (itm.name === item.name) flag = false;
- });
- }
- if (!flag) return message.warning("文件已存在");
- if (this.fileList.length === 20)
- return message.warning("图片数量不能超过20");
- if (height > 1368 || width > 1368)
- return message.warning(
- `图片:${item.name} 尺寸不符合要求尺寸,请修改后重新上传`
- );
- // 正则 /^[\u4E00-\u9FA5A-Za-z0-9]+(-|\/)[\u4E00-\u9FA5A-Za-z0-9]+(-|\/)[\u4E00-\u9FA5A-Za-z0-9]+$/ XX-XX-XX
- if (
- this.checkNumber(item.name) !== 2 &&
- this.checkNumber(item.name) !== 3
- )
- return message.warning(
- `图片:${item.name} 不符合命名要求,请修改后重新上传`
- );
- this.fileList.push({
- file: item,
- name: item.name,
- percent: 0,
- materialSize: (item.size / 1024 / 1024).toFixed(2) + "MB",
- type: item.type.split("/")[0],
- width: width,
- height: height,
- });
- });
- });
- let inputFile: any = this.$refs.chooseFile;
- inputFile.value = "";
- console.log("新增文件列表", this.fileList);
- },
- // 确定上传图片
- async onUploadImage() {
- if (this.fileList.length === 0) return message.warning("请选择图片");
- this.$emit("close");
- // message.info("素材上传中...");
- const key = "start";
- notification.open({
- key,
- message: "状态提示",
- description: "素材上传中...",
- duration: 2,
- icon: h(LoadingOutlined, { style: "color: #108ee9" }),
- });
- let num = 0;
- if (this.fileList.length === 0) return message.error("请选择图片");
- this.fileList.forEach((item) => {
- let form: any = new FormData();
- form.append("is_public", this.$props.searchForm.is_public);
- form.append("image", item.file); //,item.name
- uploadImage(form)
- .catch((err) => {
- console.log("ERR", err);
- })
- .finally(() => {
- num++;
- console.log("NUM", num);
- if (num === this.fileList.length) {
- const key2 = "final";
- notification.open({
- key2,
- message: "状态提示",
- description: "素材上传完成!",
- duration: 2,
- icon: h(CheckOutlined, { style: "color: greenyellow" }),
- });
- }
- this.$emit("getList");
- });
- });
- },
- // 获取图片宽高信息
- getImgInfo(file: any) {
- return new Promise((resolve, reject) => {
- let reader = new FileReader();
- reader.readAsDataURL(file); // 必须用file.raw
- reader.onload = () => {
- // 让页面中的img标签的src指向读取的路径
- let img: any = new Image();
- img.src = reader.result;
- img.onload = () => {
- resolve({
- width: img.width,
- height: img.height,
- });
- };
- };
- });
- },
- // 删除item
- deleteItem(index: number) {
- this.fileList.splice(index, 1);
- },
- // 工具函数 返回-出现在字符串中的次数
- checkNumber(str: string) {
- let num = 0;
- str.split("").forEach((item: any) => {
- if (item === "-") {
- num++;
- }
- });
- return num;
- },
- clearList() {
- this.fileList = [];
- },
- },
- });
- export default UploadVideo;
- </script>
- <style lang="scss" scoped>
- @import "@/assets/common-style/frame.scss";
- .upload-video {
- width: 100%;
- padding: 0 10%;
- .gray-font {
- color: gray;
- }
- .upload-box {
- cursor: pointer;
- background: rgb(250, 250, 250);
- border: 2px dashed #39a4ff;
- border-radius: 6px;
- transition: all 0.3s;
- padding-bottom: 10px;
- position: relative;
- i {
- color: rgb(168, 167, 167);
- display: block;
- font-size: 60px;
- }
- i,
- p {
- text-align: center;
- transition: all 0.3s;
- color: #39a4ff;
- }
- // 选择文件
- .upload-input {
- position: absolute;
- display: block;
- width: 100%;
- height: 100%;
- opacity: 0;
- cursor: pointer;
- }
- }
- .upload-box:hover {
- i,
- p {
- color: #0829e6 !important;
- }
- border-color: #0829e6;
- }
- .upload-list {
- overflow: hidden;
- .list-item {
- margin-top: 10px;
- .icon-paper-clip {
- width: 14px;
- font-size: 12px;
- float: left;
- padding-top: 3px;
- }
- p {
- float: left;
- width: calc(100% - 14px);
- overflow: hidden;
- .icon-guanbi {
- display: block;
- float: right;
- font-size: 13px;
- cursor: pointer;
- &:hover {
- color: rgb(248, 10, 157);
- }
- }
- }
- }
- }
- .footer-num {
- position: relative;
- top: 56px;
- }
- }
- </style>
|