Merge branch 'fix-vue3-left-bug'

This commit is contained in:
田香琪
2026-07-10 13:32:53 +08:00
23 changed files with 302 additions and 760 deletions

View File

@@ -10,6 +10,7 @@
<script> <script>
import { getIconUrl } from "@/assets/iconfont/iconMap"; import { getIconUrl } from "@/assets/iconfont/iconMap";
import storage from "@/plugins/storage.js";
export default { export default {
name: "fixed-index", name: "fixed-index",
@@ -19,22 +20,26 @@ export default {
{ {
icon:"user", icon:"user",
label:"会员中心", label:"会员中心",
path:"/home" path:"/home",
requireLogin: true,
}, },
{ {
icon:"carts", icon:"carts",
label:"购物车", label:"购物车",
path:"/cart" path:"/cart",
requireLogin: true,
}, },
{ {
icon:"notification", icon:"notification",
label:"消息", label:"消息",
path:"/home/MsgList" path:"/home/MsgList",
requireLogin: true,
}, },
{ {
icon:"collage", icon:"collage",
label:"收藏", label:"收藏",
path:"/home/Favorites" path:"/home/Favorites",
requireLogin: true,
}, },
{ {
icon:"back", icon:"back",
@@ -71,13 +76,37 @@ export default {
this.isScrolling = false; this.isScrolling = false;
} }
}, },
handleClickIcon(val){ isLoggedIn () {
if(val.path === 'back'){ const rawUserInfo = storage.getItem('userInfo');
this.scrollToTop() if (rawUserInfo) {
}else{ try {
this.$router.push(val.path) return !!JSON.parse(rawUserInfo).username;
} catch {
return false;
} }
} }
return !!storage.getItem('accessToken');
},
goLogin (rePath) {
this.$router.push({
path: '/login',
query: {
rePath,
query: JSON.stringify(this.$route.query || {}),
},
});
},
handleClickIcon (val) {
if (val.path === 'back') {
this.scrollToTop();
return;
}
if (val.requireLogin && !this.isLoggedIn()) {
this.goLogin(val.path);
return;
}
this.$router.push(val.path);
},
} }
} }
</script> </script>

View File

@@ -124,9 +124,27 @@ export default {
} }
}, },
methods: { methods: {
goToPay() { // 跳转购物车 goToPay() {
let url = this.$router.resolve({ if (!this.userInfo.username) {
path: '/cart' Modal.confirm({
title: '温馨提示',
content: '请登录后执行此操作',
okText: '立即登录',
cancelText: '取消',
onOk: () => {
this.$router.push({
path: '/login',
query: {
rePath: '/cart',
query: JSON.stringify(this.$route.query || {}),
},
});
},
});
return;
}
const url = this.$router.resolve({
path: '/cart',
}); });
window.open(url.href, '_blank'); window.open(url.href, '_blank');
}, },
@@ -169,16 +187,29 @@ export default {
} }
}, },
shopEntry() { shopEntry() {
// 店铺入驻
if (storage.getItem('accessToken')) { if (storage.getItem('accessToken')) {
let routeUrl = this.$router.resolve({ const routeUrl = this.$router.resolve({
path: '/shopEntry', path: '/shopEntry',
query: {id: 1} query: { id: 1 },
}); });
window.open(routeUrl.href, '_blank'); window.open(routeUrl.href, '_blank');
} else { return;
this.$router.push('login');
} }
Modal.confirm({
title: '温馨提示',
content: '请登录后执行此操作',
okText: '立即登录',
cancelText: '取消',
onOk: () => {
this.$router.push({
path: '/login',
query: {
rePath: '/shopEntry',
query: JSON.stringify({ id: 1 }),
},
});
},
});
}, },
handleCartDropdownVisible(visible) { handleCartDropdownVisible(visible) {
if (visible) { if (visible) {

View File

@@ -51,7 +51,7 @@
</div> --> </div> -->
</div> </div>
<div v-else class="flex flex-a-c "> <div v-else class="flex flex-a-c ">
<div class="btns" @click="$router.push('login')">登录</div> <div class="btns" @click="goLogin">登录</div>
<div class="btns sign-up" @click="$router.push('signUp')">注册</div> <div class="btns sign-up" @click="$router.push('signUp')">注册</div>
</div> </div>
@@ -84,6 +84,7 @@
<script> <script>
import { Modal } from "@/utils/message";
import storage from "@/plugins/storage"; import storage from "@/plugins/storage";
import config from "@/config"; import config from "@/config";
import defaultAvatar from "@/assets/images/default.png"; import defaultAvatar from "@/assets/images/default.png";
@@ -182,10 +183,16 @@ export default {
query: Object.fromEntries(new URLSearchParams(search)), query: Object.fromEntries(new URLSearchParams(search)),
}; };
}, },
// 快捷跳转中心 isMemberRoute(location) {
entryControl(val) { return location.path.startsWith("/home/") || location.path === "/cart";
const location = this.resolveRoute(val.path); },
if (location.path.startsWith("/home/") && !storage.getItem("userInfo")) { promptLoginThenNavigate(location) {
Modal.confirm({
title: "温馨提示",
content: "请登录后执行此操作",
okText: "立即登录",
cancelText: "取消",
onOk: () => {
this.$router.push({ this.$router.push({
path: "/login", path: "/login",
query: { query: {
@@ -193,6 +200,17 @@ export default {
query: JSON.stringify(location.query || {}), query: JSON.stringify(location.query || {}),
}, },
}); });
},
});
},
goLogin() {
this.$router.push("/login");
},
// 快捷跳转中心
entryControl(val) {
const location = this.resolveRoute(val.path);
if (this.isMemberRoute(location) && !storage.getItem("userInfo")) {
this.promptLoginThenNavigate(location);
return; return;
} }
const url = this.$router.resolve(location); const url = this.$router.resolve(location);

View File

@@ -57,6 +57,7 @@
</template> </template>
<script> <script>
import { Modal } from "@/utils/message"; import { Modal } from "@/utils/message";
import storage from "@/plugins/storage";
import { couponList, receiveCoupon } from "@/api/member.js"; import { couponList, receiveCoupon } from "@/api/member.js";
export default { export default {
data() { data() {
@@ -115,6 +116,26 @@ export default {
}, },
// 领取优惠券 // 领取优惠券
receive(item) { receive(item) {
const userInfo = storage.getItem("userInfo");
const isLogin = userInfo && JSON.parse(userInfo).username;
if (!isLogin) {
Modal.confirm({
title: "温馨提示",
content: "请登录后执行此操作",
okText: "立即登录",
cancelText: "取消",
onOk: () => {
this.$router.push({
path: "/login",
query: {
rePath: this.$route.path,
query: JSON.stringify(this.$route.query),
},
});
},
});
return;
}
receiveCoupon(item.id) receiveCoupon(item.id)
.then((res) => { .then((res) => {
if (!res || !res.success) return; if (!res || !res.success) return;

View File

@@ -15,7 +15,7 @@
ref="formRegist" ref="formRegist"
:model="formRegist" :model="formRegist"
:rules="ruleInline" :rules="ruleInline"
style="width:300px;" class="signup-form"
> >
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input
@@ -66,7 +66,7 @@
>注册</el-button >注册</el-button
> >
</el-form-item> </el-form-item>
<el-form-item><span class="color999 ml_20">点击注册表示您同意<router-link to="/article?id=1371992704333905920" target="_blank">商城用户协议</router-link></span></el-form-item> <el-form-item><span class="color999">点击注册表示您同意<router-link to="/article?id=1371992704333905920" target="_blank">商城用户协议</router-link></span></el-form-item>
</el-form> </el-form>
<!-- 拼图验证码 --> <!-- 拼图验证码 -->
<Verify <Verify
@@ -240,7 +240,15 @@ export default {
margin: 0 auto; margin: 0 auto;
width: 600px; width: 600px;
background-color: #fff; background-color: #fff;
padding: 20px 150px; padding: 20px 40px;
display: flex;
flex-direction: column;
align-items: center;
.signup-form {
width: 300px;
}
.login-btn{ .login-btn{
position: absolute; position: absolute;
right: 20px; right: 20px;
@@ -250,8 +258,9 @@ export default {
.verify-con{ .verify-con{
position: absolute; position: absolute;
left: 140px; left: 50%;
top: 80px; top: 80px;
transform: translateX(-50%);
z-index: 10; z-index: 10;
} }

View File

@@ -47,6 +47,7 @@
<script> <script>
import { Message } from "@/utils/message"; import { Message } from "@/utils/message";
import { editMemberInfo } from '@/api/account.js'; import { editMemberInfo } from '@/api/account.js';
import { getMemberMsg } from '@/api/login.js';
import { commonUrl } from '@/plugins/request.js'; import { commonUrl } from '@/plugins/request.js';
import storage from '@/plugins/storage.js'; import storage from '@/plugins/storage.js';
import { User } from '@element-plus/icons-vue'; import { User } from '@element-plus/icons-vue';
@@ -64,11 +65,44 @@ export default {
} }
}, },
mounted () { mounted () {
this.formItem = JSON.parse(storage.getItem('userInfo'))
this.formItem.birthday = this.normalizeBirthday(this.formItem.birthday)
this.accessToken.accessToken = storage.getItem('accessToken'); this.accessToken.accessToken = storage.getItem('accessToken');
this.loadUserInfo();
}, },
methods: { methods: {
loadUserInfo () {
const rawUserInfo = storage.getItem('userInfo');
if (rawUserInfo) {
this.applyUserInfo(JSON.parse(rawUserInfo));
return;
}
if (!storage.getItem('accessToken')) {
this.redirectToLogin();
return;
}
getMemberMsg().then(res => {
if (res.success && res.result) {
storage.setItem('userInfo', res.result);
this.applyUserInfo(res.result);
} else {
this.redirectToLogin();
}
}).catch(() => {
this.redirectToLogin();
});
},
applyUserInfo (userInfo) {
this.formItem = { ...userInfo };
this.formItem.birthday = this.normalizeBirthday(this.formItem.birthday);
},
redirectToLogin () {
this.$router.push({
path: '/login',
query: {
rePath: this.$route.path,
query: JSON.stringify(this.$route.query || {}),
},
});
},
normalizeBirthday (value) { normalizeBirthday (value) {
if (!value) return '' if (!value) return ''
if (value instanceof Date) return value if (value instanceof Date) return value

View File

@@ -182,7 +182,7 @@
}}</span></span> }}</span></span>
<span class="describe">{{ item.consumeThreshold }}元可用</span> <span class="describe">{{ item.consumeThreshold }}元可用</span>
</div> </div>
<p>使用范围{{ useScope(item.scopeType) }}</p> <p>使用范围{{ useScope(item.scopeType, item.storeName) }}</p>
<p>有效期{{ item.endTime }}</p> <p>有效期{{ item.endTime }}</p>
</div> </div>
<img class="used" v-if="usedCouponId.includes(item.id)" src="../../assets/images/geted.png" alt="" /> <img class="used" v-if="usedCouponId.includes(item.id)" src="../../assets/images/geted.png" alt="" />
@@ -861,8 +861,10 @@ export default {
}); });
}, },
// 优惠券可用范围 // 优惠券可用范围
useScope(type) { useScope(type, storeName) {
let shop = "平台";
let goods = "全部商品"; let goods = "全部商品";
if (storeName !== "platform") shop = storeName;
switch (type) { switch (type) {
case "ALL": case "ALL":
goods = "全部商品"; goods = "全部商品";
@@ -874,7 +876,7 @@ export default {
goods = "部分分类商品"; goods = "部分分类商品";
break; break;
} }
return `${goods}可用`; return `${shop}${goods}可用`;
}, },
}, },
}; };
@@ -1380,6 +1382,7 @@ export default {
.coupon-item { .coupon-item {
width: 280px; width: 280px;
height: 125px; height: 125px;
margin-left: 0;
margin-right: 10px; margin-right: 10px;
margin-bottom: 10px; margin-bottom: 10px;
overflow: hidden; overflow: hidden;
@@ -1470,6 +1473,10 @@ export default {
.coupon-list { .coupon-list {
max-height: 260px; max-height: 260px;
overflow: scroll; overflow: scroll;
padding: 0;
margin: 0;
list-style: none;
justify-content: flex-start;
} }
.pay-gcc-module { .pay-gcc-module {

View File

@@ -51,7 +51,13 @@ module.exports = {
minSize: 20000, minSize: 20000,
cacheGroups: { cacheGroups: {
vendor: { vendor: {
test: /[\\/]node_modules[\\/]/, test(module) {
if (!module.context) return false;
if (/[\\/]node_modules[\\/]vue-qr[\\/]/.test(module.context)) {
return false;
}
return /[\\/]node_modules[\\/]/.test(module.context);
},
name(module) { name(module) {
const match = const match =
module.context && module.context &&

View File

@@ -176,6 +176,13 @@ export const addMemberGroupUsers = (groupId, memberIds) => {
}); });
}; };
export const setMemberUserGroups = (memberId, groupIds) => {
const ids = Array.isArray(groupIds) ? groupIds : groupIds ? [groupIds] : [];
return postRequest(`/member/memberGroup/user/${memberId}/groups`, {
groupIds: ids.join(","),
});
};
// 客户等级 // 客户等级
export const getMemberGradeByPage = (params) => { export const getMemberGradeByPage = (params) => {
return getRequest("/member/memberGrade/getByPage"); return getRequest("/member/memberGrade/getByPage");

View File

@@ -174,7 +174,7 @@ export default {
} }
.active { .active {
color: $theme_color; color: var(--el-color-primary);
position: relative; position: relative;
} }
@@ -185,6 +185,6 @@ export default {
left: 0; left: 0;
width: 100%; width: 100%;
height: 3px; height: 3px;
background: $theme_color; background: var(--el-color-primary);
} }
</style> </style>

View File

@@ -95,3 +95,13 @@
color: #c0c4cc; color: #c0c4cc;
cursor: not-allowed; cursor: not-allowed;
} }
/* 顶部路由加载条(与商家后台一致) */
#nprogress .bar {
height: 2x;
background: var(--el-color-primary, #409eff);
}
#nprogress .peg {
box-shadow: 0 0 4px var(--el-color-primary, #409eff), 0 0 2px var(--el-color-primary, #409eff);
}

View File

@@ -468,17 +468,27 @@ export default {
this.$refs.memberGroupForm.validate((valid) => { this.$refs.memberGroupForm.validate((valid) => {
if (!valid) return; if (!valid) return;
const memberIds = this.selectedRows.map((item) => item.id); const memberIds = this.selectedRows.map((item) => item.id);
const groupId = this.memberGroupForm.groupId;
this.memberGroupLoading = true; this.memberGroupLoading = true;
API_Member.addMemberGroupUsers(this.memberGroupForm.groupId, memberIds).then((res) => { Promise.all(
memberIds.map((memberId) => API_Member.setMemberUserGroups(memberId, [groupId]))
)
.then((results) => {
this.memberGroupLoading = false; this.memberGroupLoading = false;
if (res && res.success) { const failed = results.find((res) => !res || !res.success);
if (failed) {
ElMessage.error(failed.message || "设置失败");
return;
}
ElMessage.success("设置成功"); ElMessage.success("设置成功");
this.memberGroupFlag = false; this.memberGroupFlag = false;
this.selectedRows = []; this.selectedRows = [];
this.clearSelection(); this.clearSelection();
} else if (res && res.message) { this.getData();
ElMessage.error(res.message); })
} .catch(() => {
this.memberGroupLoading = false;
ElMessage.error("设置失败,请稍后重试");
}); });
}); });
}, },

View File

@@ -90,7 +90,7 @@ export default {
this.hotWordsChart.tooltip({ this.hotWordsChart.tooltip({
showMarkers: false, showMarkers: false,
}); });
this.hotWordsChart.interval().position("keywords*score").color("#f59b99"); this.hotWordsChart.interval().position("keywords*score").color("#409EFF");
this.hotWordsChart.interaction("element-active"); this.hotWordsChart.interaction("element-active");
this.hotWordsChart.render(); this.hotWordsChart.render();

View File

@@ -162,12 +162,20 @@
<el-form-item> <el-form-item>
<div style="color: grey">主图仅支持pngjpgjpeg格式宽高至少600*600px大小2M内可拖拽调整主图顺序</div> <div style="color: grey">主图仅支持pngjpgjpeg格式宽高至少600*600px大小2M内可拖拽调整主图顺序</div>
</el-form-item> </el-form-item>
<el-form-item class="form-item-view-el" label="主图视频" prop="goodsVideo"> <el-form-item
class="form-item-view-el goods-video-form-item"
:class="{ 'goods-video-form-item--multi': baseInfoForm.goodsVideo }"
label="主图视频"
prop="goodsVideo"
>
<div class="goods-video"> <div class="goods-video">
<div v-if="baseInfoForm.goodsVideo" class="goods-video-preview"> <div v-if="baseInfoForm.goodsVideo" class="goods-video-preview">
<video :src="baseInfoForm.goodsVideo" class="video" controls style="max-width: 300px;" /> <video :src="baseInfoForm.goodsVideo" class="video" controls style="max-width: 300px;" />
</div> </div>
<div class="goods-video-actions"> <div
class="goods-video-actions"
:class="{ 'goods-video-actions--with-preview': baseInfoForm.goodsVideo }"
>
<el-upload <el-upload
:action="uploadFileUrl" :action="uploadFileUrl"
:headers="{ ...accessToken }" :headers="{ ...accessToken }"
@@ -2365,16 +2373,32 @@ export default {
/* .tox-notifications-container{ /* .tox-notifications-container{
display: none !important; display: none !important;
} */ } */
.goods-video-label { .goods-video-form-item {
width: 120px; align-items: center;
text-align: right; }
padding: 10px 12px 10px 0;
.goods-video-form-item--multi {
align-items: flex-start;
}
.goods-video-form-item--multi :deep(.el-form-item__label) {
padding-top: 8px;
}
.goods-video-form-item :deep(.el-form-item__content) {
display: flex;
align-items: center;
}
.goods-video-form-item--multi :deep(.el-form-item__content) {
align-items: flex-start;
} }
.goods-video { .goods-video {
align-items: flex-start; align-items: flex-start;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%;
} }
.goods-video-preview { .goods-video-preview {
@@ -2386,7 +2410,17 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
margin-top: 6px; min-height: 32px;
}
.goods-video-actions--with-preview {
margin-top: 8px;
}
.goods-video-actions :deep(.el-upload) {
display: inline-flex;
align-items: center;
vertical-align: middle;
} }
.mb-10 { .mb-10 {

View File

@@ -174,7 +174,7 @@ export default {
} }
.active { .active {
color: $theme_color; color: var(--el-color-primary);
position: relative; position: relative;
} }
@@ -185,6 +185,6 @@ export default {
left: 0; left: 0;
width: 100%; width: 100%;
height: 3px; height: 3px;
background: $theme_color; background: var(--el-color-primary);
} }
</style> </style>

View File

@@ -1,133 +0,0 @@
<template>
<div v-if="templateShow">
<el-form :model="form" label-width="120px">
<el-form-item label="每日场次设置">
<el-row :gutter="16" class="row">
<el-col
v-for="(item, index) in times"
:key="index"
:span="3"
class="time-item"
>
<div class="time" :class="{ active: item.check }" @click="handleClickTime(item, index)">
{{ item.time }}:00
</div>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="秒杀规则">
<el-input
v-model="form.seckillRule"
type="textarea"
:autosize="{ minRows: 4 }"
placeholder="申请规则"
clearable
style="width: 360px"
/>
</el-form-item>
<el-form-item>
<div class="foot-btn">
<el-button @click="closeCurrentPage">返回</el-button>
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
</div>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getSetting, setSetting } from "@/api/index";
export default {
data() {
return {
templateShow: false,
submitLoading: false,
times: [],
form: {
seckillRule: "",
},
};
},
mounted() {
this.init();
},
methods: {
closeCurrentPage() {
this.$store.commit("removeTag", "manager-seckill-add");
localStorage.pageOpenedList = JSON.stringify(this.$store.state.app.pageOpenedList);
this.$router.go(-1);
},
async handleSubmit() {
const hours = this.times
.filter((item) => item.check)
.map((item) => item.time)
.join(",");
const result = await setSetting("SECKILL_SETTING", {
seckillRule: this.form.seckillRule,
hours,
});
if (result.success) {
this.$Message.success("设置成功!");
this.init();
}
},
async init() {
const result = await getSetting("SECKILL_SETTING");
if (result.success) {
this.templateShow = true;
this.form.seckillRule = result.result.seckillRule;
this.times = [];
for (let i = 0; i < 24; i++) {
let matched = false;
if (result.result.hours) {
const way = result.result.hours.split(",");
way.forEach((hours) => {
if (hours == i) {
this.times.push({ time: i, check: true });
matched = true;
}
});
}
if (!matched) {
this.times.push({ time: i, check: false });
}
}
}
},
handleClickTime(val) {
val.check = !val.check;
},
},
};
</script>
<style scoped lang="scss">
.row {
width: 50%;
}
.foot-btn {
margin-left: 10px;
display: flex;
gap: 8px;
}
.active {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
color: #fff;
background: $theme_color !important;
}
.time {
width: 100%;
cursor: pointer;
transition: 0.35s;
border-radius: 0.8em;
justify-content: center;
align-items: center;
display: flex;
background: #f3f5f7;
height: 50px;
font-size: 15px;
}
.time-item {
margin: 8px 0;
}
</style>

View File

@@ -1,216 +0,0 @@
<template>
<div class="model-view">
<div class="model-view-content">
<div class="content">
<div class="wap-title">??</div>
<div class="draggable">
<!-- ?? -->
<div class="full-shadow" v-if="type == 'full'">
<img :src="advertising[0].img" alt="" />
</div>
</div>
</div>
</div>
<div class="model-config">
<div class="decorate">
<div class="decorate-title">????</div>
<div class="decorate-list">
<div
class="decorate-item"
v-for="(item, index) in advertising"
:key="index"
>
<div class="decorate-item-title">
<div>??</div>
</div>
<div class="decorate-item-box">
<!-- ???? -->
<div class="decorate-view">
<div class="decorate-view-title">????</div>
<div>
<img class="show-image" :src="item.img" alt />
<input
type="file"
class="hidden-input"
@change="changeFile(item, index)"
ref="files"
:id="'files' + index"
/>
<div class="tips">
????
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<el-button
size="small"
@click="handleClickFile(item, index)"
plain
type="primary"
>????</el-button
>
</div>
</div>
<!-- ???? -->
<div class="decorate-view">
<div class="decorate-view-title">????</div>
<div>
<el-button
plain
type="primary"
size="small"
@click="clickLink(item)"
>????</el-button
>
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">??????</div>
<div>
<el-tag :type="result.pageShow === 'OPEN' ? 'success' : 'danger'">
{{ result.pageShow === "OPEN" ? "??" : "??" }}
</el-tag>
</div>
</div>
</div>
</div>
</div>
<!-- <el-button type="primary" @click="addDecorate()" ghost>??</el-button> -->
<liliDialog ref="liliDialog" @selectedLink="selectedLink" :types="linkType"></liliDialog>
</div>
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
<ossManage @callback="callbackSelected" :is-component="true" :initialize="picModelFlag" :max-select="1" ref="ossManage" />
</el-dialog>
</div>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
import * as API_Other from "@/api/other.js";
export default {
components: {
ossManage,
},
data() {
return {
result:"",
picModelFlag: false, //?????
type: "full", // ????
//????
advertising: [
{
img:
"https://st-gdx.dancf.com/gaodingx/0/uxms/design/20200903-182035-5e87.png?x-oss-process=image/resize,w_932/interlace,1,image/format,webp",
size: "750*1624",
},
],
selectedLinks: {},
linkType: "", // ????
};
},
watch: {
advertising: {
handler(val) {
this.$store.state.openStyleStore = val;
console.log(
"this.$store.state.openStyleStore",
this.$store.state.openStyleStore
);
},
deep: true,
},
},
mounted() {
this.openPage();
},
methods: {
openPage() {
const alertType = this.$route.query.pagetype;
const pageType = {
INDEX: "INDEX",
ALERT: "OPEN_SCREEN_PAGE",
OPEN_SCREEN_ANIMATION: "OPEN_SCREEN_ANIMATION",
}[alertType ? alertType : "INDEX"];
API_Other.getOpenHomeData(pageType).then((res) => {
this.$store.state.openStoreId = res.result.id;
if (res.result.pageData) {
this.advertising = [JSON.parse(res.result.pageData)];
}
this.result = res.result
});
},
// ????
clickLink(item) {
this.$refs.liliDialog.open('link')
},
// ???????
selectedLink(val) {
this.selectedLinks.url = val;
this.advertising[0].config = val;
},
// ??????
handleClickFile() {
this.picModelFlag = true;
this.$nextTick(() => {
if (this.$refs.ossManage) {
this.$refs.ossManage.selectImage = true;
}
});
}, // ???????
callbackSelected(val) {
this.picModelFlag = false;
if (!val?.url) return;
this.advertising[0].img = val.url;
}
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
@import "./decorate.scss";
.decorate-radio {
margin: 10px 0;
}
.window-shadow,
.full-shadow {
display: flex;
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
left: 0;
align-items: center;
justify-content: center;
}
.window-shadow {
> img {
width: 306px;
height: 418px;
}
}
.full-shadow {
> img {
width: 100%;
height: 100%;
}
}
.draggable {
position: relative;
}
.btn-item {
> img {
margin: 4px 0;
border-radius: 50%;
width: 30px;
height: 30px;
}
}
</style>

View File

@@ -1,233 +0,0 @@
<template>
<div class="model-view">
<div class="model-view-content">
<div class="content">
<div class="wap-title">首页</div>
<div class="draggable">
<!-- 弹窗广告 -->
<div class="window-shadow">
<img :src="advertising[0].img" alt="" />
</div>
</div>
</div>
</div>
<div class="model-config">
<div class="decorate">
<div class="decorate-title">弹窗广告</div>
<div class="decorate-list">
<div
class="decorate-item"
v-for="(item, index) in advertising"
:key="index"
>
<div class="decorate-item-title">
<div>设置</div>
</div>
<div class="decorate-item-box">
<!-- 选择照片 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<img class="show-image" :src="item.img" alt />
<input
type="file"
class="hidden-input"
@change="changeFile(item, index)"
ref="files"
:id="'files' + index"
/>
<div class="tips">
建议尺寸
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<el-button
size="small"
@click="handleClickFile(item, index)"
plain
type="primary"
>选择链接</el-button
>
</div>
</div>
<!-- 选择连接 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<el-button
plain
type="primary"
size="small"
@click="clickLink(item)"
>选择链接</el-button
>
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">当前页面状态</div>
<div>
<el-tag :type="result.pageShow === 'OPEN' ? 'success' : 'danger'">
{{ result.pageShow === "OPEN" ? "开启" : "关闭" }}
</el-tag>
</div>
</div>
</div>
</div>
</div>
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
:types="linkType"
></liliDialog>
</div>
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
<ossManage @callback="callbackSelected" :is-component="true" :initialize="picModelFlag" :max-select="1" ref="ossManage" />
</el-dialog>
</div>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
import * as API_Other from "@/api/other.js";
export default {
components: {
ossManage,
},
data() {
return {
result:"",
picModelFlag: false, //图片选择器
type: "full", // 展示方式
//全屏广告
advertising: [
{
img:
"https://shopro-1253949872.file.myqcloud.com/uploads/20200704/9136ecddcddf6607184fab689207e7e3.png",
size: "612*836",
},
],
linkType: "", // 选择类型
selectedLinks: {},
};
},
watch: {
advertising: {
handler(val) {
this.$store.state.openStyleStore = val;
console.log(
"this.$store.state.openStyleStore",
this.$store.state.openStyleStore
);
},
deep: true,
},
},
mounted() {
this.openPage();
},
methods: {
// 回调选择的链接
selectedLink(val) {
this.selectedLinks.url = val;
this.advertising[0].config = val;
},
openPage() {
const alertType = this.$route.query.pagetype;
const pageType = {
INDEX: "INDEX",
ALERT: "OPEN_SCREEN_PAGE",
OPEN_SCREEN_ANIMATION: "OPEN_SCREEN_ANIMATION",
}[alertType ? alertType : "INDEX"];
API_Other.getOpenHomeData(pageType).then((res) => {
this.$store.state.openStoreId = res.result.id;
if (res.result.pageData) {
this.advertising = [JSON.parse(res.result.pageData)];
}
this.result = res.result
});
},
// 图片选择器回显
callbackSelected(val) {
this.picModelFlag = false;
if (!val?.url) return;
this.advertising[0].img = val.url;
},
// 点击选择图片
handleClickFile(item, index) {
this.picModelFlag = true;
this.$nextTick(() => {
if (this.$refs.ossManage) {
this.$refs.ossManage.selectImage = true;
}
});
},
// 点击链接
clickLink(item) {
this.$refs.liliDialog.open('link')
},
//点击图片解析成base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];
if (file == void 0) return false;
const reader = new FileReader();
reader.readAsDataURL(file);
this.$nextTick((res) => {
reader.onload = (e) => {
item.img = e.target.result;
};
});
},
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
@import "./decorate.scss";
.decorate-radio {
margin: 10px 0;
}
.window-shadow,
.full-shadow {
display: flex;
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
left: 0;
align-items: center;
justify-content: center;
}
.window-shadow {
> img {
width: 306px;
height: 418px;
}
}
.full-shadow {
> img {
width: 100%;
height: 100%;
}
}
.draggable {
position: relative;
}
.btn-item {
> img {
margin: 4px 0;
border-radius: 50%;
width: 30px;
height: 30px;
}
}
</style>

View File

@@ -1,17 +1,7 @@
import index from './index.vue' //首页 import index from "./index.vue";
import advertising from './advertising.vue' //全屏活动
import alertAdvertising from './alertAdvertising.vue' //弹窗活动
const templates = { const templates = {
index, index,
};
advertising, export default templates;
alertAdvertising
}
export default templates

View File

@@ -81,7 +81,6 @@ import Draggable from "vuedraggable";
import { modelData } from "./config"; import { modelData } from "./config";
import decorate from "./decorate"; import decorate from "./decorate";
import * as API_Other from "@/api/other"; import * as API_Other from "@/api/other";
import * as API_Promotions from "@/api/promotion";
export default { export default {
components: { components: {
Draggable, Draggable,
@@ -192,68 +191,8 @@ export default {
}, },
// 右侧栏回调 // 右侧栏回调
handleDrawer(val) { handleDrawer(val) {
let newIndex = this.selected; const newIndex = this.selected;
if (val.promotionsType) {
if (this.contentData.list[newIndex].options.list.length >= 2) {
this.$Message.error("最多只能展示两个活动");
return;
}
if (val.promotionsType === "LIVE") {
API_Promotions.getLiveList({
status: "START",
pageSize: 1,
pageNumber: 1,
}).then((listRes) => {
const records = listRes.result?.records || [];
if (!listRes.success || records.length === 0) {
this.$Message.warning("暂无进行中的直播活动");
return;
}
API_Promotions.getLiveInfo(records[0].id).then((infoRes) => {
if (infoRes.success) {
this.contentData.list[newIndex].options.list.push({
type: val.promotionsType,
title: val.name,
title1: val.subName,
color1: val.subColor,
bk_color: val.subBkColor,
data: infoRes.result.commodityList
? infoRes.result.commodityList.splice(0, 2)
: [],
});
}
});
});
} else {
API_Promotions.getAllPromotion().then((res) => {
let exist = this.contentData.list[newIndex].options.list.find(
(i) => i.type === val.promotionsType
);
if (res.success && !exist) {
this.contentData.list[newIndex].options.list.push({
data: res.result[val.promotionsType]
? res.result[val.promotionsType].splice(0, 2)
: [],
type: val.promotionsType,
title1: val.subName,
color1: val.subColor,
bk_color: val.subBkColor,
title: val.name,
});
}
});
}
this.contentData.list[newIndex] = {
...val,
options: {
...this.contentData.list[newIndex].options,
},
model: val.type,
};
} else {
this.decorateData = ""; this.decorateData = "";
this.contentData.list[newIndex] = { this.contentData.list[newIndex] = {
...val, ...val,
options: { options: {
@@ -261,11 +200,8 @@ export default {
}, },
model: val.type, model: val.type,
}; };
this.contentData.list = JSON.parse( this.contentData.list = JSON.parse(JSON.stringify(this.contentData.list));
JSON.stringify(this.contentData.list) this.decorateData = this.contentData.list[newIndex];
);
this["decorateData"] = this.contentData.list[newIndex];
}
}, },
// 封装拖拽参数 // 封装拖拽参数

View File

@@ -22,13 +22,7 @@ export default {
}; };
}, },
mounted() { mounted() {
if (this.$route.query.pagetype == "ALERT") { this.pagetype = this.$route.query.pagetype || "INDEX";
this.name = "alertAdvertising";
}
if (this.$route.query.pagetype == "OPEN_SCREEN_ANIMATION") {
this.name = "advertising";
}
this.pagetype = this.$route.query.pagetype;
}, },
methods: { methods: {
selected(val) { selected(val) {

View File

@@ -68,22 +68,11 @@ export default {
num: 20, // 提交进度 num: 20, // 提交进度
saveDialog: false, // 加载状态 saveDialog: false, // 加载状态
way: [ way: [
// 装修tab栏切换
{ {
title: "首页", title: "首页",
name: "index", name: "index",
selected: true, selected: true,
}, },
{
title: "全屏广告",
name: "advertising",
selected: false,
},
{
title: "弹窗广告",
name: "ALERT",
selected: false,
},
], ],
submitWay: { submitWay: {
@@ -102,10 +91,6 @@ export default {
this.way.push({ title: "首页", name: "index", selected: true }); this.way.push({ title: "首页", name: "index", selected: true });
} else if (val == "SPECIAL") { } else if (val == "SPECIAL") {
this.way.push({ title: "专题", name: "special", selected: true }); this.way.push({ title: "专题", name: "special", selected: true });
} else if (val == "ALERT") {
this.way.push({ title: "开屏广告", name: "alert", selected: true });
}else if (val == "OPEN_SCREEN_ANIMATION") {
this.way.push({ title: "app开屏页面", name: "OPEN_SCREEN_ANIMATION", selected: true });
} }
}, },
immediate: true, immediate: true,
@@ -144,7 +129,7 @@ export default {
save() { save() {
if ( if (
this.$store.state.styleStore == void 0 && this.$store.state.styleStore == void 0 &&
(this.$route.query.pagetype && this.$route.query.pagetype != 'ALERT' && this.$route.query.pagetype != 'OPEN_SCREEN_ANIMATION') this.$route.query.pagetype != 'SPECIAL'
) { ) {
this.$Message.error("请装修楼层"); this.$Message.error("请装修楼层");
return false; return false;
@@ -155,17 +140,9 @@ export default {
: (this.submitWay.pageShow = "CLOSE"); : (this.submitWay.pageShow = "CLOSE");
this.submitWay.pageData = JSON.stringify(this.$store.state.styleStore); this.submitWay.pageData = JSON.stringify(this.$store.state.styleStore);
this.submitWay.pageType = "INDEX";
this.submitWay.pageType = this.$route.query.pagetype || "INDEX"; this.submitWay.pageType = this.$route.query.pagetype || "INDEX";
// this.submitWay.pageType = this.pagetype;
if (this.$route.query.pagetype == 'ALERT' || this.$route.query.pagetype == 'OPEN_SCREEN_ANIMATION') {
this.update(this.submitWay);
} else {
this.$route.query.id ? this.updateHome() : this.submit(this.submitWay); this.$route.query.id ? this.updateHome() : this.submit(this.submitWay);
}
// this.$route.query.id ? this.update() : this.submit(this.submitWay);
}, },
// 更新 // 更新

View File

@@ -31,6 +31,17 @@ module.exports = {
}, },
devServer: { devServer: {
port: configs.port, port: configs.port,
client: {
overlay: {
runtimeErrors: (error) => {
const message = error?.message || "";
if (message.includes("ResizeObserver loop")) {
return false;
}
return true;
},
},
},
}, },
productionSourceMap: false, productionSourceMap: false,
configureWebpack: { configureWebpack: {