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

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

@@ -1,271 +1,300 @@
<template> <template>
<div class="ui"> <div class="ui">
<div class="all"> <div class="all">
<div class="top"> <div class="top">
<Toolbar @back="back" @save="save" :title="title" /> <Toolbar @back="back" @save="save" @downloadScreenshot="downloadScreenshot" :title="title" />
</div> </div>
<div class="yo-container"> <div class="yo-container">
<div class="left"> <div class="left">
<TabListCommodity @clickThumb="clickThumbCommodity" @add="addCommodity" @remove="removeCommodity" /> <TabListCommodity @clickThumb="clickThumbCommodity" @add="addCommodity" @remove="removeCommodity" />
</div> </div>
<div class="yo-main"> <div class="yo-main">
<SceneSeparateTexturePreviewer ref="ss" :selCommodity="selCommodity" :selTexture="selTexture" @onLoadingCompletion="onLoadingCompletion" /> <SceneSeparateTexturePreviewer ref="ss" :selCommodity="selCommodity" :selTexture="selTexture" @onLoadingCompletion="onLoadingCompletion" />
</div> </div>
<div class="right"> <div class="right">
<TabListCommodityRelTexture :relCommodity="selCommodity" :selTexture="selTexture" @clickThumb="clickThumbTexture" <TabListCommodityRelTexture :relCommodity="selCommodity" :selTexture="selTexture" @clickThumb="clickThumbTexture"
@add="addTexture" @remove="removeTexture" /> @add="addTexture" @remove="removeTexture" />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- <CommodityUploader :isOpen="isOpenCommodityUploader" @close="closeCommodityUploader" <!-- <CommodityUploader :isOpen="isOpenCommodityUploader" @close="closeCommodityUploader"
@success="commodityAddSuccess" /> @success="commodityAddSuccess" />
<TextureUploader :isOpen="isOpenTextureUploader" @close="closeTextureUploader" @success="textureAddSuccess" <TextureUploader :isOpen="isOpenTextureUploader" @close="closeTextureUploader" @success="textureAddSuccess"
:relCommodityId="selCommodity ? selCommodity.id : null" /> --> :relCommodityId="selCommodity ? selCommodity.id : null" /> -->
</template> </template>
<script setup> <script setup>
// https://2x.antdv.com/docs/vue/getting-started // https://2x.antdv.com/docs/vue/getting-started
// https://share.lanhuapp.com/#/invite?sid=lXPuKlJa // https://share.lanhuapp.com/#/invite?sid=lXPuKlJa
import Toolbar from '../../shelves-vue/components/editor/Toolbar.vue' import Toolbar from '../../shelves-vue/components/editor/Toolbar.vue'
import TabListCommodity from '../../shelves-vue/components/editor/TabListCommodity.vue' import TabListCommodity from '../../shelves-vue/components/editor/TabListCommodity.vue'
import TabListCommodityRelTexture from '../../shelves-vue/components/editor/TabListCommodityRelTexture.vue' import TabListCommodityRelTexture from '../../shelves-vue/components/editor/TabListCommodityRelTexture.vue'
// import CommodityUploader from '../../shelves-vue/view/CommodityUploader.vue' // import CommodityUploader from '../../shelves-vue/view/CommodityUploader.vue'
// import TextureUploader from '../../shelves-vue/view/TextureUploader.vue' // import TextureUploader from '../../shelves-vue/view/TextureUploader.vue'
import SceneSeparateTexturePreviewer from '../../shelves-vue/components/SceneSeparateTexturePreviewer.vue' import SceneSeparateTexturePreviewer from '../../shelves-vue/components/SceneSeparateTexturePreviewer.vue'
</script> </script>
<script> <script>
import { updateMaterialCenter } from "../../../../api.js" import {downloadRes, updateMaterialCenter} from "../../../../api.js"
import common from "@/api/common.js"; import common from "@/api/common.js";
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
export default { export default {
props: { props: {
currentModelData: { currentModelData: {
type: Object, type: Object,
default: () => (null) default: () => (null)
}, },
title: { title: {
type: String, type: String,
default: "" default: ""
}, },
}, },
data() { data() {
return { return {
isOpenCommodityUploader: false, isOpenCommodityUploader: false,
isOpenTextureUploader: false, isOpenTextureUploader: false,
selCommodity: null, selCommodity: null,
selTexture: null, selTexture: null,
} }
}, },
methods: { methods: {
onLoadingCompletion(){ onLoadingCompletion(){
if(!this.currentModelData) return; if(!this.currentModelData) return;
var current = JSON.parse(JSON.stringify(this.currentModelData)) var current = JSON.parse(JSON.stringify(this.currentModelData))
this.selCommodity = current.commodity this.selCommodity = current.commodity
setTimeout(() => { setTimeout(() => {
this.selTexture = current.texture this.selTexture = current.texture
}, 100); }, 100);
}, },
back() { back() {
this.$router.go(-1) this.$router.go(-1)
}, },
async save(callback) { async save(callback) {
try{ try{
// create new ware // create new ware
if(!this.selCommodity) { if(!this.selCommodity) {
message.warning("请选择商品模型"); message.warning("请选择商品模型");
callback(); callback();
return; return;
} }
// if(!this.selTexture) { // if(!this.selTexture) {
// message.warning("请选择商品贴图"); // message.warning("请选择商品贴图");
// return; // return;
// } // }
var clone = { var clone = {
type: 1, type: 1,
commodity: this.selCommodity, commodity: this.selCommodity,
texture: this.selTexture, texture: this.selTexture,
urlThumb: this.selCommodity.urlThumb, urlThumb: this.selCommodity.urlThumb,
} }
console.log(clone) console.log(clone)
const blob = await this.$refs.ss.previewer_.snapshot(); const blob = await this.$refs.ss.previewer_.snapshot();
const res = await common.cosUpload3DCompress(blob); const res = await common.cosUpload3DCompress(blob);
await updateMaterialCenter({ await updateMaterialCenter({
id: this.$route.query.id, id: this.$route.query.id,
data: JSON.stringify(clone), data: JSON.stringify(clone),
simple_data: {}, simple_data: {},
version: new Date().getTime(), version: new Date().getTime(),
cover: res.url cover: res.url
}); });
this.$router.go(-1); this.$router.go(-1);
} }
catch(e){ catch(e){
console.log(e) console.log(e)
callback() callback()
} }
// this.$store.dispatch('wares/add', { // this.$store.dispatch('wares/add', {
// type: 1, // type: 1,
// commodity: this.selCommodity, // commodity: this.selCommodity,
// texture: this.selTexture, // texture: this.selTexture,
// urlThumb: this.selCommodity.urlThumb, // urlThumb: this.selCommodity.urlThumb,
// }).then(data2 => { // }).then(data2 => {
// }) // })
}, },
// //
addCommodity() { addCommodity() {
this.isOpenCommodityUploader = true this.isOpenCommodityUploader = true
}, },
clickThumbCommodity(itm) { clickThumbCommodity(itm) {
// console.log(itm) // console.log(itm)
this.selCommodity = itm this.selCommodity = itm
}, },
removeCommodity() { removeCommodity() {
this.selCommodity = null this.selCommodity = null
}, },
// //
// //
addTexture() { addTexture() {
this.isOpenTextureUploader = true this.isOpenTextureUploader = true
}, },
clickThumbTexture(itm) { clickThumbTexture(itm) {
this.selTexture = itm this.selTexture = itm
}, },
removeTexture() { removeTexture() {
this.selTexture = null this.selTexture = null
}, },
// //
closeCommodityUploader() { closeCommodityUploader() {
this.isOpenCommodityUploader = false this.isOpenCommodityUploader = false
}, },
commodityAddSuccess(data) { commodityAddSuccess(data) {
this.clickThumbCommodity(data) this.clickThumbCommodity(data)
}, },
closeTextureUploader() { closeTextureUploader() {
this.isOpenTextureUploader = false this.isOpenTextureUploader = false
}, },
textureAddSuccess(data) { textureAddSuccess(data) {
this.clickThumbTexture(data) this.clickThumbTexture(data)
}, },
}, async downloadScreenshot () {
}
try {
</script>
const blob = await this.$refs.ss.previewer_.snapshot();
<style scoped> // var blob = await viewerRef.value.viewer.snapshot();
div.ui { // console.log("props.title",this.title);
position: fixed; const data = await common.cosUpload(blob, this.title, "", () => {
width: 100vw; });
/* height: 100vh; */
} console.log("data--",data);
var url = data.url;
.all { var name = data.name;
height: 100vh;
/* background-color: beige; */ downloadRes(url, name, 'png');
} // 创建一个a标签并设置下载属性
// const link = document.createElement('a');
.yo-tabs { // link.href = url;
position: absolute; // link.target = "_blank";
top: 90px; // link.download = 'screenshot.png';
left: 24px; //
right: 24px; // // 模拟点击链接来触发下载
bottom: 20px; // link.click();
display: flex; }catch(e){
flex-direction: row; console.log(e)
flex: 1; }
flex-basis: auto;
box-sizing: border-box; }
min-width: 0;
border-radius: 6px; },
background: transparent; }
}
</script>
.yo-container {
position: absolute; <style scoped>
/* top: 135px; */ div.ui {
top: 90px; position: fixed;
left: 24px; width: 100vw;
right: 24px; /* height: 100vh; */
bottom: 20px; }
display: flex;
flex-direction: row; .all {
flex: 1; height: 100vh;
flex-basis: auto; /* background-color: beige; */
box-sizing: border-box; }
min-width: 0;
/* margin: 21px 24px; */ .yo-tabs {
border-radius: 0 6px 6px 6px; position: absolute;
background: #FFFFFF; top: 90px;
box-shadow: 0 10px 8px 0 rgba(0, 0, 0, 0.1); left: 24px;
} right: 24px;
bottom: 20px;
.yo-main { display: flex;
display: block; flex-direction: row;
flex: 1; flex: 1;
flex-basis: auto; flex-basis: auto;
overflow: auto; box-sizing: border-box;
box-sizing: border-box; min-width: 0;
padding: 0; border-radius: 6px;
} background: transparent;
}
.top {
/* background-color: burlywood; */ .yo-container {
height: auto; position: absolute;
padding: 0; /* top: 135px; */
} top: 90px;
left: 24px;
.left { right: 24px;
width: 280px; bottom: 20px;
background-color: #ffffff; display: flex;
} flex-direction: row;
flex: 1;
.main { flex-basis: auto;
padding: 0px; box-sizing: border-box;
} min-width: 0;
/* margin: 21px 24px; */
.right { border-radius: 0 6px 6px 6px;
width: 280px; background: #FFFFFF;
background-color: #ffffff; box-shadow: 0 10px 8px 0 rgba(0, 0, 0, 0.1);
} }
</style>
.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> <template>
<div class="container-previewer-1-"></div> <div class="container-previewer-1-"></div>
</template> </template>
<script> <script>
import { SeparateTexturePreviewer } from "../../../../lib/shelves.module" import { SeparateTexturePreviewer } from "../../../../lib/shelves.module"
// class Ref1 { // class Ref1 {
// constructor() { // constructor() {
// let current_ = null // let current_ = null
// this.setCurrent = v => { // this.setCurrent = v => {
// current_ = v // current_ = v
// } // }
// this.getCurrent = () => { // this.getCurrent = () => {
// return current_ // return current_
// } // }
// this.useCurrent = cb => { // this.useCurrent = cb => {
// if (current_) { // if (current_) {
// cb(current_) // cb(current_)
// } // }
// } // }
// } // }
// } // }
export default { export default {
props: ["isOpen", "selCommodity", "selTexture"], props: ["isOpen", "selCommodity", "selTexture"],
mounted() { mounted() {
console.log("## SeparateTexturePreviewer mounted", this.$el.clientWidth) console.log("## SeparateTexturePreviewer mounted", this.$el.clientWidth)
this.$nextTick(() => { this.$nextTick(() => {
console.log("## SeparateTexturePreviewer mounted - nt", this.$el.clientWidth) console.log("## SeparateTexturePreviewer mounted - nt", this.$el.clientWidth)
this.tryInitView() this.tryInitView()
}) })
}, },
watch: { watch: {
selCommodity(newVal, oldVal) { selCommodity(newVal, oldVal) {
if (this.previewer_) { if (this.previewer_) {
this.previewer_.selCommodity = newVal this.previewer_.selCommodity = newVal
// selCommodity 为 set 函数,其中异步的给 first_mat_ 赋值; // selCommodity 为 set 函数,其中异步的给 first_mat_ 赋值;
// 只有在 first_mat_ 被赋值后,才能添加纹理,但是没有 first_mat_ 被赋值后并没有回调, // 只有在 first_mat_ 被赋值后,才能添加纹理,但是没有 first_mat_ 被赋值后并没有回调,
// 所以,暂时加了一个定时器判断 first_mat_ 是否存在,并添加纹理; // 所以,暂时加了一个定时器判断 first_mat_ 是否存在,并添加纹理;
let maxIntervalTime = 30; // 如果 30 秒内,还没有 first_mat_ 的话,就放弃添加纹理 let maxIntervalTime = 30; // 如果 30 秒内,还没有 first_mat_ 的话,就放弃添加纹理
const timer = setInterval(() => { const timer = setInterval(() => {
if (this.previewer_.first_mat_ || maxIntervalTime <= 0) { if (this.previewer_.first_mat_ || maxIntervalTime <= 0) {
this.previewer_.selTexture = this.selTexture; this.previewer_.selTexture = this.selTexture;
clearInterval(timer); clearInterval(timer);
} }
maxIntervalTime -= 0.5; maxIntervalTime -= 0.5;
}, 500); }, 500);
} }
}, },
selTexture(newVal, oldVal) { selTexture(newVal, oldVal) {
if (this.previewer_) { if (this.previewer_) {
this.previewer_.selTexture = newVal this.previewer_.selTexture = newVal
} }
}, },
// brightness(oldV, newV) { // brightness(oldV, newV) {
// // console.log('#brightness', oldV, newV) // // console.log('#brightness', oldV, newV)
// if (this.previewer_) { // if (this.previewer_) {
// this.previewer_.brightness = newV // this.previewer_.brightness = newV
// } // }
// } // }
}, },
beforeUnmount() { beforeUnmount() {
console.log("## SeparateTexturePreviewer beforeUnmount") console.log("## SeparateTexturePreviewer beforeUnmount")
if (this.previewer_) { if (this.previewer_) {
this.previewer_.dispose() this.previewer_.dispose()
this.previewer_ = null this.previewer_ = null
} }
}, },
methods: { methods: {
tryInitView() { tryInitView() {
if (!this.previewer_) { if (!this.previewer_) {
// let search = new URLSearchParams(document.location.search) // let search = new URLSearchParams(document.location.search)
let container = this.$el let container = this.$el
// console.log(container.clientWidth, container.clientHeight) // console.log(container.clientWidth, container.clientHeight)
let v = new SeparateTexturePreviewer({ let v = new SeparateTexturePreviewer({
container, container,
prefixAsset: '/shelves-v5-asset', // v5, #20230104 prefixAsset: '/shelves-v5-asset', // v5, #20230104
}) })
v.on("loadingCompletion", () => { v.on("loadingCompletion", () => {
console.log('## SeparateTexturePreviewer loadingCompletion') console.log('## SeparateTexturePreviewer loadingCompletion')
this.$emit("onLoadingCompletion") this.$emit("onLoadingCompletion")
if (this.selTexture) { if (this.selTexture) {
v.selTexture = this.selTexture; v.selTexture = this.selTexture;
} }
}) })
v.startup() v.startup()
this.previewer_ = v this.previewer_ = v
} }
return this.previewer_ return this.previewer_
}, },
snapshot() { snapshot() {
if (this.previewer_) { if (this.previewer_) {
return this.previewer_.snapshot() return this.previewer_.snapshot()
} else { } else {
return null return null
} }
}, },
}, },
}; };
</script> </script>
<style scoped> <style scoped>
div.container-previewer-1- { div.container-previewer-1- {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
div.container-previewer-1-:focus { div.container-previewer-1-:focus {
outline: none; outline: none;
} }
div.container-previewer-1-:deep()canvas:focus { div.container-previewer-1-:deep()canvas:focus {
outline: none; outline: none;
} }
</style> </style>

View File

@@ -1,109 +1,125 @@
<template> <template>
<div class="tool-bar"> <div class="tool-bar">
<!-- <el-button class="yo-btn-rect yo-btn-back" type="primary" @click="$emit('back')"> <!-- <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-icon class="yo-icon"><img :src="IconBack" /></el-icon>
</el-button> --> </el-button> -->
<a-button class="yo-btn-back" type="text" @click="$emit('back')"> <a-button class="yo-btn-back" type="text" @click="$emit('back')">
<template #icon> <template #icon>
<LeftOutlined /> <LeftOutlined />
</template> </template>
{{props.title}} {{props.title}}
</a-button> </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> <a-button class="yo-btn-right" type="primary" @click="save" :loading="loading">
<img :src="SaveSvg" /> <template #icon>
</template> <img :src="SaveSvg" />
<span style="font-size: 15px;">保存</span> </template>
</a-button> <span style="font-size: 15px;">保存</span>
</div> </a-button>
</template> </div>
<script setup> </template>
// console.log(IconSelect)
import { SendOutlined, LeftOutlined } from '@ant-design/icons-vue' <script setup>
import { ref } from '@vue/reactivity'; // console.log(IconSelect)
import SaveSvg from '../../asset/icon2/save.svg' import { SendOutlined, LeftOutlined } from '@ant-design/icons-vue'
import { ref } from '@vue/reactivity';
const props = defineProps(["title"]); import SaveSvg from '../../asset/icon2/save.svg'
const $emit = defineEmits("save"); const props = defineProps(["title"]);
const loading = ref(false); const $emit = defineEmits("save");
const save = () => { const loading = ref(false);
loading.value = true;
$emit('save', () => { const save = () => {
loading.value = false; loading.value = true;
}); $emit('save', () => {
} loading.value = false;
});
</script> }
<style scoped> const downloadScreenshot = () => {
.el-button+.el-button { $emit('downloadScreenshot', () => {
margin-left: 0; });
} }
.tool-bar { </script>
display: flex;
height: 70px; <style scoped>
background: #FFFFFF; .el-button+.el-button {
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.0614); margin-left: 0;
} }
.yo-btn-right { .tool-bar {
position: absolute; display: flex;
right: 15px; height: 70px;
align-self: center; background: #FFFFFF;
height: 40px; box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.0614);
width: 100px; }
min-width: 10px;
line-height: 28px; .yo-btn-right {
color: #FFFFFF; position: absolute;
/* background: #1C6FFF; */ right: 15px;
background: #70B936; align-self: center;
border-color: #70B936; height: 40px;
font-size: 15px; width: 100px;
font-weight: 400; min-width: 10px;
border-radius: 6px; line-height: 28px;
letter-spacing: 2px; color: #FFFFFF;
/* padding: 4px 20px; */ /* background: #1C6FFF; */
} background: #70B936;
border-color: #70B936;
.yo-btn-right:hover { font-size: 15px;
border: #70B936; font-weight: 400;
} border-radius: 6px;
letter-spacing: 2px;
.yo-btn-right:focus { /* padding: 4px 20px; */
border: #70B936; }
}
.yo-btn-right:hover {
.yo-btn-right img { border: #70B936;
width: 24px; }
margin-right: 6px;
padding-bottom: 2px; .yo-btn-right:focus {
} border: #70B936;
}
.yo-btn-back {
position: absolute; .yo-btn-right img {
left: 15px; width: 24px;
align-self: center; margin-right: 6px;
height: 40px; padding-bottom: 2px;
min-width: 10px; }
/* line-height: 24px; */
color: #434343; .yo-btn-back {
font-size: 15px; position: absolute;
font-weight: 400; left: 15px;
letter-spacing: 2px; align-self: center;
/* padding: 4px 20px; */ height: 40px;
} min-width: 10px;
/* line-height: 24px; */
.yo-btn-back img { color: #434343;
width: 24px; font-size: 15px;
margin-right: 6px; font-weight: 400;
} letter-spacing: 2px;
</style> /* 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 SceneSeparateTexturePreviewer from "./3d/crossyo/shelves-vue/components/SceneSeparateTexturePreviewer.vue";
import { ref } from "@vue/reactivity"; import { ref } from "@vue/reactivity";
import { getMaterialsById } from "./api"; import {downloadRes, getMaterialsById} from "./api";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { regDelTinymceCreativeIframe } from "./utils/iframeEvent"; 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 route = useRoute();
const selCommodity = ref(null); const selCommodity = ref(null);
const selTexture = ref(null); const selTexture = ref(null);
const viewer = ref();
onMounted(() => { onMounted(() => {
regDelTinymceCreativeIframe(); regDelTinymceCreativeIframe();
// 在第二层组件的mounted钩子中将第三层组件的ref方法赋值给第二层组件的ref
// this.$refs.viewer.snapshot = this.$refs.thirdComponentRef.snapshot;
}); });
const onLoadingCompletion = async () => { 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); const data = JSON.parse(res.data.materials[0].space_json);
selCommodity.value = data.commodity; selCommodity.value = data.commodity;
@@ -35,7 +54,12 @@ const onLoadingCompletion = async () => {
}, 200); }, 200);
} }
//将数据暴漏出去给父组件用
defineExpose({
viewer
})
</script> </script>
<style> <style>
</style> </style>

View File

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

View File

@@ -1,24 +1,65 @@
<template> <template>
<a-modal v-model:visible="visible" title="3D产品模型" width="1000px" @ok="ok" :footer="null"> <a-modal v-model:visible="visible" width="1000px" @ok="ok" :footer="null">
<iframe v-if="visible" :src="url" frameborder="0" style="width: 100%; height: 500px;"></iframe> <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> </a-modal>
</template> </template>
<script setup> <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 { ref }=require("@vue/reactivity");
const visible = ref(false); const visible = ref(false);
const url = ref("") const url = ref("")
const data3d = ref();
defineExpose({ defineExpose({
show(data){ show(data){
data3d.value = data;
url.value = `/#/model3d-preview?id=${data.id}`; url.value = `/#/model3d-preview?id=${data.id}`;
visible.value = true; 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> </script>
<style> <style>
</style> </style>

View File

@@ -1,72 +1,76 @@
<template> <template>
<a-modal <a-modal
v-model:visible="sceneViewer.visible" v-model:visible="sceneViewer.visible"
title="场景预览" title="场景预览"
:maskClosable="false" :maskClosable="false"
:width="800" :width="800"
:footer="null" :footer="null"
> >
<div style="height: 500px"> <div style="height: 500px">
<SceneSurveyViewerPreview <SceneSurveyViewerPreview
v-if="sceneViewer.visible" v-if="sceneViewer.visible"
:shopData="sceneViewer.shopData" :shopData="sceneViewer.shopData"
:page="sceneViewer.page" :page="sceneViewer.page"
:page_shelves="sceneViewer.page_shelves" :page_shelves="sceneViewer.page_shelves"
:sceneAction="sceneViewer.sceneAction" :sceneAction="sceneViewer.sceneAction"
@onLoadingCompletion="onLoadingCompletion" @onLoadingCompletion="onLoadingCompletion"
@onFromSceneHoldToShelf="onFromSceneHoldToShelf" @onFromSceneHoldToShelf="onFromSceneHoldToShelf"
/> />
</div> </div>
</a-modal> </a-modal>
</template> </template>
<script setup> <script setup>
import SceneSurveyViewerPreview from "@/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview"; import SceneSurveyViewerPreview from "@/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview";
import { buildShopDataDemo } from "@/views/planetDesign/Design/components/config/config3d.utils"; import { buildShopDataDemo } from "@/views/planetDesign/Design/components/config/config3d.utils";
import { reactive, ref } from "@vue/reactivity"; import { reactive, ref } from "@vue/reactivity";
import common from "@/api/common";
const sceneViewer = reactive({ import {downloadRes} from "@/views/Creative/api";
visible: false,
shopData: null, const sceneViewer = reactive({
page: null, visible: false,
page_shelves: null, shopData: null,
sceneAction: null, page: null,
}); page_shelves: null,
sceneAction: null,
});
const onLoadingCompletion = () => {
sceneViewer.page_shelves = {
shelves: sceneViewer.shopData.shelves const onLoadingCompletion = () => {
}; sceneViewer.page_shelves = {
}; shelves: sceneViewer.shopData.shelves
};
const onFromSceneHoldToShelf = () => { };
sceneViewer.sceneAction = {
action: "hold_to_shelf", const onFromSceneHoldToShelf = () => {
}; sceneViewer.sceneAction = {
}; action: "hold_to_shelf",
};
defineExpose({ };
show(data) {
var json = JSON.parse(data.materials[0].space_json); defineExpose({
const shopData = buildShopDataDemo(json); show(data) {
console.log(shopData); var json = JSON.parse(data.materials[0].space_json);
if(shopData.type == "panorama") { const shopData = buildShopDataDemo(json);
shopData.panorama.url += "?real"; console.log(shopData);
shopData.panorama.urlSmall += "?real"; if(shopData.type == "panorama") {
} shopData.panorama.url += "?real";
if(shopData.type == "hall") { shopData.panorama.urlSmall += "?real";
shopData.hall.url += "?real"; }
shopData.hall.urlSmall += "?real"; if(shopData.type == "hall") {
} shopData.hall.url += "?real";
sceneViewer.shopData = shopData; shopData.hall.urlSmall += "?real";
sceneViewer.page = null; }
sceneViewer.visible = true; sceneViewer.shopData = shopData;
}, sceneViewer.page = null;
}); sceneViewer.visible = true;
},
</script> });
<style>
</style> </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="file-question" v-if="question_type === 18" :style="{width:data.width + 'px'}">
<div class="label">{{ content }}</div> <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> </div>
<!-- 图文题--> <!-- 图文题-->
@@ -49,11 +54,12 @@ const question_type = ref(null)
// https://stackoverflow.com/questions/15458876/check-if-a-string-is-html-or-not // 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 includeHtmlTag = computed(() =>/<\/?[a-z][\s\S]*>/i.test(content.value))
const shortTitle = computed(() => content.value ? content.value.slice(0, 40) : '') const shortTitle = computed(() => content.value ? content.value.slice(0, 40) : '')
const searchParams = ref({});
function download() { function download() {
const params = JSON.parse(JSON.stringify(props.search_params)) const params = JSON.parse(JSON.stringify(props.search_params))
const query = convertQueryToString(params) const query = convertQueryToString(params)
// console.log("serpar",params);
searchParams.value = params;
// downloadAnswerFile(props.sn, question_index.value, query).then(res => { // downloadAnswerFile(props.sn, question_index.value, query).then(res => {
// // const url = res.data.url // // const url = res.data.url
// // downloadFile(url) // // downloadFile(url)
@@ -72,7 +78,7 @@ const route = useRoute();
const downloadVisible = ref(false); const downloadVisible = ref(false);
// 下载中心 // 下载中心
function downloadCenter() { 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=>{ addDownloadCenter(props.sn,data).then(res=>{
store.dispatch('downloadCenter/changeCenterUrl',route.path) store.dispatch('downloadCenter/changeCenterUrl',route.path)
// downloadVisible.value = true // downloadVisible.value = true
@@ -110,7 +116,7 @@ watchEffect(() => {
display: flex; display: flex;
align-items: center; align-items: center;
.label { .label {
width: 50%; width: 40%;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import CustomTableHeaderCell from '@/views/DataAnalyse/components/CustomTableHeaderCell' import CustomTableHeaderCell from '@/views/DataAnalyse/components/CustomTableHeaderCell'
export default function renderCustomHeader(columns, sn ,search_params) { export default function renderCustomHeader(columns, sn ,search_params) {
const customHeaders = ref([]) const customHeaders = ref([])
function renderCell(data, sn, search_params) { function renderCell(data, sn, search_params) {
@@ -12,12 +12,25 @@ export default function renderCustomHeader(columns, sn ,search_params) {
customHeaders.value = data.map(item => { customHeaders.value = data.map(item => {
return { return {
...item, ...item,
title: renderCell(item, sn, search_params) title: renderCell(item, sn, search_params.value)
} }
}) })
} }
}, { }, {
immediate: true 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 permission = inject("permission");
const searchParams = inject("searchParams"); const searchParams = inject("searchParams");
console.log('searchParams',searchParams);
const tableSource = ref([]); const tableSource = ref([]);
const columns = ref([ const columns = ref([
@@ -138,7 +138,12 @@ export default defineComponent({
async function handleClick() { async function handleClick() {
const sn = props.sn; const sn = props.sn;
const question_index = props.data.question_index; 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=>{ addDownloadCenter(sn,data).then(res=>{
store.dispatch('downloadCenter/changeCenterUrl',route.path) store.dispatch('downloadCenter/changeCenterUrl',route.path)
store.dispatch('downloadCenter/changeCenterShow',true) store.dispatch('downloadCenter/changeCenterShow',true)

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="random-list"> <div class="random-list">
<div class="random-list-add"> <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>
<div <div
class="random-list-show" class="random-list-show"
@@ -153,6 +153,8 @@ export default {
const questions = ref(props.data.questions); const questions = ref(props.data.questions);
const logics = ref(props.data.logics); const logics = ref(props.data.logics);
const deal_questions = ref(props.data.deal_questions); const deal_questions = ref(props.data.deal_questions);
const isAdd = ref(false); //是否可以点击添加随机按钮 只有 当存在未填写完成的题组时,【添加随机】按钮置灰,即不可点击
onMounted(async () => { onMounted(async () => {
var data= await getProcess({ var data= await getProcess({
sn: route.query.sn sn: route.query.sn
@@ -201,6 +203,8 @@ export default {
}; };
const addRaddom = () => { const addRaddom = () => {
isAdd.value = true;
options.value.push({ options.value.push({
title: `随机${options.value.length + 1}`, title: `随机${options.value.length + 1}`,
num: undefined, num: undefined,
@@ -229,6 +233,8 @@ export default {
document.getElementById('logicalContent').scrollTop = document.getElementById('logicalContent').scrollTop =
options.value.length * 775; options.value.length * 775;
}); });
// console.log('isAdd--'+isAdd)
}; };
const addoptions = (item) => { const addoptions = (item) => {
@@ -303,9 +309,11 @@ export default {
}; };
const onStartChange = () => { const onStartChange = () => {
console.log("star")
edit(); edit();
}; };
const onEndChange = () => { const onEndChange = () => {
console.log("edncha")
edit(); 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 { return {
options, options,
addRaddom, addRaddom,
@@ -742,6 +771,7 @@ export default {
onEndChange, onEndChange,
onClickOutside, onClickOutside,
emptyImage, emptyImage,
isAdd
}; };
} }
}; };

View File

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

View File

@@ -100,6 +100,36 @@
</a-modal> </a-modal>
</div> </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> </div>
</template> </template>
@@ -219,6 +249,7 @@ export default defineComponent({
const visible = ref(false) const visible = ref(false)
const visible1 = ref(false) const visible1 = ref(false)
const visible2 = ref(false) const visible2 = ref(false)
const visible3 = ref(false)
const showcj = ref(false) const showcj = ref(false)
const index = ref('') const index = ref('')
// 转盘上要展示的奖品数据 // 转盘上要展示的奖品数据
@@ -245,10 +276,12 @@ export default defineComponent({
visible.value = false visible.value = false
visible1.value = false visible1.value = false
visible2.value = false visible2.value = false
visible3.value = false
}; };
const log_id = ref('') const log_id = ref('')
const imgurl = ref('') const imgurl = ref('')
const title = ref('') const title = ref('')
const jump_link = ref('') //跳转兑奖的,跳转链接地址
const addinfor = () => { const addinfor = () => {
visible1.value = false visible1.value = false
router.push({ 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 relation_id = ref('')
const activity_id = ref('') const activity_id = ref('')
const exchange_method = ref('') const exchange_method = ref('')
@@ -311,6 +368,22 @@ export default defineComponent({
}, 2000); }, 2000);
return 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) { if (data.data.is_winning == 0) {
nextTick(() => { nextTick(() => {
@@ -343,14 +416,17 @@ export default defineComponent({
useRoute, useRoute,
visible, visible,
imgurl, imgurl,
jump_link,
visible1, visible1,
visible2, visible2,
visible3,
prizeList, prizeList,
prizeIndex, prizeIndex,
prize, prize,
startTurns, startTurns,
endTurns, endTurns,
addinfor, addinfor,
skipPrize,
priLists, priLists,
beganToDraw, beganToDraw,
log_id, log_id,