inleft
2024-05-18 57e3bead08715d72efaeffe90fafa179b8366473
commit | author | age
f5539f 1 <template>
1ad93b 2     <div>
fa1bd9 3         <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
I 4             <img alt="example" style="width: 100%" :src="previewImage" />
5         </a-modal>
1ad93b 6         <a-form-model ref="myForm" :model="form" :label-col="labelCol" :wrapper-col="wrapperCol" :rules="rules">
6bcd13 7             <a-form-model-item label="认证" prop="secret">
I 8                 <a-input v-model="form.secret" autocomplete='new-password' type="password" placeholder="口令">
9                     <a-icon slot="prefix" type="lock" style="color:rgba(0,0,0,.25)" />
10                 </a-input>
11             </a-form-model-item>
12
1ad93b 13             <a-form-model-item label="标题" prop="title">
f5539f 14                 <a-input v-model="form.title" placeholder="限 50字内" />
L 15             </a-form-model-item>
16
06ee76 17             <a-form-model-item label="模式切换" prop="common">
f5539f 18                 <a-switch v-model="form.online" />
4b854c 19                 <span class="myTip" v-if="form.online">
I 20                     由系统生成文件
21                 </span>
22                 <span class="myTip" v-else>
23                     本地文件上传
f5539f 24                 </span>
L 25             </a-form-model-item>
26
6bcd13 27             <a-form-model-item label="日志文件" v-show="!form.online">
af029b 28                 <a-upload ref="blogFileUpload" :customRequest="customRequest" name="file" :showUploadList="true"
I 29                     @change="handleChange" :default-file-list="form.blogFileList" :beforeUpload="beforeUpload"
80476f 30                     :data="{'bucketName':bucketName.bucket_article}" accept=".md,.html,.htm,.txt">
6bcd13 31                     <a-button>
fa1bd9 32                         <a-icon type="upload" />限 md/html/txt
f5539f 33                     </a-button>
L 34                 </a-upload>
35             </a-form-model-item>
36
63f511 37             <a-form-model-item label="日志内容" v-show="form.online">
f5539f 38                 <a-input v-model="form.content" type="textarea" placeholder="限10k字数" />
L 39             </a-form-model-item>
40
1ad93b 41             <a-form-model-item label="分类" prop="class">
6bcd13 42                 <a-select v-model="form.class" :allowClear="true" mode="default" placeholder="日志分类"
f5539f 43                     :getPopupContainer="getCalendarContainer()">
6bcd13 44                     <a-select-option v-for="(item,index) in this.blogArticleType" :key="index" :value="item.id">
I 45                         {{ item.typeName }}
f5539f 46                     </a-select-option>
L 47                 </a-select>
48             </a-form-model-item>
49
1ad93b 50             <a-form-model-item label="额外设置">
f5539f 51                 <a-switch v-model="form.preference" />
L 52             </a-form-model-item>
53
54             <div v-show="form.preference" class="myBorder" style="padding:10px;">
1ad93b 55                 <a-form-model-item label="起个草稿">
f5539f 56                     <a-switch v-model="form.tempSave" />
L 57                     <span v-show="form.tempSave" class="myTip">
1ad93b 58                         临时存储,游客无法浏览
f5539f 59                     </span>
L 60                 </a-form-model-item>
61
fa1bd9 62                 <a-form-model-item label=" 主类型">
00e46d 63                     <a-select v-model="form.blogType" mode="default" placeholder=""
I 64                         :getPopupContainer="getCalendarContainer()">
105729 65                         <a-select-option value="1">
1ad93b 66                             markdown
00e46d 67                         </a-select-option>
105729 68                         <a-select-option value="2">
1ad93b 69                             html
00e46d 70                         </a-select-option>
105729 71                         <a-select-option value="3">
c6793e 72                             视频
I 73                         </a-select-option>
a23166 74                         <a-select-option value="4">
c6793e 75                             音频
105729 76                         </a-select-option>
I 77                         <a-select-option value="5">
c6793e 78                             图组
I 79                         </a-select-option>
80                         <a-select-option value="9">
81                             taking
00e46d 82                         </a-select-option>
I 83                     </a-select>
f5539f 84                 </a-form-model-item>
L 85
fa1bd9 86                 <a-form-model-item label="引言" prop="introduce">
I 87                     <a-input v-model="form.introduce" type="textarea" placeholder="限700字数" />
88                 </a-form-model-item>
89                 
90                 <a-form-model-item label="封面">
91                     <a-upload :customRequest="customRequest" name="file" :showUploadList="true" list-type="picture"
92                         :data="{'bucketName':bucketName.bucket_cover}" @change="handleChangeCoverFile"
93                         :default-file-list="form.coverFileList" :beforeUpload="beforeUploadCover"
94                         accept=".jpg,.png,.jpeg" @preview="handlePreview">
95                         <!-- :disabled="form.coverFileList.length>=1" -->
96                         <a-button>
97                             <a-icon type="upload" />jpg/png/jpeg..
98                         </a-button>
99                     </a-upload>
100                     <!-- <span class="myTip">
101                         自动转码,可以传高清图
102                     </span> -->
103                 </a-form-model-item>
f5539f 104
fa1bd9 105                 <a-form-model-item label="图组">
I 106                     <a-upload :customRequest="customRequest" name="file" :showUploadList="true" list-type="picture-card"
107                         :data="{'bucketName':bucketName.bucket_picture}" @change="handleChangePictureFile"
108                         :default-file-list="form.pictureList" :beforeUpload="beforeUploadPicture"
109                         accept=".jpg,.png,.jpeg" :multiple="true" @preview="handlePreview">
110                         <a-button>
111                             <a-icon type="upload" />jpg/png/jpeg..
112                         </a-button>
113                     </a-upload>
114                 </a-form-model-item>
115
116                 <a-form-model-item label="视频组">
117                     <a-upload :customRequest="customRequest" name="file" :showUploadList="true" list-type="text"
118                         :data="{'bucketName':bucketName.bucket_video}" @change="handleChangeVideoFile"
119                         :default-file-list="form.videoList" :beforeUpload="beforeUploadVideo" :multiple="true"
120                         accept=".mp4">
121                         <a-button>
122                             <a-icon type="upload" />mp4
123                         </a-button>
124                     </a-upload>
125                 </a-form-model-item>
126
127                 <a-form-model-item label="定时">
128                     <a-date-picker v-model="momentDate" show-time type="datetime" placeholder="发布时间"
731926 129                         style="width: 100%;"  @change="formatDate"
I 130                         :getCalendarContainer="getCalendarContainer()" /><!-- :disabledDate="disabledDate" -->
fa1bd9 131                 </a-form-model-item>
I 132                 
f5539f 133                 <a-form-model-item label="标签">
L 134                     <template v-for="(tag, index) in tags">
135                         <a-tooltip v-if="tag.length > 20" :key="tag" :title="tag">
136                             <a-tag :key="tag" :closable="index !== 0" @close="() => handleClose(tag)">
137                                 {{ `${tag.slice(0, 20)}...` }}
138                             </a-tag>
139                         </a-tooltip>
1ad93b 140                         <a-tag v-else :key="tag" :closable="index >= 0" @close="() => handleClose(tag)">
f5539f 141                             {{ tag }}
L 142                         </a-tag>
143                     </template>
fa1bd9 144                 
f5539f 145                     <a-input v-if="inputVisible" ref="input" type="text" size="small" :style="{ width: '78px' }"
L 146                         :value="inputValue" @change="handleInputChange" @blur="handleInputConfirm"
147                         @keyup.enter="handleInputConfirm" />
fa1bd9 148                 
f5539f 149                     <a-tag v-else style="background: #fff; borderStyle: dashed;" @click="showInput">
L 150                         <a-icon type="plus" /> New Tag
151                     </a-tag>
06ee76 152                 </a-form-model-item>
L 153
7b98c8 154                 <div v-bind:class="{'myBorder':form.top}" style="padding: 3px;margin-bottom: 10px;">
6bcd13 155                     <a-form-model-item label="置顶">
I 156                         <a-switch v-model="form.top" />
157                     </a-form-model-item>
f5539f 158
6bcd13 159                     <div v-show="form.top">
I 160                         <a-form-model-item label="权重">
7b98c8 161                             <a-slider v-model="form.sliderValue" :default-value="50" :step="5"
6bcd13 162                                 :getTooltipPopupContainer="getCalendarContainer()" />
I 163                             <span class="myTip">
164                                 越小越靠前
165                             </span>
166                         </a-form-model-item>
167                     </div>
168                 </div>
f5539f 169
L 170
1ad93b 171                 <div v-bind:class="{'myBorder':form.lock}" style="padding: 3px;">
f5539f 172
L 173                     <a-form-model-item label="加锁">
174                         <a-switch v-model="form.lock" />
175                         <span v-show="!form.lock" class="myTip">
176                             默认为公开
177                         </span>
178                     </a-form-model-item>
179
180                     <div v-show="form.lock ">
181                         <a-form-model-item label="阅读权限">
182                             <a-radio-group v-model="form.auth">
c23efb 183                                 <a-radio value="2">
f5539f 184                                     私人
L 185                                 </a-radio>
c23efb 186                                 <a-radio value="3">
f5539f 187                                     密码授权
L 188                                 </a-radio>
189                             </a-radio-group>
190                         </a-form-model-item>
191
fc0c10 192                         <a-form-model-item label="授权密码" v-show="form.auth==3">
7b98c8 193                             <a-input-password v-model="form.password" autocomplete='new-password' type="password"
6bcd13 194                                 placeholder="独立密码">
f5539f 195                                 <a-icon slot="prefix" type="lock" style="color:rgba(0,0,0,.25)" />
7b98c8 196                             </a-input-password>
f5539f 197                         </a-form-model-item>
L 198                     </div>
199
200                 </div>
201
202             </div>
203
204         </a-form-model>
205     </div>
206 </template>
207
208 <script>
209     import moment from "moment";
6bcd13 210     import {
105729 211         sysFileInfoUpload,
I 212         myFileInfoUpload
6bcd13 213     } from '../../api/fileManage.js';
63f511 214
6bcd13 215     import {
I 216         queryBlogArticleType
217     } from '../../api/blogArticleType.js'
63f511 218
105729 219     import myConstant from "../../config/myConstant.js"
0dd41b 220     import md5 from 'js-md5';
63f511 221
fa1bd9 222     function getBase64(file) {
I 223         return new Promise((resolve, reject) => {
224             const reader = new FileReader();
225             reader.readAsDataURL(file);
226             reader.onload = () => resolve(reader.result);
227             reader.onerror = error => reject(error);
228         });
229     }
230
f5539f 231     export default {
6bcd13 232         beforeMount() {
I 233             queryBlogArticleType({}).then((res) => {
234                 this.blogArticleType = res.data;
235             })
236         },
f5539f 237         data() {
af029b 238             let _this = this;
06ee76 239             let validateContent = (rule, value, callback) => {
af029b 240                 if (_this.form.online) {
I 241                     //this.$refs.myForm.validateField('content')
242                     if (_this.form.content == null || _this.form.content == "") {
63f511 243                         callback(new Error('内容未填'));
I 244                     }
06ee76 245                 } else {
af029b 246                     //this.$refs.myForm.validateField('blogFileList')
I 247                     if (_this.form.fileId == null) {
63f511 248                         callback(new Error('文件未传'));
I 249                     }
06ee76 250                 }
L 251                 callback();
252             };
253
f5539f 254             return {
fa1bd9 255                 previewVisible: false,
I 256                 previewImage: '',
80476f 257                 bucketName: myConstant.bucketName,
fa1bd9 258                 momentDate: undefined,
6bcd13 259                 blogArticleType: [],
f5539f 260                 tags: [],
L 261                 inputVisible: false,
262                 inputValue: '',
263                 labelCol: {
1ad93b 264                     span: 7
f5539f 265                 },
L 266                 wrapperCol: {
1ad93b 267                     span: 13
f5539f 268                 },
L 269                 form: {
fa1bd9 270                     introduce: '',
6bcd13 271                     secret: '',
f5539f 272                     title: '',
L 273                     content: '',
274                     class: [],
275                     tempSave: false,
c23efb 276                     blogType: "1",
f5539f 277                     publishDate: "",
L 278                     lock: false,
6bcd13 279                     top: false,
105729 280                     sliderValue: 50,
c23efb 281                     auth: 1,
f5539f 282                     password: "",
c23efb 283                     fileId: null,
I 284                     coverFile: null,
fa1bd9 285                     pictureIds: null,
I 286                     videoIds: null,
f5539f 287                     blogFileList: [],
1ad93b 288                     coverFileList: [],
fa1bd9 289                     pictureList: [],
I 290                     videoList: [],
291                     online: false,
292                     preference: false,
f5539f 293                 },
1ad93b 294                 rules: {
I 295                     title: [{
296                             required: true,
297                             message: '标题不能为空',
298                             trigger: 'blur'
299                         },
300                         {
63f511 301                             min: 1,
1ad93b 302                             max: 50,
I 303                             message: '字数限制1~50',
304                             trigger: 'blur'
305                         },
306                     ],
fa1bd9 307                     introduce: [{
731926 308                         max: 700,
fa1bd9 309                         message: '字数限制700',
I 310                         trigger: 'blur'
311                     }, ],
6bcd13 312                     secret: [{
I 313                         required: true,
0dd41b 314                         message: '好像这里错了..',
6bcd13 315                         trigger: 'blur'
I 316                     }],
06ee76 317                     common: [{
L 318                         validator: validateContent,
319                         trigger: []
320                     }],
63f511 321                     // content: [{
I 322                     //     max: 10,
323                     //     required: true,
324                     //     message: '至少填一下上传内容',
325                     //     trigger: 'blur'
326                     // }, ],
327                     // blogFileList: [{
328                     //     max: 1,
329                     //     required: true,
330                     //     message: '文件未上传',
331                     // }],
1ad93b 332                     class: [{
I 333                         required: true,
334                         message: '至少选一个分类',
335                         trigger: 'blur'
336                     }, ],
63f511 337
1ad93b 338                 }
f5539f 339             };
L 340         },
341         methods: {
fa1bd9 342             handleCancel() {
I 343                 this.previewVisible = false;
344             },
345             async handlePreview(file) {
346                 if (!file.url && !file.preview) {
347                     file.preview = await getBase64(file.originFileObj);
348                 }
349                 this.previewImage = file.url || file.preview;
350                 this.previewVisible = true;
351             },
af029b 352             reset() {
I 353                 // this.form.blogFileList = [];
354                 // this.form.coverFileList = [];
fa1bd9 355             },
I 356             formatDate(date, dateString) {
357                 this.form.publishDate = dateString;
358             },
359             beforeUploadVideo(file, fileList) {
360                 return new Promise((resolve, reject) => {
361                     if (this.form.secret == null || this.form.secret == "") {
362                         this.$message.error('需要正确的授权码');
363                         return reject(false);
364                     }
365
366                     if (this.form.coverFileList.length > 10) {
367                         this.$message.error('这里最多上传10个文件');
368                         return reject(false);
369                     }
370                     if (file.size > myConstant.uploadVideoSizeLimit) {
371                         this.$message.error('上传文件大小不能超过 200M!');
372                         return reject(false);
373                     }
374                     return resolve(true)
375                 });
376             },
377             beforeUploadPicture(file, fileList) {
378                 return new Promise((resolve, reject) => {
379                     if (this.form.secret == null || this.form.secret == "") {
380                         this.$message.error('需要正确的授权码');
381                         return reject(false);
382                     }
383
384                     if (this.form.coverFileList.length > 10) {
385                         this.$message.error('这里最多上传10个文件');
386                         return reject(false);
387                     }
388                     if (file.size > myConstant.uploadFileSizeLimit) {
389                         this.$message.error('上传文件大小不能超过 2M!');
390                         return reject(false);
391                     }
392                     return resolve(true)
393                 });
105729 394             },
af029b 395             beforeUploadCover(file, fileList) {
6bcd13 396                 return new Promise((resolve, reject) => {
0dd41b 397                     if (this.form.secret == null || this.form.secret == "") {
I 398                         this.$message.error('需要正确的授权码');
399                         return reject(false);
400                     }
401
af029b 402                     if (this.form.coverFileList.length >= 1) {
6bcd13 403                         this.$message.error('这里最多上传一个文件');
I 404                         return reject(false);
405                     }
af029b 406                     if (file.size > myConstant.uploadFileSizeLimit) {
I 407                         this.$message.error('上传文件大小不能超过 2M!');
408                         return reject(false);
409                     }
410                     return resolve(true)
411                 });
412             },
413             beforeUpload(file, fileList) {
414                 return new Promise((resolve, reject) => {
0dd41b 415                     if (this.form.secret == null || this.form.secret == "") {
I 416                         this.$message.error('需要正确的口令..');
417                         return reject(false);
418                     }
419
af029b 420                     if (this.form.blogFileList.length >= 1) {
I 421                         this.$message.error('这里最多上传一个文件');
422                         return reject(false);
423                     }
63f511 424
af029b 425                     if (file.size > myConstant.uploadFileSizeLimit) {
63f511 426                         this.$message.error('上传文件大小不能超过 2M!');
I 427                         return reject(false);
428                     }
429                     return resolve(true)
430                 });
431
6bcd13 432             },
I 433             handleChange(info) {
af029b 434                 this.form.blogFileList = info.fileList;
I 435
6bcd13 436                 if (info.file.status !== 'uploading') {
I 437                     console.log(info.file, info.fileList);
438                 }
439                 if (info.file.status === 'done') {
c23efb 440                     this.form.fileId = info.file.response.data;
fa1bd9 441                     this.$message.success(`${info.file.name} 上传成功`);
c23efb 442                 } else if (info.file.status === 'error') {
fa1bd9 443                     this.$message.error(`${info.file.name} 上传失败`);
c23efb 444                 }
af029b 445
I 446                 if (this.form.blogFileList == null || this.form.blogFileList.length == 0) {
447                     this.form.fileId = null
448                 }
c23efb 449             },
I 450             handleChangeCoverFile(info) {
af029b 451                 this.form.coverFileList = info.fileList;
I 452
c23efb 453                 if (info.file.status !== 'uploading') {
I 454                     console.log(info.file, info.fileList);
455                 }
456                 if (info.file.status === 'done') {
457                     this.form.coverFile = info.file.response.data;
fa1bd9 458                     this.$message.success(`${info.file.name} 上传成功`);
6bcd13 459                 } else if (info.file.status === 'error') {
fa1bd9 460                     this.$message.error(`${info.file.name} 上传失败`);
af029b 461                 }
I 462
463                 if (this.form.coverFileList == null || this.form.coverFileList.length == 0) {
464                     this.form.coverFile = null
fa1bd9 465                 }
I 466             },
467             handleChangePictureFile(info) {
468                 this.form.pictureList = info.fileList;
469
470                 if (info.file.status !== 'uploading') {
471                     console.log(info.file, info.fileList);
472                 }
473                 if (info.file.status === 'done') {
474                     if (this.form.pictureIds == null || this.form.pictureIds == "") {
475                         this.form.pictureIds = info.file.response.data;
476                     } else {
477                         this.form.pictureIds = this.form.pictureIds + "," + info.file.response.data;
478                     }
479                     this.$message.success(`${info.file.name} 上传成功`);
480                 } else if (info.file.status === 'error') {
481                     this.$message.error(`${info.file.name} 上传失败`);
482                 }
483
484                 if (this.form.pictureList == null || this.form.pictureList.length == 0) {
485                     this.form.pictureIds = null
486                 }
487             },
488             handleChangeVideoFile(info) {
489                 this.form.videoList = info.fileList;
490
491                 if (info.file.status !== 'uploading') {
492                     console.log(info.file, info.fileList);
493                 }
494                 if (info.file.status === 'done') {
495                     if (this.form.videoIds == null || this.form.videoIds == "") {
496                         this.form.videoIds = info.file.response.data;
497                     } else {
498                         this.form.videoIds = this.form.videoIds + "," + info.file.response.data
499                     }
500                     this.$message.success(`${info.file.name} 上传成功`);
501                 } else if (info.file.status === 'error') {
502                     this.$message.error(`${info.file.name} 上传失败`);
503                 }
504
505                 if (this.form.videoList == null || this.form.videoList.length == 0) {
506                     this.form.videoIds = null
6bcd13 507                 }
I 508             },
509             /**
510              * 上传文件
511              */
512             customRequest(option) {
513                 const formData = new FormData()
514                 formData.append('file', option.file)
80476f 515                 formData.append('bucketName', option.data.bucketName)
0dd41b 516                 formData.append('authCode', this.form.secret == "" ? "" : md5(this.form.secret))
fa1bd9 517                 let _this = this
105729 518                 myFileInfoUpload(formData).then((res) => {
6bcd13 519                     if (res.success) {
I 520                         option.onSuccess(res, option.file)
87317f 521                         // 在上传成功后进度条显示为99
I 522                         progress.percent = 100
fa1bd9 523                         // this.$message.success('上传成功')
6bcd13 524                     } else {
I 525                         this.$message.error('上传失败:' + res.message)
526                     }
527                 })
87317f 528
I 529                 let progress = {
530                     percent: 1
531                 }
532                 let speed = 100 / (option.file.size / 65000) //上传速度
533                 const intervalId = setInterval(() => {
534                     // 控制进度条防止在未上传成功时进度条达到100
535                     if (progress.percent < 99 && progress.percent + speed < 100) {
536                         progress.percent += speed //控制进度条速度
537                         option.onProgress(progress) //onProgress接收一个对象{ percent: 进度 }在进度条上显示
538                     } else if ((progress.percent < 100)) {
539                         progress.percent++
540                     } else if (progress.percent >= 100) {
541                         clearInterval(intervalId)
542                     }
543                 }, 500)
544
6bcd13 545             },
f5539f 546             disabledDate(current) {
L 547                 return current < moment().subtract(1, "day");
548             },
549             getCalendarContainer(trigger) {
550                 return trigger => trigger.parentNode;
551             },
552             handleClose(removedTag) {
af029b 553                 // const tags = this.tags.filter(tag => tag !== removedTag);
1ad93b 554                 //console.log(tags);
af029b 555                 this.tags = this.tags.filter(tag => tag !== removedTag);
f5539f 556             },
L 557             showInput() {
558                 this.inputVisible = true;
559                 this.$nextTick(function() {
560                     this.$refs.input.focus();
561                 });
562             },
563             handleInputChange(e) {
564                 this.inputValue = e.target.value;
565             },
566             handleInputConfirm() {
567                 const inputValue = this.inputValue;
568                 let tags = this.tags;
569                 if (inputValue && tags.indexOf(inputValue) === -1) {
570                     tags = [...tags, inputValue];
571                 }
1ad93b 572                 //console.log(tags);
f5539f 573                 Object.assign(this, {
L 574                     tags,
575                     inputVisible: false,
576                     inputValue: '',
577                 });
578             },
1ad93b 579
f5539f 580         },
L 581     };
582 </script>
583
584 <style lang="less">
1ad93b 585     @media screen and(max-width: 575px) {
I 586         .ant-form-item-label {
587             padding: 8px !important;
588         }
589     }
590
f5539f 591     .myTip {
L 592         font-size: 10px;
593         color: #999;
594     }
595
596     .myBorder {
597         border: 1px solid #999;
1ad93b 598         border-radius: 10px;
f5539f 599     }
L 600
601     .ant-upload-list-item-info {
602         a {
603             color: #999;
604         }
605     }
606
607     /* tile uploaded pictures */
608     .upload-list-inline>.ant-upload-list-item {
609         float: left;
610         width: 100px;
611         margin-right: 8px;
612     }
613
614     .upload-list-inline>.ant-upload-animate-enter {
615         animation-name: uploadAnimateInlineIn;
616     }
617
618     .upload-list-inline>.ant-upload-animate-leave {
619         animation-name: uploadAnimateInlineOut;
620     }
621 </style>