gy-app-shop/pages/fun/materialEdit.vue

641 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<view class="select-box" v-if="commitState === 'add'">
<view class="form-label">素材模板</view>
<view class="form-value" @click="openMaterialShow">
<view class="form-select">{{materialfrom.dictId?materialfrom.dictName:'请选择素材模板'}}</view>
<u-icon name="arrow-down-fill" color="#999" size="28"></u-icon>
</view>
</view>
<view class="form-item" v-if="commitState === 'back'">
<text class="form-label">修改意见</text>
<template>
<view class="comment-box">
{{ comment }}
</view>
</template>
</view>
<view class="form-item">
<text class="form-label">剧本 <text class="form-hint">视频的剧本</text> </text>
<!-- 文本输入 -->
<template>
<u-input style="max-height: 500rpx;overflow-y: auto;" :disabled="getDisabledStatus()" maxlength="9999" type='textarea' class="bg-gray" v-model="scriptContent" :placeholder="`请输入剧本`" />
</template>
<u-button @click="openAiDrama" type="primary" :disabled="getDisabledStatus()">Ai生成剧本</u-button>
</view>
<view v-for="(item,index) in materialTemplateList" :key="index" class="form-item">
<text class="form-label">{{ item.attrTitle }} <text class="form-hint">{{ item.attrHint ? '(' +item.attrHint + ')' : '' }}</text> </text>
<!-- 文本输入 -->
<template v-if="item.attrType === 0">
<u-input :disabled="getDisabledStatus()" class="bg-gray" v-model="item.attrValue" :placeholder="`请输入${item.attrTitle}`" />
</template>
<!-- 图片上传 -->
<template v-if="item.attrType === 1">
<view class="upload-area">
<view v-if="item.attrValue" class="preview-wrapper">
<image :src="item.fileUrl" mode="scaleToFill" class="preview-image" @click="previewImage(item.fileUrl)">
</image>
<u-icon v-if="!getDisabledStatus()" name="close" class="delete-icon" @click="deleteFile(item.attrValue,index)"></u-icon>
</view>
<u-button @click="chooseImage(item,index)" type="primary" :disabled="getDisabledStatus()"
:loading="item.uploading">{{ item.attrValue ? '重新上传' : '上传图片' }}</u-button>
</view>
</template>
<!-- 音频上传 -->
<template v-if="item.attrType === 2">
<view class="upload-area">
<view v-if="item.attrValue" class="audio-preview">
<text class="audio-name">{{ shortenFileName(item.fileName,20) || '已上传音频文件' }}</text>
<u-icon v-if="!getDisabledStatus()" name="close" class="delete-icon" @click="deleteFile(item.attrValue,index)"></u-icon>
</view>
<u-button @click="chooseAudio(item,index)" type="primary" :disabled="getDisabledStatus()"
:loading="item.uploading">{{ item.attrValue ? '重新上传' : '上传音频' }}</u-button>
<!-- <text v-if="item.fileUrl" class="audio-name">已上传音频文件</text> -->
<text class="upload-tip">{{'最大' + audioSize + 'MB'}}</text>
</view>
</template>
<!-- 视频上传 -->
<template v-if="item.attrType === 3">
<view class="upload-area">
<view v-if="item.attrValue" class="audio-preview">
<!-- <video :src="item.fileUrl" class="preview-video"></video> -->
<text class="audio-name">{{ shortenFileName(item.fileName,20) || '已上传音频文件' }}</text>
<u-icon v-if="!getDisabledStatus()" name="close" class="delete-icon" @click="deleteFile(item.attrValue,index)"></u-icon>
</view>
<u-button @click="chooseVideo(item,index)" type="primary" :disabled="getDisabledStatus()"
:loading="item.uploading">{{ item.attrValue ? '重新上传' : '上传视频' }}</u-button>
<text class="upload-tip">{{'最大' + videoSize + 'MB'}}</text>
</view>
</template>
<!-- 用户说明 -->
<u-input v-if="item.attrType !== 0" :disabled="getDisabledStatus()" type="textarea" class="bg-gray" v-model="item.userExplain" placeholder="请输入素材说明" />
<!-- 星级评分 -->
重要级别:<u-rate v-model="item.starLevel" :disabled="getDisabledStatus()" active-color="#f7ba2a" :count="5" />
</view>
<u-select v-model="materialShow" mode="single-column" :list="materialDictList" value-name="id" label-name="dictName" @confirm="changeTemplate"></u-select>
<!-- 提交按钮 -->
<view class="btn-box" v-if="commitState === 'add' || commitState === 'draft' || commitState === 'back'">
<u-button type="default" :loading="buttonLoading" class="bg-grey" @click="verifyForm('draft')">暂存</u-button>
<u-button type="primary" :loading="buttonLoading" @click="verifyForm('submit')">提交</u-button>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
import config from '../../common/api/config';
export default {
data() {
return {
token: '',
orderId: "",
productId: "",
orderItemId: "",
// 素材提交状态
commitState:'add',
comment:'',
materialfrom:{
id: undefined,
dictId: undefined,
dictName: undefined,
productId: undefined,
productSn: undefined,
flowId: undefined,
},
// 素材模板列表
materialDictList:[],
materialTemplateList:[],
// 模板选择弹窗
materialShow:false,
audioSize: 10,
videoSize: 50,
audioType: ['.wav', '.mp3', '.aac', '.flac', '.ogg'],
audioH5Type: ['wav', 'mp3', 'aac', 'flac', 'ogg'],
buttonLoading:false,
scriptContent:'',
// videoType: ['.avi', '.mp4', '.mkv', '.flv', '.mov', '.wmv', '.mpeg', '.3gp'],
}
},
onLoad(option) {
console.log("获取参数为",option)
this.orderId = option.orderId;
this.productId = option.productId;
this.orderItemId = option.orderItemId;
this.token = uni.getStorageSync('userToken');
this.getProductDetail();
},
methods: {
getAiDramaTxt(txt){
this.scriptContent = txt;
},
openAiDrama(){
uni.navigateTo({
url:'./AiDrama'
})
},
getDisabledStatus(){
if(this.commitState !== 'add' && this.commitState !== 'draft' && this.commitState !== 'back'){
return true;
}else{
return false;
}
},
openMaterialShow(){
this.materialShow = true;
},
async changeTemplate(e){
console.log("当前选择",e)
this.materialfrom.dictId = e[0].value;
this.materialfrom.dictName = e[0].label;
let res = await this.$api.orderApi.getProductMaterialDictItemList({ pageNum: 1, pageSize: 100, dictId: e[0].value, orderByColumn: 'orderNum', isAsc: 'asc' })
this.materialTemplateList = res.rows.map((item) => {
item.starLevel = 0;
item.userExplain = '';
item.attrValue = '';
item.orderId = this.orderId;
item.productId = this.productId;
item.orderItemId = this.orderItemId;
item.dictId = this.materialfrom.dictId;
item.id = null;
return item;
});
},
async getProductDetail(){
let res = await this.$api.orderApi.getOrderMaterialList({ orderItemId: this.orderItemId })
if(res.rows.length!=0){
this.materialfrom.flowId = res.rows[0].id;
this.commitState = res.rows[0].status;
this.comment = res.rows[0].comment || '';
this.scriptContent = res.rows[0].script || '';
this.materialTemplateList = res.rows[0].materialItems || [];
res.rows[0].materialItems.forEach(async (item,index)=>{
if(item.attrType !== 0 && item.attrValue !== ''){
let {fileUrl,fileName} = await this.getFileDetail(item.attrValue);
console.log("fileUrl,fileName",fileUrl,fileName)
this.$nextTick(()=>{
this.$set(this.materialTemplateList[index],'fileUrl',fileUrl)
this.$set(this.materialTemplateList[index],'fileName',fileName)
})
}
})
}else{
this.getMaterialDictList();
}
},
async getFileDetail(ossId){
let res = await this.$api.getOssDetail(ossId)
if(res.code == 200){
return {
fileUrl: res.data[0].url || '',
fileName:res.data[0].originalName || '',
}
}else{
return {
fileUrl:'',
fileName:'',
}
}
},
async getMaterialDictList(){
let res = await this.$api.orderApi.getProductMaterialDictList({ pageNum: 1, pageSize: 100, productId: this.productId })
this.materialDictList = res.rows || [];
},
async getMaterialList(){
let res = await this.$api.orderApi.getMallOrderProductMaterialList({ orderId: this.orderId, productId: this.productId, orderByColumn: 'orderNum', isAsc: 'asc' })
this.materialTemplateList = res.rows || [];
},
shortenFileName(fileName, maxLength = 10) {
if(fileName==undefined){
return '';
}
// 检查文件名是否已经足够短
if (fileName.length <= maxLength) {
return fileName;
}
// 获取文件后缀
const lastDotIndex = fileName.lastIndexOf('.');
const extension = fileName.slice(lastDotIndex); // 包括点号
// 获取文件名(不包括后缀)
const nameWithoutExtension = fileName.slice(0, lastDotIndex);
// 缩短文件名
const shortenedName = nameWithoutExtension.slice(0, maxLength);
// 返回缩短后的文件名,加上后缀
return `${shortenedName}...${extension}`;
},
chooseImage(item, index) {
this.materialTemplateList[index].uploading = true;
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0];
this.uploadFile(tempFilePath, 'image', item, index);
},
complete: () => {
this.materialTemplateList[index].uploading = false;
}
});
},
chooseVideo(item,index) {
this.materialTemplateList[index].uploading = true;
uni.chooseVideo({
count: 1,
maxDuration: 60,
success: (res) => {
const tempFilePath = res.tempFilePath;
const fileSize = res.size;
if (fileSize > this.videoSize * 1024 * 1024) {
uni.showToast({
title: '视频大小不能超过' + this.videoSize + 'MB',
icon: 'none'
});
this.materialTemplateList[index].uploading = false;
return;
}
this.uploadFile(tempFilePath, 'video', item, index);
},
fail: (err) => {
console.error('选择视频失败', err);
uni.showToast({
title: '选择视频失败',
icon: 'none'
});
},
complete: () => {
this.materialTemplateList[index].uploading = false;
}
});
},
chooseAudio(item,index) {
this.materialTemplateList[index].uploading = true;
// 注意H5不支持chooseFile需要单独处理
// #ifdef H5
uni.chooseFile({
count: 1,
type: 'all',
extension: this.audioType,
success: (res) => {
const tempFilePath = res.tempFiles[0].path;
const fileSize = res.tempFiles[0].size;
const fileName = res.tempFiles[0].name;
if (fileSize > this.audioSize * 1024 * 1024) {
uni.showToast({
title: '音频大小不能超过' + this.audioSize + 'MB',
icon: 'none'
});
this.materialTemplateList[index].uploading = false;
return;
}
this.uploadFile(tempFilePath, 'audio', item, index, fileName);
},
fail: (err) => {
console.error('选择音频失败', err);
uni.showToast({
title: '选择音频失败',
icon: 'none'
});
},
complete: () => {
this.materialTemplateList[index].uploading = false;
}
});
// #endif
// #ifndef H5
uni.chooseMessageFile({
count: 1,
type: 'file',
extension: this.audioH5Type,
success: (res) => {
const tempFilePath = res.tempFiles[0].path;
const fileSize = res.tempFiles[0].size;
const fileName = res.tempFiles[0].name;
if (fileSize > this.audioSize * 1024 * 1024) {
uni.showToast({
title: '音频大小不能超过' + this.audioSize + 'MB',
icon: 'none'
});
this.materialTemplateList[index].uploading = false;
return;
}
this.uploadFile(tempFilePath, 'audio', item, index, fileName);
},
fail: (err) => {
console.error('选择音频失败', err);
uni.showToast({
title: '选择音频失败',
icon: 'none'
});
},
complete: () => {
this.materialTemplateList[index].uploading = false;
}
});
// #endif
},
uploadFile(filePath, fileType, item, index, fileName = '') {
// 这里应该是您的实际上传接口
const uploadUrl = config.baseUrl + '/resource/oss/upload';
uni.uploadFile({
url: uploadUrl,
filePath: filePath,
name: 'file',
header: {
'Clientid': config.clientId,
'Authorization': 'Bearer ' + this.token
},
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data);
console.log("data", data)
// 假设服务器返回的是文件的URL
// this.materialTemplateList[index].fileUrl = data.url
this.materialTemplateList[index].attrValue = data.data.ossId;
this.materialTemplateList[index].fileUrl = data.data.url;
this.materialTemplateList[index].fileName = data.data.fileName;
uni.showToast({
title: '上传成功',
icon: 'success'
});
},
fail: (err) => {
console.error('上传失败', err);
uni.showToast({
title: '上传失败',
icon: 'none'
});
}
});
},
deleteFile(item,index) {
uni.showModal({
title: '确认删除',
content: '是否确认删除该文件?',
success: (res) => {
if (res.confirm) {
this.$api.orderApi.delOssFile(this.materialTemplateList[index].attrValue)
this.materialTemplateList[index].attrValue = '';
this.materialTemplateList[index].fileUrl = '';
this.materialTemplateList[index].fileName = '';
uni.showToast({
title: '删除成功',
icon: 'success'
});
}
}
});
},
previewImage(url) {
uni.previewImage({
urls: [url],
current: 0
});
},
verifyForm(status){
console.log('提交的表单数据:', this.materialTemplateList);
if(!this.materialfrom.dictId && this.commitState === 'add'){
this.$refs.uToast.show({
title: '请选择素材模板',
type: 'error',
})
return;
}
if(this.materialTemplateList.length==0){
this.$refs.uToast.show({
title: '请选择有素材项的模板',
type: 'error',
})
return;
}
let btnTitle = status==='draft' ?'暂存':'提交'
uni.showModal({
title: '操作确认',
content: '是否要'+ btnTitle +'素材?',
success: (res) => {
if (res.confirm) {
this.submitForm(status)
}
}
});
},
async submitForm(status) {
try {
this.buttonLoading = true;
// 这里添加实际的提交逻辑
let res = null;
if(this.commitState === 'add'){
res = await this.$api.orderApi.AddOrderMaterial({
orderId: this.orderId,
productId: this.productId,
orderItemId: this.orderItemId,
materialItems: this.materialTemplateList,
script: this.scriptContent
});
this.buttonLoading = false;
this.materialfrom.flowId = res.data.id;
this.getProductDetail();
}else{
res = await this.$api.orderApi.EditOrderMaterial({
orderId: this.orderId,
productId: this.productId,
orderItemId: this.orderItemId,
materialItems: this.materialTemplateList,
script: this.scriptContent,
id: this.materialfrom.flowId
});
this.buttonLoading = false;
}
if (status === 'draft') {
if (res.code === 200) {
this.$refs.uToast.show({
title: '暂存成功',
type: 'success',
})
}
uni.navigateBack({
delta: 1
})
} else {
this.buttonLoading = true;
// 提交,调用完成接口
let res1 = await this.$api.orderApi.mallMaterialCommit(this.orderItemId);
if (res1.code === 200) {
this.$refs.uToast.show({
title: '提交成功',
type: 'success',
})
}
this.buttonLoading = false;
uni.navigateBack({
delta: 1
})
}
} finally {
this.buttonLoading = false;
}
}
}
}
</script>
<style>
page{
background: #f5f5f5;
}
</style>
<style lang="scss">
.container {
padding: 20rpx;
padding-bottom: 120rpx;
}
.bg-gray{
background: #f8f8f8;
margin-bottom: 20rpx;
}
.select-box{
padding: 20rpx;
background: #fff;
border-radius: 20rpx;
margin-bottom: 20rpx;
.form-value{
padding: 10rpx;
border: 1px solid #c6c6c6;
border-radius: 10rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
}
.comment-box{
background-color: rgb(254,242,242);
border: 1px solid rgb(254,226,226);
border-radius: 0.5rem;
padding: 1rem;
width: 100%;
color: red;
font-size: 36rpx;
}
.form-item {
margin-bottom: 20rpx;
padding: 20rpx;
background: #fff;
border-radius: 20rpx;
}
.form-label {
display: block;
margin-bottom: 10rpx;
font-weight: bold;
.form-hint{
font-size: 20rpx;
color: #999;
margin-left: 6rpx;
}
}
.upload-area {
// display: flex;
// flex-direction: column;
// align-items: flex-start;
margin-bottom: 10rpx;
}
.preview-wrapper {
margin: 0 auto;
position: relative;
width: 200rpx;
height: 200rpx;
background-color: #eeeeee;
margin-bottom: 10rpx;
.preview-image{
width: 100%;
height: 100%;
}
.delete-icon {
position: absolute;
top: -10rpx;
right: -10rpx;
background-color: #fa3534;
color: #fff;
font-size: 20rpx;
border-radius: 50%;
padding: 10rpx;
}
}
.preview-video {
width: 200rpx;
height: 200rpx;
margin-bottom: 10rpx;
}
.audio-preview {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
position: relative;
border: 1px solid #999;
border-radius: 10rpx;
padding: 5rpx 10rpx;
.audio-name {
margin-right: 10rpx;
font-size: 24rpx;
color: #888;
}
.delete-icon {
color: #888;
font-size: 28rpx;
padding: 10rpx;
}
}
.upload-tip {
margin-top: 5rpx;
font-size: 24rpx;
color: #999;
}
.btn-box{
display: flex;
justify-content: space-around;
align-items: center;
height: 120rpx;
position: fixed;
left: 0;
right: 0;
bottom: 0;
background: #fff;
z-index: 999;
button{
width: 340rpx;
height: 85rpx;
border-radius: 10rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>