合并上线1030

This commit is contained in:
Bella
2023-10-31 14:01:28 +08:00
27 changed files with 1003 additions and 671 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -3510,9 +3510,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1697433388124') format('woff2'),
url('iconfont.woff?t=1697433388124') format('woff'),
url('iconfont.ttf?t=1697433388124') format('truetype');
src: url('iconfont.woff2?t=1698731786246') format('woff2'),
url('iconfont.woff?t=1698731786246') format('woff'),
url('iconfont.ttf?t=1698731786246') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>

View File

@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3121635 */
src: url('iconfont.woff2?t=1697433388124') format('woff2'),
url('iconfont.woff?t=1697433388124') format('woff'),
url('iconfont.ttf?t=1697433388124') format('truetype');
src: url('iconfont.woff2?t=1698731786246') format('woff2'),
url('iconfont.woff?t=1698731786246') format('woff'),
url('iconfont.ttf?t=1698731786246') format('truetype');
}
.iconfont {

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -186,15 +186,13 @@ const constantRoutes = [
{
path: 'data-particulars',
name: 'DataParticulars',
meta: { keepAlive: true },
meta: { showPublish: false, showPreview: false, showShare: true, showDownload: true },
meta: { keepAlive: true, showPublish: false, showPreview: false, showShare: true, showDownload: true },
component: () => import(/* webpackChunkName: "analyse" */ '@/views/DataAnalyse/particulars/list')
},
{
path: 'test-particulars',
name: 'TestParticulars',
meta: { keepAlive: true },
meta: { showPublish: false, showPreview: false, showShare: true, showDownload: true },
meta: { keepAlive: true, showPublish: false, showPreview: false, showShare: true, showDownload: true },
component: () => import(/* webpackChunkName: "analyse" */ '@/views/DataAnalyse/particulars/test')
},
{

View File

@@ -22,13 +22,13 @@
<img src="@/assets/img/answer/actions/suspend.png"/>
<LangTranslate translate-key="FeedbackNotice" class="msg"/>
</div>
<div v-else-if="[20006,20017,20018, 20007, 20008, 20009].includes(questionsData.action?.code)" class="action">
<img src="@/assets/img/answer/actions/yitijiao.png"/>
<LangTranslate v-if="[20017].includes(questionsData.action?.code)" translate-key="EquipmentNotice" class="msg"></LangTranslate>
<LangTranslate v-else-if="[20018].includes(questionsData.action?.code)" translate-key="SubmitIpNotice" class="msg"></LangTranslate>
<LangTranslate v-else class="msg" translate-key="SubmittedNotice"></LangTranslate>
</div>
<!-- 提前终止和正常完成 -->
<div v-else-if="[20004, 20011, 20016].includes(questionsData.action?.code)" class="action">

View File

@@ -1,271 +1,300 @@
<template>
<div class="ui">
<div class="all">
<div class="top">
<Toolbar @back="back" @save="save" :title="title" />
</div>
<div class="yo-container">
<div class="left">
<TabListCommodity @clickThumb="clickThumbCommodity" @add="addCommodity" @remove="removeCommodity" />
</div>
<div class="yo-main">
<SceneSeparateTexturePreviewer ref="ss" :selCommodity="selCommodity" :selTexture="selTexture" @onLoadingCompletion="onLoadingCompletion" />
</div>
<div class="right">
<TabListCommodityRelTexture :relCommodity="selCommodity" :selTexture="selTexture" @clickThumb="clickThumbTexture"
@add="addTexture" @remove="removeTexture" />
</div>
</div>
</div>
</div>
<!-- <CommodityUploader :isOpen="isOpenCommodityUploader" @close="closeCommodityUploader"
@success="commodityAddSuccess" />
<TextureUploader :isOpen="isOpenTextureUploader" @close="closeTextureUploader" @success="textureAddSuccess"
:relCommodityId="selCommodity ? selCommodity.id : null" /> -->
</template>
<script setup>
// https://2x.antdv.com/docs/vue/getting-started
// https://share.lanhuapp.com/#/invite?sid=lXPuKlJa
import Toolbar from '../../shelves-vue/components/editor/Toolbar.vue'
import TabListCommodity from '../../shelves-vue/components/editor/TabListCommodity.vue'
import TabListCommodityRelTexture from '../../shelves-vue/components/editor/TabListCommodityRelTexture.vue'
// import CommodityUploader from '../../shelves-vue/view/CommodityUploader.vue'
// import TextureUploader from '../../shelves-vue/view/TextureUploader.vue'
import SceneSeparateTexturePreviewer from '../../shelves-vue/components/SceneSeparateTexturePreviewer.vue'
</script>
<script>
import { updateMaterialCenter } from "../../../../api.js"
import common from "@/api/common.js";
import { message } from 'ant-design-vue'
export default {
props: {
currentModelData: {
type: Object,
default: () => (null)
},
title: {
type: String,
default: ""
},
},
data() {
return {
isOpenCommodityUploader: false,
isOpenTextureUploader: false,
selCommodity: null,
selTexture: null,
}
},
methods: {
onLoadingCompletion(){
if(!this.currentModelData) return;
var current = JSON.parse(JSON.stringify(this.currentModelData))
this.selCommodity = current.commodity
setTimeout(() => {
this.selTexture = current.texture
}, 100);
},
back() {
this.$router.go(-1)
},
async save(callback) {
try{
// create new ware
if(!this.selCommodity) {
message.warning("请选择商品模型");
callback();
return;
}
// if(!this.selTexture) {
// message.warning("请选择商品贴图");
// return;
// }
var clone = {
type: 1,
commodity: this.selCommodity,
texture: this.selTexture,
urlThumb: this.selCommodity.urlThumb,
}
console.log(clone)
const blob = await this.$refs.ss.previewer_.snapshot();
const res = await common.cosUpload3DCompress(blob);
await updateMaterialCenter({
id: this.$route.query.id,
data: JSON.stringify(clone),
simple_data: {},
version: new Date().getTime(),
cover: res.url
});
this.$router.go(-1);
}
catch(e){
console.log(e)
callback()
}
// this.$store.dispatch('wares/add', {
// type: 1,
// commodity: this.selCommodity,
// texture: this.selTexture,
// urlThumb: this.selCommodity.urlThumb,
// }).then(data2 => {
// })
},
//
addCommodity() {
this.isOpenCommodityUploader = true
},
clickThumbCommodity(itm) {
// console.log(itm)
this.selCommodity = itm
},
removeCommodity() {
this.selCommodity = null
},
//
//
addTexture() {
this.isOpenTextureUploader = true
},
clickThumbTexture(itm) {
this.selTexture = itm
},
removeTexture() {
this.selTexture = null
},
//
closeCommodityUploader() {
this.isOpenCommodityUploader = false
},
commodityAddSuccess(data) {
this.clickThumbCommodity(data)
},
closeTextureUploader() {
this.isOpenTextureUploader = false
},
textureAddSuccess(data) {
this.clickThumbTexture(data)
},
},
}
</script>
<style scoped>
div.ui {
position: fixed;
width: 100vw;
/* height: 100vh; */
}
.all {
height: 100vh;
/* background-color: beige; */
}
.yo-tabs {
position: absolute;
top: 90px;
left: 24px;
right: 24px;
bottom: 20px;
display: flex;
flex-direction: row;
flex: 1;
flex-basis: auto;
box-sizing: border-box;
min-width: 0;
border-radius: 6px;
background: transparent;
}
.yo-container {
position: absolute;
/* top: 135px; */
top: 90px;
left: 24px;
right: 24px;
bottom: 20px;
display: flex;
flex-direction: row;
flex: 1;
flex-basis: auto;
box-sizing: border-box;
min-width: 0;
/* margin: 21px 24px; */
border-radius: 0 6px 6px 6px;
background: #FFFFFF;
box-shadow: 0 10px 8px 0 rgba(0, 0, 0, 0.1);
}
.yo-main {
display: block;
flex: 1;
flex-basis: auto;
overflow: auto;
box-sizing: border-box;
padding: 0;
}
.top {
/* background-color: burlywood; */
height: auto;
padding: 0;
}
.left {
width: 280px;
background-color: #ffffff;
}
.main {
padding: 0px;
}
.right {
width: 280px;
background-color: #ffffff;
}
</style>
<template>
<div class="ui">
<div class="all">
<div class="top">
<Toolbar @back="back" @save="save" @downloadScreenshot="downloadScreenshot" :title="title" />
</div>
<div class="yo-container">
<div class="left">
<TabListCommodity @clickThumb="clickThumbCommodity" @add="addCommodity" @remove="removeCommodity" />
</div>
<div class="yo-main">
<SceneSeparateTexturePreviewer ref="ss" :selCommodity="selCommodity" :selTexture="selTexture" @onLoadingCompletion="onLoadingCompletion" />
</div>
<div class="right">
<TabListCommodityRelTexture :relCommodity="selCommodity" :selTexture="selTexture" @clickThumb="clickThumbTexture"
@add="addTexture" @remove="removeTexture" />
</div>
</div>
</div>
</div>
<!-- <CommodityUploader :isOpen="isOpenCommodityUploader" @close="closeCommodityUploader"
@success="commodityAddSuccess" />
<TextureUploader :isOpen="isOpenTextureUploader" @close="closeTextureUploader" @success="textureAddSuccess"
:relCommodityId="selCommodity ? selCommodity.id : null" /> -->
</template>
<script setup>
// https://2x.antdv.com/docs/vue/getting-started
// https://share.lanhuapp.com/#/invite?sid=lXPuKlJa
import Toolbar from '../../shelves-vue/components/editor/Toolbar.vue'
import TabListCommodity from '../../shelves-vue/components/editor/TabListCommodity.vue'
import TabListCommodityRelTexture from '../../shelves-vue/components/editor/TabListCommodityRelTexture.vue'
// import CommodityUploader from '../../shelves-vue/view/CommodityUploader.vue'
// import TextureUploader from '../../shelves-vue/view/TextureUploader.vue'
import SceneSeparateTexturePreviewer from '../../shelves-vue/components/SceneSeparateTexturePreviewer.vue'
</script>
<script>
import {downloadRes, updateMaterialCenter} from "../../../../api.js"
import common from "@/api/common.js";
import { message } from 'ant-design-vue'
export default {
props: {
currentModelData: {
type: Object,
default: () => (null)
},
title: {
type: String,
default: ""
},
},
data() {
return {
isOpenCommodityUploader: false,
isOpenTextureUploader: false,
selCommodity: null,
selTexture: null,
}
},
methods: {
onLoadingCompletion(){
if(!this.currentModelData) return;
var current = JSON.parse(JSON.stringify(this.currentModelData))
this.selCommodity = current.commodity
setTimeout(() => {
this.selTexture = current.texture
}, 100);
},
back() {
this.$router.go(-1)
},
async save(callback) {
try{
// create new ware
if(!this.selCommodity) {
message.warning("请选择商品模型");
callback();
return;
}
// if(!this.selTexture) {
// message.warning("请选择商品贴图");
// return;
// }
var clone = {
type: 1,
commodity: this.selCommodity,
texture: this.selTexture,
urlThumb: this.selCommodity.urlThumb,
}
console.log(clone)
const blob = await this.$refs.ss.previewer_.snapshot();
const res = await common.cosUpload3DCompress(blob);
await updateMaterialCenter({
id: this.$route.query.id,
data: JSON.stringify(clone),
simple_data: {},
version: new Date().getTime(),
cover: res.url
});
this.$router.go(-1);
}
catch(e){
console.log(e)
callback()
}
// this.$store.dispatch('wares/add', {
// type: 1,
// commodity: this.selCommodity,
// texture: this.selTexture,
// urlThumb: this.selCommodity.urlThumb,
// }).then(data2 => {
// })
},
//
addCommodity() {
this.isOpenCommodityUploader = true
},
clickThumbCommodity(itm) {
// console.log(itm)
this.selCommodity = itm
},
removeCommodity() {
this.selCommodity = null
},
//
//
addTexture() {
this.isOpenTextureUploader = true
},
clickThumbTexture(itm) {
this.selTexture = itm
},
removeTexture() {
this.selTexture = null
},
//
closeCommodityUploader() {
this.isOpenCommodityUploader = false
},
commodityAddSuccess(data) {
this.clickThumbCommodity(data)
},
closeTextureUploader() {
this.isOpenTextureUploader = false
},
textureAddSuccess(data) {
this.clickThumbTexture(data)
},
async downloadScreenshot () {
try {
const blob = await this.$refs.ss.previewer_.snapshot();
// var blob = await viewerRef.value.viewer.snapshot();
// console.log("props.title",this.title);
const data = await common.cosUpload(blob, this.title, "", () => {
});
console.log("data--",data);
var url = data.url;
var name = data.name;
downloadRes(url, name, 'png');
// 创建一个a标签并设置下载属性
// const link = document.createElement('a');
// link.href = url;
// link.target = "_blank";
// link.download = 'screenshot.png';
//
// // 模拟点击链接来触发下载
// link.click();
}catch(e){
console.log(e)
}
}
},
}
</script>
<style scoped>
div.ui {
position: fixed;
width: 100vw;
/* height: 100vh; */
}
.all {
height: 100vh;
/* background-color: beige; */
}
.yo-tabs {
position: absolute;
top: 90px;
left: 24px;
right: 24px;
bottom: 20px;
display: flex;
flex-direction: row;
flex: 1;
flex-basis: auto;
box-sizing: border-box;
min-width: 0;
border-radius: 6px;
background: transparent;
}
.yo-container {
position: absolute;
/* top: 135px; */
top: 90px;
left: 24px;
right: 24px;
bottom: 20px;
display: flex;
flex-direction: row;
flex: 1;
flex-basis: auto;
box-sizing: border-box;
min-width: 0;
/* margin: 21px 24px; */
border-radius: 0 6px 6px 6px;
background: #FFFFFF;
box-shadow: 0 10px 8px 0 rgba(0, 0, 0, 0.1);
}
.yo-main {
display: block;
flex: 1;
flex-basis: auto;
overflow: auto;
box-sizing: border-box;
padding: 0;
}
.top {
/* background-color: burlywood; */
height: auto;
padding: 0;
}
.left {
width: 280px;
background-color: #ffffff;
}
.main {
padding: 0px;
}
.right {
width: 280px;
background-color: #ffffff;
}
</style>

View File

@@ -1,125 +1,125 @@
<template>
<div class="container-previewer-1-"></div>
</template>
<script>
import { SeparateTexturePreviewer } from "../../../../lib/shelves.module"
// class Ref1 {
// constructor() {
// let current_ = null
// this.setCurrent = v => {
// current_ = v
// }
// this.getCurrent = () => {
// return current_
// }
// this.useCurrent = cb => {
// if (current_) {
// cb(current_)
// }
// }
// }
// }
export default {
props: ["isOpen", "selCommodity", "selTexture"],
mounted() {
console.log("## SeparateTexturePreviewer mounted", this.$el.clientWidth)
this.$nextTick(() => {
console.log("## SeparateTexturePreviewer mounted - nt", this.$el.clientWidth)
this.tryInitView()
})
},
watch: {
selCommodity(newVal, oldVal) {
if (this.previewer_) {
this.previewer_.selCommodity = newVal
// selCommodity 为 set 函数,其中异步的给 first_mat_ 赋值;
// 只有在 first_mat_ 被赋值后,才能添加纹理,但是没有 first_mat_ 被赋值后并没有回调,
// 所以,暂时加了一个定时器判断 first_mat_ 是否存在,并添加纹理;
let maxIntervalTime = 30; // 如果 30 秒内,还没有 first_mat_ 的话,就放弃添加纹理
const timer = setInterval(() => {
if (this.previewer_.first_mat_ || maxIntervalTime <= 0) {
this.previewer_.selTexture = this.selTexture;
clearInterval(timer);
}
maxIntervalTime -= 0.5;
}, 500);
}
},
selTexture(newVal, oldVal) {
if (this.previewer_) {
this.previewer_.selTexture = newVal
}
},
// brightness(oldV, newV) {
// // console.log('#brightness', oldV, newV)
// if (this.previewer_) {
// this.previewer_.brightness = newV
// }
// }
},
beforeUnmount() {
console.log("## SeparateTexturePreviewer beforeUnmount")
if (this.previewer_) {
this.previewer_.dispose()
this.previewer_ = null
}
},
methods: {
tryInitView() {
if (!this.previewer_) {
// let search = new URLSearchParams(document.location.search)
let container = this.$el
// console.log(container.clientWidth, container.clientHeight)
let v = new SeparateTexturePreviewer({
container,
prefixAsset: '/shelves-v5-asset', // v5, #20230104
})
v.on("loadingCompletion", () => {
console.log('## SeparateTexturePreviewer loadingCompletion')
this.$emit("onLoadingCompletion")
if (this.selTexture) {
v.selTexture = this.selTexture;
}
})
v.startup()
this.previewer_ = v
}
return this.previewer_
},
snapshot() {
if (this.previewer_) {
return this.previewer_.snapshot()
} else {
return null
}
},
},
};
</script>
<style scoped>
div.container-previewer-1- {
width: 100%;
height: 100%;
}
div.container-previewer-1-:focus {
outline: none;
}
div.container-previewer-1-:deep()canvas:focus {
outline: none;
}
</style>
<template>
<div class="container-previewer-1-"></div>
</template>
<script>
import { SeparateTexturePreviewer } from "../../../../lib/shelves.module"
// class Ref1 {
// constructor() {
// let current_ = null
// this.setCurrent = v => {
// current_ = v
// }
// this.getCurrent = () => {
// return current_
// }
// this.useCurrent = cb => {
// if (current_) {
// cb(current_)
// }
// }
// }
// }
export default {
props: ["isOpen", "selCommodity", "selTexture"],
mounted() {
console.log("## SeparateTexturePreviewer mounted", this.$el.clientWidth)
this.$nextTick(() => {
console.log("## SeparateTexturePreviewer mounted - nt", this.$el.clientWidth)
this.tryInitView()
})
},
watch: {
selCommodity(newVal, oldVal) {
if (this.previewer_) {
this.previewer_.selCommodity = newVal
// selCommodity 为 set 函数,其中异步的给 first_mat_ 赋值;
// 只有在 first_mat_ 被赋值后,才能添加纹理,但是没有 first_mat_ 被赋值后并没有回调,
// 所以,暂时加了一个定时器判断 first_mat_ 是否存在,并添加纹理;
let maxIntervalTime = 30; // 如果 30 秒内,还没有 first_mat_ 的话,就放弃添加纹理
const timer = setInterval(() => {
if (this.previewer_.first_mat_ || maxIntervalTime <= 0) {
this.previewer_.selTexture = this.selTexture;
clearInterval(timer);
}
maxIntervalTime -= 0.5;
}, 500);
}
},
selTexture(newVal, oldVal) {
if (this.previewer_) {
this.previewer_.selTexture = newVal
}
},
// brightness(oldV, newV) {
// // console.log('#brightness', oldV, newV)
// if (this.previewer_) {
// this.previewer_.brightness = newV
// }
// }
},
beforeUnmount() {
console.log("## SeparateTexturePreviewer beforeUnmount")
if (this.previewer_) {
this.previewer_.dispose()
this.previewer_ = null
}
},
methods: {
tryInitView() {
if (!this.previewer_) {
// let search = new URLSearchParams(document.location.search)
let container = this.$el
// console.log(container.clientWidth, container.clientHeight)
let v = new SeparateTexturePreviewer({
container,
prefixAsset: '/shelves-v5-asset', // v5, #20230104
})
v.on("loadingCompletion", () => {
console.log('## SeparateTexturePreviewer loadingCompletion')
this.$emit("onLoadingCompletion")
if (this.selTexture) {
v.selTexture = this.selTexture;
}
})
v.startup()
this.previewer_ = v
}
return this.previewer_
},
snapshot() {
if (this.previewer_) {
return this.previewer_.snapshot()
} else {
return null
}
},
},
};
</script>
<style scoped>
div.container-previewer-1- {
width: 100%;
height: 100%;
}
div.container-previewer-1-:focus {
outline: none;
}
div.container-previewer-1-:deep()canvas:focus {
outline: none;
}
</style>

View File

@@ -1,109 +1,125 @@
<template>
<div class="tool-bar">
<!-- <el-button class="yo-btn-rect yo-btn-back" type="primary" @click="$emit('back')">
<el-icon class="yo-icon"><img :src="IconBack" /></el-icon>
</el-button> -->
<a-button class="yo-btn-back" type="text" @click="$emit('back')">
<template #icon>
<LeftOutlined />
</template>
{{props.title}}
</a-button>
<a-button class="yo-btn-right" type="primary" @click="save" :loading="loading">
<template #icon>
<img :src="SaveSvg" />
</template>
<span style="font-size: 15px;">保存</span>
</a-button>
</div>
</template>
<script setup>
// console.log(IconSelect)
import { SendOutlined, LeftOutlined } from '@ant-design/icons-vue'
import { ref } from '@vue/reactivity';
import SaveSvg from '../../asset/icon2/save.svg'
const props = defineProps(["title"]);
const $emit = defineEmits("save");
const loading = ref(false);
const save = () => {
loading.value = true;
$emit('save', () => {
loading.value = false;
});
}
</script>
<style scoped>
.el-button+.el-button {
margin-left: 0;
}
.tool-bar {
display: flex;
height: 70px;
background: #FFFFFF;
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.0614);
}
.yo-btn-right {
position: absolute;
right: 15px;
align-self: center;
height: 40px;
width: 100px;
min-width: 10px;
line-height: 28px;
color: #FFFFFF;
/* background: #1C6FFF; */
background: #70B936;
border-color: #70B936;
font-size: 15px;
font-weight: 400;
border-radius: 6px;
letter-spacing: 2px;
/* padding: 4px 20px; */
}
.yo-btn-right:hover {
border: #70B936;
}
.yo-btn-right:focus {
border: #70B936;
}
.yo-btn-right img {
width: 24px;
margin-right: 6px;
padding-bottom: 2px;
}
.yo-btn-back {
position: absolute;
left: 15px;
align-self: center;
height: 40px;
min-width: 10px;
/* line-height: 24px; */
color: #434343;
font-size: 15px;
font-weight: 400;
letter-spacing: 2px;
/* padding: 4px 20px; */
}
.yo-btn-back img {
width: 24px;
margin-right: 6px;
}
</style>
<template>
<div class="tool-bar">
<!-- <el-button class="yo-btn-rect yo-btn-back" type="primary" @click="$emit('back')">
<el-icon class="yo-icon"><img :src="IconBack" /></el-icon>
</el-button> -->
<a-button class="yo-btn-back" type="text" @click="$emit('back')">
<template #icon>
<LeftOutlined />
</template>
{{props.title}}
</a-button>
<a-button type="button" @click="downloadScreenshot" class="down-but" ><span class="icon iconfont" style="font-size: 1.15rem;margin-right: 5px;">&#xe869;</span>下载素材图</a-button>
<a-button class="yo-btn-right" type="primary" @click="save" :loading="loading">
<template #icon>
<img :src="SaveSvg" />
</template>
<span style="font-size: 15px;">保存</span>
</a-button>
</div>
</template>
<script setup>
// console.log(IconSelect)
import { SendOutlined, LeftOutlined } from '@ant-design/icons-vue'
import { ref } from '@vue/reactivity';
import SaveSvg from '../../asset/icon2/save.svg'
const props = defineProps(["title"]);
const $emit = defineEmits("save");
const loading = ref(false);
const save = () => {
loading.value = true;
$emit('save', () => {
loading.value = false;
});
}
const downloadScreenshot = () => {
$emit('downloadScreenshot', () => {
});
}
</script>
<style scoped>
.el-button+.el-button {
margin-left: 0;
}
.tool-bar {
display: flex;
height: 70px;
background: #FFFFFF;
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.0614);
}
.yo-btn-right {
position: absolute;
right: 15px;
align-self: center;
height: 40px;
width: 100px;
min-width: 10px;
line-height: 28px;
color: #FFFFFF;
/* background: #1C6FFF; */
background: #70B936;
border-color: #70B936;
font-size: 15px;
font-weight: 400;
border-radius: 6px;
letter-spacing: 2px;
/* padding: 4px 20px; */
}
.yo-btn-right:hover {
border: #70B936;
}
.yo-btn-right:focus {
border: #70B936;
}
.yo-btn-right img {
width: 24px;
margin-right: 6px;
padding-bottom: 2px;
}
.yo-btn-back {
position: absolute;
left: 15px;
align-self: center;
height: 40px;
min-width: 10px;
/* line-height: 24px; */
color: #434343;
font-size: 15px;
font-weight: 400;
letter-spacing: 2px;
/* padding: 4px 20px; */
}
.yo-btn-back img {
width: 24px;
margin-right: 6px;
}
.down-but{
position: absolute;
right: 130px;
height: 40px;
top: 15px;
display:flex;
align-items: center;
border-radius: 4px;
}
</style>

View File

@@ -11,22 +11,41 @@
import SceneSeparateTexturePreviewer from "./3d/crossyo/shelves-vue/components/SceneSeparateTexturePreviewer.vue";
import { ref } from "@vue/reactivity";
import { getMaterialsById } from "./api";
import {downloadRes, getMaterialsById} from "./api";
import { useRoute } from "vue-router";
import { regDelTinymceCreativeIframe } from "./utils/iframeEvent";
import { onMounted } from "vue";
import { onMounted,defineProps } from "vue";
import common from "@/api/common";
const props = defineProps({
id: {
type: Number,
default: undefined,
},
})
const route = useRoute();
const selCommodity = ref(null);
const selTexture = ref(null);
const viewer = ref();
onMounted(() => {
regDelTinymceCreativeIframe();
// 在第二层组件的mounted钩子中将第三层组件的ref方法赋值给第二层组件的ref
// this.$refs.viewer.snapshot = this.$refs.thirdComponentRef.snapshot;
});
const onLoadingCompletion = async () => {
const res = await getMaterialsById(route.query.id);
let id = route.query.id;
if (!id)
{
id = props.id;
}
const res = await getMaterialsById(id);
const data = JSON.parse(res.data.materials[0].space_json);
selCommodity.value = data.commodity;
@@ -35,7 +54,12 @@ const onLoadingCompletion = async () => {
}, 200);
}
//将数据暴漏出去给父组件用
defineExpose({
viewer
})
</script>
<style>
</style>
</style>

View File

@@ -37,7 +37,7 @@ export default {
async mounted() {
regDelTinymceCreativeIframe();
const res = await getMaterialsById(this.$route.query.id);
try{
const data = JSON.parse(res.data.materials[0].space_json);
@@ -99,4 +99,4 @@ export default {
top: 50%;
transform: translate(-50%, -50%);
}
</style>
</style>

View File

@@ -1,24 +1,65 @@
<template>
<a-modal v-model:visible="visible" title="3D产品模型" width="1000px" @ok="ok" :footer="null">
<iframe v-if="visible" :src="url" frameborder="0" style="width: 100%; height: 500px;"></iframe>
<a-modal v-model:visible="visible" width="1000px" @ok="ok" :footer="null">
<template #title >
<div style="display: flex;justify-content: flex-start">
<div style="font-weight: 600;margin-right: 20px">3D产品模型</div>
<div @click="downloadScreenshot" style="color: #70b936; cursor: pointer;"><span class="icon iconfont" style="font-size: 1.15rem;margin-right: 5px;">&#xe869;</span>下载素材图</div>
</div>
</template>
<div style="height: 500px">
<Model3DPreviewerViewerPreview
v-if="visible"
ref="viewerRef"
:id="data3d.id"
/>
</div>
<!-- <iframe v-if="visible" :src="url" frameborder="0" style="width: 100%; height: 500px;"></iframe>-->
</a-modal>
</template>
<script setup>
import common from "@/api/common";
import {downloadRes} from "@/views/Creative/api";
import Model3DPreviewerViewerPreview
from "@/views/Creative/Model3DPreview.vue";
const { ref }=require("@vue/reactivity");
const visible = ref(false);
const url = ref("")
const data3d = ref();
defineExpose({
show(data){
data3d.value = data;
url.value = `/#/model3d-preview?id=${data.id}`;
visible.value = true;
}
})
const viewerRef = ref();
const downloadScreenshot = async () =>{
var blob = await viewerRef.value.viewer.snapshot();
// const data = await common.cosUpload3DCompress(blob);
const data = await common.cosUpload(blob, blob.name, "", () => {});
var url= data.url;
var name= data.name;
downloadRes(url, name, 'png');
// 创建一个a标签并设置下载属性
// const link = document.createElement('a');
// link.href = url;
// link.target = "_blank";
// link.download = 'screenshot.png';
//
// // 模拟点击链接来触发下载
// link.click();
};
</script>
<style>
</style>
</style>

View File

@@ -1,72 +1,76 @@
<template>
<a-modal
v-model:visible="sceneViewer.visible"
title="场景预览"
:maskClosable="false"
:width="800"
:footer="null"
>
<div style="height: 500px">
<SceneSurveyViewerPreview
v-if="sceneViewer.visible"
:shopData="sceneViewer.shopData"
:page="sceneViewer.page"
:page_shelves="sceneViewer.page_shelves"
:sceneAction="sceneViewer.sceneAction"
@onLoadingCompletion="onLoadingCompletion"
@onFromSceneHoldToShelf="onFromSceneHoldToShelf"
/>
</div>
</a-modal>
</template>
<script setup>
import SceneSurveyViewerPreview from "@/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview";
import { buildShopDataDemo } from "@/views/planetDesign/Design/components/config/config3d.utils";
import { reactive, ref } from "@vue/reactivity";
const sceneViewer = reactive({
visible: false,
shopData: null,
page: null,
page_shelves: null,
sceneAction: null,
});
const onLoadingCompletion = () => {
sceneViewer.page_shelves = {
shelves: sceneViewer.shopData.shelves
};
};
const onFromSceneHoldToShelf = () => {
sceneViewer.sceneAction = {
action: "hold_to_shelf",
};
};
defineExpose({
show(data) {
var json = JSON.parse(data.materials[0].space_json);
const shopData = buildShopDataDemo(json);
console.log(shopData);
if(shopData.type == "panorama") {
shopData.panorama.url += "?real";
shopData.panorama.urlSmall += "?real";
}
if(shopData.type == "hall") {
shopData.hall.url += "?real";
shopData.hall.urlSmall += "?real";
}
sceneViewer.shopData = shopData;
sceneViewer.page = null;
sceneViewer.visible = true;
},
});
</script>
<style>
</style>
<template>
<a-modal
v-model:visible="sceneViewer.visible"
title="场景预览"
:maskClosable="false"
:width="800"
:footer="null"
>
<div style="height: 500px">
<SceneSurveyViewerPreview
v-if="sceneViewer.visible"
:shopData="sceneViewer.shopData"
:page="sceneViewer.page"
:page_shelves="sceneViewer.page_shelves"
:sceneAction="sceneViewer.sceneAction"
@onLoadingCompletion="onLoadingCompletion"
@onFromSceneHoldToShelf="onFromSceneHoldToShelf"
/>
</div>
</a-modal>
</template>
<script setup>
import SceneSurveyViewerPreview from "@/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview";
import { buildShopDataDemo } from "@/views/planetDesign/Design/components/config/config3d.utils";
import { reactive, ref } from "@vue/reactivity";
import common from "@/api/common";
import {downloadRes} from "@/views/Creative/api";
const sceneViewer = reactive({
visible: false,
shopData: null,
page: null,
page_shelves: null,
sceneAction: null,
});
const onLoadingCompletion = () => {
sceneViewer.page_shelves = {
shelves: sceneViewer.shopData.shelves
};
};
const onFromSceneHoldToShelf = () => {
sceneViewer.sceneAction = {
action: "hold_to_shelf",
};
};
defineExpose({
show(data) {
var json = JSON.parse(data.materials[0].space_json);
const shopData = buildShopDataDemo(json);
console.log(shopData);
if(shopData.type == "panorama") {
shopData.panorama.url += "?real";
shopData.panorama.urlSmall += "?real";
}
if(shopData.type == "hall") {
shopData.hall.url += "?real";
shopData.hall.urlSmall += "?real";
}
sceneViewer.shopData = shopData;
sceneViewer.page = null;
sceneViewer.visible = true;
},
});
</script>
<style>
</style>

View File

@@ -9,7 +9,12 @@
<!-- 下载题型-->
<div class="file-question" v-if="question_type === 18" :style="{width:data.width + 'px'}">
<div class="label">{{ content }}</div>
<a-button size="mini" @click="download">下载全部附件</a-button>
<i
class="iconfont icon-xiazai"
style="color: #70b936; cursor: pointer"
@click="download"
></i>
<!-- <a-button size="mini" @click="download">下载全部附件333</a-button>-->
</div>
<!-- 图文题-->
@@ -49,11 +54,12 @@ const question_type = ref(null)
// https://stackoverflow.com/questions/15458876/check-if-a-string-is-html-or-not
const includeHtmlTag = computed(() =>/<\/?[a-z][\s\S]*>/i.test(content.value))
const shortTitle = computed(() => content.value ? content.value.slice(0, 40) : '')
const searchParams = ref({});
function download() {
const params = JSON.parse(JSON.stringify(props.search_params))
const query = convertQueryToString(params)
// console.log("serpar",params);
searchParams.value = params;
// downloadAnswerFile(props.sn, question_index.value, query).then(res => {
// // const url = res.data.url
// // downloadFile(url)
@@ -72,7 +78,7 @@ const route = useRoute();
const downloadVisible = ref(false);
// 下载中心
function downloadCenter() {
let data ={ download_type: '3', question_index:question_index.value }
let data ={ download_type: '3', question_index:question_index.value, ...searchParams.value }
addDownloadCenter(props.sn,data).then(res=>{
store.dispatch('downloadCenter/changeCenterUrl',route.path)
// downloadVisible.value = true
@@ -110,7 +116,7 @@ watchEffect(() => {
display: flex;
align-items: center;
.label {
width: 50%;
width: 40%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

View File

@@ -32,14 +32,13 @@
</template>
<script setup>
import { defineComponent, ref, toRefs, watchEffect, useAttrs, onUnmounted, reactive, useSlots, defineProps, createVNode, resolveComponent, h } from 'vue'
import { defineComponent,watch, ref, toRefs, watchEffect, useAttrs, onUnmounted, reactive, useSlots, defineProps, createVNode, resolveComponent, h } from 'vue'
import { useStore } from 'vuex'
import usePagination from '@views/DataAnalyse/composables/usePagination'
import useGeneratorTableColumns from '@views/DataAnalyse/composables/use-generator-table-columns'
import useCustomHeaderTitle from '@views/DataAnalyse/composables/useCustomHeaderTitle'
import RenderTableTitle from '@views/DataAnalyse/components/RenderTableTitle'
import { computed } from '@vue/reactivity'
import { watch } from 'fs'
import * as cheerio from 'cheerio'
import { Input, Modal } from 'ant-design-vue'
@@ -95,17 +94,18 @@ const props = defineProps({
sn: {
type: String,
default: ''
}
},
})
const emit = defineEmits(['change', 'select'])
const store = useStore()
const data = ref([])
const columns = ref(null)
const searchParams = ref(props.params)
const { perPage: per_page, total, page, rowKey } = toRefs(props)
const { pagination } = usePagination(per_page, total, page)
const { tableHeaders } = useGeneratorTableColumns(columns)
const { customHeaders } = useCustomHeaderTitle(tableHeaders, props.sn, props.params)
console.log('tableHeaders', tableHeaders)
const { customHeaders } = useCustomHeaderTitle(tableHeaders, props.sn, searchParams)
// 页码&分页条数,改变时候触发
const handlePageChange = (data) => {
const { pageSize, current } = data
@@ -157,6 +157,11 @@ const showSign = (item) => {
const hideSign = (item) => {
emit('sign', [item], false)
}
watch(()=>props.params,(val)=>{
searchParams.value = val;
delete searchParams.value.type;//文件下载没有type类型去掉
},{deep:true})
</script>
<style lang="scss" scoped>
.show-type {

View File

@@ -56,33 +56,48 @@
</a-modal>
<!-- 导出框 -->
<a-modal class="custom-modal" v-model:visible="dataExportVis" title="数据导出" @ok="dataExportOk">
<a-form ref="formRef" :model="formState" :rules="rules">
<a-form-item ref="type" label="文件格式" name="type">
<a-select class="custom-select" v-model:value="formState.type" placeholder="请选择" @change="changeType">
<a-select-option value="1">Excel(.xlsx)</a-select-option>
<a-select-option value="2">CSV-逗号分隔值.csv</a-select-option>
<a-select-option value="3">SPSS统计包.sav</a-select-option>
</a-select>
<a-form ref="formRef" :model="formState" :rules="rules" :labelCol="{ span:5 }" >
<a-form-item ref="type" label="文件格式" name="type" >
<a-radio-group v-model:value="formState.type" @change="changeType" class="custom-radio-group">
<a-radio class="custom-radio" value="1">Excel(.xlsx)</a-radio>
<a-radio class="custom-radio" value="2">CSV(.csv)</a-radio>
<a-radio class="custom-radio" value="3">SPSS(.sav)</a-radio>
</a-radio-group>
<!-- <a-select class="custom-select" v-model:value="formState.type" placeholder="请选择" @change="changeType">-->
<!-- <a-select-option value="1">Excel(.xlsx)</a-select-option>-->
<!-- <a-select-option value="2">CSV-逗号分隔值.csv</a-select-option>-->
<!-- <a-select-option value="3">SPSS统计包.sav</a-select-option>-->
<!-- </a-select>-->
</a-form-item>
<a-form-item ref="header_column_type" label="题目行格式">
<a-select class="custom-select" v-model:value="formState.header_column_type" placeholder="请选择">
<a-select-option value="0" >题目文本</a-select-option>
<a-select-option value="1">题目序号</a-select-option>
</a-select>
<a-form-item ref="header_column_type" label="题目行格式" @change="changeHeaderColumnType" >
<a-radio-group v-model:value="formState.header_column_type" class="custom-radio-group">
<a-radio class="custom-radio" value="0" :disabled="formState.type === '3'">文本</a-radio>
<a-radio class="custom-radio" value="1">序号</a-radio>
</a-radio-group>
<!-- <a-select class="custom-select" v-model:value="formState.header_column_type" placeholder="请选择">-->
<!-- <a-select-option value="0" :disabled="formState.type === '3'">题目文本</a-select-option>-->
<!-- <a-select-option value="1">题目序号</a-select-option>-->
<!-- </a-select>-->
</a-form-item>
<a-form-item ref="column_type" label="答案行格式">
<a-select class="custom-select" v-model:value="formState.column_type" placeholder="请选择">
<a-select-option value="0" >答案文本</a-select-option>
<a-select-option value="1">答案代码</a-select-option>
</a-select>
<a-form-item ref="column_type" label="答案行格式" @change="changneColumnType" >
<a-radio-group v-model:value="formState.column_type" class="custom-radio-group">
<a-radio class="custom-radio" value="0" >文本</a-radio>
<a-radio class="custom-radio" value="1">代码</a-radio>
</a-radio-group>
<!-- <a-select class="custom-select" v-model:value="formState.column_type" placeholder="请选择">-->
<!-- <a-select-option value="0" :disabled="formState.type === '3'">答案文本</a-select-option>-->
<!-- <a-select-option value="1">答案代码</a-select-option>-->
<!-- </a-select>-->
</a-form-item>
<a-form-item label="是否包括开放文本" name="include_open">
<a-form-item label="导出开放文本" name="include_open">
<div class="switchBox">
<span>开放式文本包括填空题文件上传题等</span>
<a-switch v-model:checked="formState.include_open" />
</div>
</a-form-item>
<a-form-item label="是否包括作答信息" name="contains_base">
<a-form-item label="导出作答信息" name="contains_base">
<div class="switchBox">
<span></span>
<a-switch v-model:checked="formState.contains_base" />
@@ -106,8 +121,13 @@
<a-switch v-model:checked="formState.is_import" />
</div>
</a-form-item> -->
<a-form-item ref="name" label="数据" v-if="operType !== 1">
<a-select class="custom-select" v-model:value="formState.isFilter" placeholder="请选择" :options="isFilterData"> </a-select>
<a-form-item ref="name" label="数据导出范围" v-if="operType !== 1" >
<a-radio-group v-model:value="formState.isFilter" class="custom-radio-group">
<a-radio class="custom-radio" v-for="radio in isFilterData" :key="radio.value" :value="radio.value">
{{ radio.label }}
</a-radio>
</a-radio-group>
<!-- <a-select class="custom-select" v-model:value="formState.isFilter" placeholder="请选择" :options="isFilterData"> </a-select>-->
</a-form-item>
</a-form>
</a-modal>
@@ -463,14 +483,14 @@ const selectKeys = computed(() => store.state.dataFilter.selectKeys)
const isFilterData = computed(() => {
const retArr = [
{
value: '0',
label: '整个数据'
value: '1',
label: '筛选后数据'
}
]
if (isFilterInfo.value?.isFilterFlag) {
retArr.push({
value: '1',
label: '筛选后数据'
value: '0',
label: '整个数据'
})
}
// if(selectKeys.value.length>0){
@@ -494,11 +514,11 @@ const formState = reactive({
})
const rules = {
type: [
{
required: true,
message: '请选择文件格式',
trigger: 'change'
}
// {
// required: true,
// message: '请选择文件格式',
// trigger: 'change'
// }
]
}
// 模板下载
@@ -868,18 +888,50 @@ const postSurveysAnswersClone = async (id) => {
// 修改格式
const changeType = (e) => {
console.log(e)
if (e == 3) {
formState.column_type = null
formState.header_column_type = null
formState.include_open = false
formState.contains_base = false
} else {
formState.column_type = '0'
formState.header_column_type = '0'
formState.include_open = true
formState.contains_base = true
if (e.target.value ==2)
{
//如果选择csv格式如果选择序号或者代码则提示
if (formState.column_type == 1 || formState.header_column_type == 1)
{
message.warning('CSV文件由于格式限制不支持导出代码与文本对照表如有需要请下载Excel文件')
}
}
if (e.target.value ==3)
{
formState.header_column_type = '1'
}
// if (e == 3) {
// formState.column_type = null
// formState.header_column_type = null
// formState.include_open = false
// formState.contains_base = false
// } else {
// formState.column_type = '0'
// formState.header_column_type = '0'
// formState.include_open = true
// formState.contains_base = true
// }
}
const changeColumnType = (e) => {
//如果选择序号则判断导出格式类型是否是csv则提示
if (e.target.value ==1) {
if (formState.type == 2) {
message.warning('CSV文件由于格式限制不支持导出代码与文本对照表如有需要请下载Excel文件')
}
}
}
const changeHeaderColumnType = (e) => {
//如果选择代码则判断导出格式类型是否是csv则提示
if (e.target.value ==1) {
if (formState.type == 2) {
message.warning('CSV文件由于格式限制不支持导出代码与文本对照表如有需要请下载Excel文件')
}
}
}
watch(
() => modalVis.value,
async (nval) => {

View File

@@ -53,4 +53,4 @@ const eventClick = ()=>{}
.actIcon{
margin-left: 10px;
}
</style>
</style>

View File

@@ -1,7 +1,7 @@
import { ref, watch } from "vue";
import CustomTableHeaderCell from '@/views/DataAnalyse/components/CustomTableHeaderCell'
export default function renderCustomHeader(columns, sn ,search_params) {
const customHeaders = ref([])
function renderCell(data, sn, search_params) {
@@ -12,12 +12,25 @@ export default function renderCustomHeader(columns, sn ,search_params) {
customHeaders.value = data.map(item => {
return {
...item,
title: renderCell(item, sn, search_params)
title: renderCell(item, sn, search_params.value)
}
})
}
}, {
immediate: true
})
return { customHeaders }
watch(search_params, (data) => {
if(columns) {
customHeaders.value = columns.value.map(item => {
return {
...item,
title: renderCell(item, sn, data)
}
})
}
}, {
deep:true
})
return {customHeaders}
}

View File

@@ -84,7 +84,7 @@ export default defineComponent({
const permission = inject("permission");
const searchParams = inject("searchParams");
console.log('searchParams',searchParams);
const tableSource = ref([]);
const columns = ref([
@@ -138,7 +138,12 @@ export default defineComponent({
async function handleClick() {
const sn = props.sn;
const question_index = props.data.question_index;
let data ={ download_type: '3', question_index }
const tableSearchInfo = searchParams.value;
delete tableSearchInfo.type;//文件下载没有type类型去掉
console.log(tableSearchInfo);
let data ={ download_type: '3', question_index,...tableSearchInfo }
addDownloadCenter(sn,data).then(res=>{
store.dispatch('downloadCenter/changeCenterUrl',route.path)
store.dispatch('downloadCenter/changeCenterShow',true)

View File

@@ -17,7 +17,7 @@
</div>
</search> -->
<!-- 新的筛选 -->
<newSearch ref="newSearchRef" @onSearch="onSearch" @openModal="openModal" @searchPlan="searchPlan" @saveVisOpen="saveVisOpen" :versions="versions" :logics="logics" :questions="questions" :count="dataCount" :publish_types="publish_types" :filterData="filterData" :isArt="isArt" :nowPlanVal="nowPlanVal" />
<newSearch ref="newSearchRef" @onSearch="onSearch" @openModal="openModal" @searchPlan="searchPlan" @saveVisOpen="saveVisOpen" :versions="versions" :logics="logics" :questions="questions" :count="dataCount" :publish_types="publish_types" :filterData="filterData" :isArt="isArt" :nowPlanVal="nowPlanVal" />
<!-- 新的操作按钮 -->
<newBtnList
ref="newBtnListRef"
@@ -148,7 +148,8 @@ const searchParams = computed(() => {
return {
...queryState.value,
page: page.value,
per_page: per_page.value
per_page: per_page.value,
...subInfo.value
}
})

View File

@@ -23,12 +23,12 @@ export default {
methods: {
tryInitView() {
if (!this.viewer_) {
this.viewer_ = new SurveyViewer({
container: this.$el,
surveyId: this.surveyId,
shopData: this.shopData,
prefixAsset: '/shelves-v5-asset', // v5, #20230104
});
this.viewer_.on("loadingCompletion", () => {
@@ -48,19 +48,27 @@ export default {
}
return this.viewer_;
},
snapshot() {
if (this.viewer_) {
return this.viewer_.snapshot()
} else {
return null
}
},
},
watch: {
page(newVal, oldVal) {
// console.log('page ........', newVal, oldVal)
if (this.viewer_) {
this.viewer_.flyAnimation = !(this.defaultWare?.planetid && this.isLocked);
this.viewer_.frostFarScene = this.isLocked;
this.viewer_.arrange(newVal).then(() => {
this.$emit("onPageCompletion");
if(!this.defaultWare) return;
// #20221018
@@ -72,7 +80,7 @@ export default {
});
}
},
page_shelves(newVal, oldVal) {
console.log('page ........', newVal, oldVal)
if (this.viewer_) {
@@ -80,7 +88,7 @@ export default {
this.$emit("onPageCompletion")
if(!this.defaultWare) return;
// #20221018
this.viewer_.hold({
wareId: this.defaultWare?.planetid,
@@ -118,4 +126,4 @@ div.container-viewer-1-:focus {
div.container-viewer-1- >>> canvas:focus {
outline: none;
}
</style>
</style>

View File

@@ -534,4 +534,4 @@ export default {
.right-10 {
margin-right: 10px;
}
</style>
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="random-list">
<div class="random-list-add">
<a-button class="custom-button" type="primary" @click="addRaddom">添加随机</a-button>
<a-button class="custom-button" type="primary" @click="addRaddom" :disabled="isAdd" >添加随机</a-button>
</div>
<div
class="random-list-show"
@@ -153,6 +153,8 @@ export default {
const questions = ref(props.data.questions);
const logics = ref(props.data.logics);
const deal_questions = ref(props.data.deal_questions);
const isAdd = ref(false); //是否可以点击添加随机按钮 只有 当存在未填写完成的题组时,【添加随机】按钮置灰,即不可点击
onMounted(async () => {
var data= await getProcess({
sn: route.query.sn
@@ -201,6 +203,8 @@ export default {
};
const addRaddom = () => {
isAdd.value = true;
options.value.push({
title: `随机${options.value.length + 1}`,
num: undefined,
@@ -229,6 +233,8 @@ export default {
document.getElementById('logicalContent').scrollTop =
options.value.length * 775;
});
// console.log('isAdd--'+isAdd)
};
const addoptions = (item) => {
@@ -303,9 +309,11 @@ export default {
};
const onStartChange = () => {
console.log("star")
edit();
};
const onEndChange = () => {
console.log("edncha")
edit();
};
//获取 全部信息
@@ -728,7 +736,28 @@ export default {
// });
}
};
// 逻辑内容有一个没填则不允许添加新的逻辑
//监听,页面表单内容变化 用于监听data里面的数据是否被修改一旦修改就可以执行一些其他的操作
watch(
() => options,
(newOp) => {
// console.log('item--', newOp)
for (const newOpElement of newOp.value) {
for (const newOpElementList of newOpElement.list) {
if(!newOpElementList.start || !newOpElementList.end || !newOpElementList.title ) {
isAdd.value = true
break;
}else{
isAdd.value = false
}
}
//如果已经有未填写的,直接跳出去
if (isAdd.value) break;
}
},
{deep:true} // deep深度监听
);
return {
options,
addRaddom,
@@ -742,6 +771,7 @@ export default {
onEndChange,
onClickOutside,
emptyImage,
isAdd
};
}
};

View File

@@ -70,7 +70,7 @@
@change="changeallnumber"
v-model:value="actDetailform.rate"
precision="2"
:disabled="route.query.start == '1' || route.query.e == '3'"
:disabled="(route.query.start == '1' && !editable ) || route.query.e == '3'"
/>
<span>%</span>
</div>
@@ -382,12 +382,13 @@
<template #type="{ record }">
<span v-if="record.type == 2">虚拟奖品</span>
<span v-if="record.type == 1">实物奖品</span>
<span v-if="record.type == 3">跳转兑奖</span>
</template>
<template #number="{ record }"> {{ record.number }}个 </template>
<template #prize_rate="{ record }">
<a-input-number
class="custom-input-number"
:disabled="route.query.start == '1' || route.query.e == '3'"
:disabled="(route.query.start == '1' && !editable) || route.query.e == '3' "
:min="0"
precision="0"
style="width: 75px"
@@ -519,11 +520,12 @@
ref="select"
v-model:value="formState.type"
style="width: 100%"
:disabled="route.query.start == '1' || route.query.start == '2'"
:disabled="route.query.start == '1' || route.query.start == '2' || route.query.start == '3'"
@change="changetype(formSratetate.type)"
>
<a-select-option :value="1">实物奖品(需邮寄</a-select-option>
<a-select-option :value="2">虚拟奖品(发放券码</a-select-option>
<a-select-option :value="1">实物奖品(需根据中奖者信息发放奖品</a-select-option>
<a-select-option :value="2">虚拟奖品(中奖者自行通过券码兑奖</a-select-option>
<a-select-option :value="3">跳转兑奖(中奖后跳转至指定页面兑奖)</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="奖品名称" name="title">
@@ -606,6 +608,14 @@
</a-col>
</a-row>
</a-form-item>
<a-form-item label="跳转链接" name="jump_link" v-if="formState.type == 3" >
<a-textarea
v-model:value="formState.jump_link"
:disabled="route.query.start == '3'"
placeholder="请输入要跳转的网页链接或当前小程序页面路径"
/>
</a-form-item>
</a-form>
</a-modal>
</div>
@@ -686,6 +696,7 @@ export default defineComponent({
const send_type = ref(true);
const imageUrl = ref("");
const edidindex = ref(null);
const editable = ref(false);
//打开抽奖设置
const openform = (index) => {
var xxcy =
@@ -744,6 +755,7 @@ export default defineComponent({
// send_message: [{ required: true, message: '请输入操作提示', trigger: "blur" }],
exchange_method: [{ required: true, message: "请输入兑奖方式", trigger: "blur" }],
img_url: [{ required: true, message: "请添加奖品图片", trigger: "blur" }],
jump_link: [{ required: true, message: "请填写跳转链接", trigger: "blur" }],
};
//添加抽奖设置
const handleOk = () => {
@@ -826,6 +838,7 @@ export default defineComponent({
const actDetailform = ref({
rate: "",
is_only: "1",
editable:"0",//进行中是否可以编辑
updated_at: [],
send_day: "",
send_name: "",
@@ -999,11 +1012,13 @@ export default defineComponent({
});
};
const changeallnumber = () => {
if (actDetailform.value.rate > 100) {
message.error("概率总和不能大于100");
actDetailform.value.rate=''
}
};
//获取活动详情
const actDetail = async () => {
spinning.value = true;
@@ -1027,6 +1042,9 @@ export default defineComponent({
actDetailform.value = res.data;
actDetailform.value.updated_at = [res.data.send_start_date, res.data.send_end_date];
spinning.value = false;
editable.value = actDetailform.value.editable;//根据是否有作答记录返回的,是否可以编辑中间概率
console.log("editable--"+editable.value)
res.data.prizes.map((item) => {
if (item.id !== 0) {
leftlist.value.push(item);
@@ -1067,6 +1085,11 @@ export default defineComponent({
const changeMethod = () => {
methodlength.value = formState.value.exchange_method.length;
};
// const changeMethod = () => {
// methodlength.value = formState.value.exchange_method.length;
// };
const methodlength = ref(0);
return {
changeMethod,
@@ -1118,6 +1141,7 @@ export default defineComponent({
openform,
lookvisible,
actDetail,
editable
};
},
});

View File

@@ -100,6 +100,36 @@
</a-modal>
</div>
<div class="cumuDownModal"
ref="mymodal">
<a-modal :visible="visible3"
:closable='false'
:getContainer='()=>$refs.mymodal'>
<div>
<div style="text-align:center;font-size:16px">恭喜您中奖啦</div>
<div style="text-align:center"><img style="width:50%;margin:5vh auto"
:src="imgurl"
alt="">
<div style="text-align:center;margin:-2vh 0 4vh 0;font-size:16px">{{title}}</div>
</div>
<div style="width:90%;margin:0 auto;font-size:16px;text-align:center">
<a-button @click="skipPrize"
style="width:60%"
type="primary">立即兑奖
</a-button>
</div>
</div>
<template #footer>
<div style="text-align:center">
<!-- <img @click="cancel"
style="width:15%;margin:1vh auto "
src="@/assets/img/redpacket/close.png"
alt=""> -->
</div>
</template>
</a-modal>
</div>
</div>
</template>
@@ -219,6 +249,7 @@ export default defineComponent({
const visible = ref(false)
const visible1 = ref(false)
const visible2 = ref(false)
const visible3 = ref(false)
const showcj = ref(false)
const index = ref('')
// 转盘上要展示的奖品数据
@@ -245,10 +276,12 @@ export default defineComponent({
visible.value = false
visible1.value = false
visible2.value = false
visible3.value = false
};
const log_id = ref('')
const imgurl = ref('')
const title = ref('')
const jump_link = ref('') //跳转兑奖的,跳转链接地址
const addinfor = () => {
visible1.value = false
router.push({
@@ -266,6 +299,30 @@ export default defineComponent({
}
});
}
//跳转兑奖
const skipPrize = () => {
visible3.value = false
// router.push({
// path: jump_link.value
// });
const url = jump_link.value;
console.log("url--"+url)
// 判断是否小程序路径
if (url[0] === "/") {
// 判断是否在小程序环境
wx.miniProgram.getEnv(() => {
wx.miniProgram.redirectTo({ url });
});
} else {
if (url.indexOf("http://") === -1 && url.indexOf("https://") === -1) {
url = `http://${url}`;
}
open(url);
}
}
const relation_id = ref('')
const activity_id = ref('')
const exchange_method = ref('')
@@ -311,6 +368,22 @@ export default defineComponent({
}, 2000);
return
}
//中奖跳转兑奖
if (data.data.is_winning == 1 && data.data.prize_type == 3) {
//结束赋值
title.value = data.data.prize.title
imgurl.value = data.data.prize.img_url
jump_link.value = data.data.prize.jump_link
exchange_method.value = data.data.prize.exchange_method
nextTick(() => {
prizeIndex.value = data.data.prize.index;
})
setTimeout(() => {
visible3.value = true
}, 2000);
return
}
//未中奖
if (data.data.is_winning == 0) {
nextTick(() => {
@@ -343,14 +416,17 @@ export default defineComponent({
useRoute,
visible,
imgurl,
jump_link,
visible1,
visible2,
visible3,
prizeList,
prizeIndex,
prize,
startTurns,
endTurns,
addinfor,
skipPrize,
priLists,
beganToDraw,
log_id,