mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-09-22 04:42:04 +08:00
升级Vue3,iView替换ElementPlus
- 删除babel配置、更新依赖与入口初始化 - 全量替换UI组件、样式适配,新增迁移文档与标签/过滤器自动化替换脚本
This commit is contained in:
@@ -1,222 +1,240 @@
|
||||
<template>
|
||||
<div class="forget-password" @click='$refs.verify.show = false'>
|
||||
<div style="height:50px;"></div>
|
||||
<!-- 顶部logo -->
|
||||
<div class="forget-password" @click="$refs.verify.show = false">
|
||||
<div style="height: 50px"></div>
|
||||
<div class="logo-box">
|
||||
<img
|
||||
:src="$store.state.logoImg" width='150'
|
||||
@click="$router.push('/')"
|
||||
/>
|
||||
<img :src="$store.state.logoImg" width="150" @click="$router.push('/')" />
|
||||
<div>修改密码</div>
|
||||
</div>
|
||||
<div class="login-container">
|
||||
<!-- 验证手机号 -->
|
||||
<Form
|
||||
ref="formFirst"
|
||||
:model="formFirst"
|
||||
:rules="ruleInline"
|
||||
style="width:300px;"
|
||||
v-show="step === 0"
|
||||
>
|
||||
<FormItem prop="mobile">
|
||||
<i-input
|
||||
type="text"
|
||||
v-model="formFirst.mobile"
|
||||
clearable
|
||||
placeholder="手机号"
|
||||
>
|
||||
<Icon type="md-phone-portrait" slot="prepend"></Icon>
|
||||
</i-input>
|
||||
</FormItem>
|
||||
<FormItem prop="code">
|
||||
<i-input
|
||||
type="text"
|
||||
v-model="formFirst.code"
|
||||
clearable
|
||||
placeholder="手机验证码"
|
||||
>
|
||||
<Icon
|
||||
type="ios-text-outline"
|
||||
style="font-weight: bold"
|
||||
slot="prepend"
|
||||
/>
|
||||
<Button slot="append" @click="sendCode">{{ codeMsg }}</Button>
|
||||
</i-input>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button @click="verifyBtnClick" long :type="verifyStatus?'success':'default'">{{verifyStatus?'验证通过':'点击完成安全验证'}}</Button>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="error" @click="next" :loading="loading" long>下一步</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<Form
|
||||
ref="form"
|
||||
:model="form"
|
||||
:rules="ruleInline"
|
||||
style="width:300px;"
|
||||
v-show="step === 1"
|
||||
>
|
||||
<FormItem prop="password">
|
||||
<i-input
|
||||
type="password"
|
||||
v-model="form.password"
|
||||
clearable
|
||||
placeholder="请输入至少六位密码"
|
||||
>
|
||||
<Icon type="md-lock" slot="prepend"></Icon>
|
||||
</i-input>
|
||||
</FormItem>
|
||||
<FormItem prop="password">
|
||||
<i-input
|
||||
type="password"
|
||||
v-model="form.oncePasd"
|
||||
clearable
|
||||
placeholder="请再次输入密码"
|
||||
>
|
||||
<Icon type="md-lock" slot="prepend"></Icon>
|
||||
</i-input>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="error" size="large" @click="handleSubmit" :loading="loading1" long>提交</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<!-- 拼图验证码 -->
|
||||
<verify
|
||||
ref="verify"
|
||||
class="verify-con"
|
||||
:verifyType="verifyType"
|
||||
@change="verifyChange"
|
||||
></verify>
|
||||
<div class="login-btn"><a @click="$router.push('login')">前往登录</a></div>
|
||||
<el-form
|
||||
ref="formFirst"
|
||||
:model="formFirst"
|
||||
:rules="ruleInline"
|
||||
style="width: 300px"
|
||||
v-show="step === 0"
|
||||
>
|
||||
<el-form-item prop="mobile">
|
||||
<el-input v-model="formFirst.mobile" clearable placeholder="手机号">
|
||||
<template #prepend>
|
||||
<el-icon><Iphone /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<el-input v-model="formFirst.code" clearable placeholder="手机验证码">
|
||||
<template #prepend>
|
||||
<el-icon><Message /></el-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button @click="sendCode">{{ codeMsg }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
style="width: 100%"
|
||||
:type="verifyStatus ? 'success' : 'default'"
|
||||
@click="verifyBtnClick"
|
||||
>
|
||||
{{ verifyStatus ? "验证通过" : "点击完成安全验证" }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="danger" style="width: 100%" :loading="loading" @click="next">
|
||||
下一步
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="form"
|
||||
:rules="ruleInline"
|
||||
style="width: 300px"
|
||||
v-show="step === 1"
|
||||
>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="form.password"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
placeholder="请输入至少六位密码"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-icon><Lock /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="oncePasd">
|
||||
<el-input
|
||||
v-model="form.oncePasd"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
placeholder="请再次输入密码"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-icon><Lock /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="large"
|
||||
style="width: 100%"
|
||||
:loading="loading1"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<verify
|
||||
ref="verify"
|
||||
class="verify-con"
|
||||
:verifyType="verifyType"
|
||||
@change="verifyChange"
|
||||
/>
|
||||
<div class="login-btn"><a @click="$router.push('login')">前往登录</a></div>
|
||||
</div>
|
||||
<div class="foot">
|
||||
<Row type="flex" justify="space-around" class="help">
|
||||
<el-row justify="space-around" class="help">
|
||||
<a class="item" href="https://pickmall.cn/" target="_blank">帮助</a>
|
||||
<a class="item" href="https://pickmall.cn/" target="_blank">隐私</a>
|
||||
<a class="item" href="https://pickmall.cn/" target="_blank">条款</a>
|
||||
</Row>
|
||||
<Row type="flex" justify="center" class="copyright">
|
||||
Copyright © {{year}} - Present
|
||||
<a href="https://pickmall.cn/" target="_blank" style="margin: 0 5px"
|
||||
>{{config.title}}</a
|
||||
>
|
||||
</el-row>
|
||||
<el-row justify="center" class="copyright">
|
||||
Copyright © {{ year }} - Present
|
||||
<a href="https://pickmall.cn/" target="_blank" style="margin: 0 5px">{{
|
||||
config.title
|
||||
}}</a>
|
||||
版权所有
|
||||
</Row>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import * as RegExp from '@/utils/regular.js';
|
||||
import * as apiLogin from '@/api/index.js';
|
||||
import { sendSms } from '@/api/common.js';
|
||||
import { Iphone, Message, Lock } from "@element-plus/icons-vue";
|
||||
import * as RegExp from "@/utils/regular.js";
|
||||
import * as apiLogin from "@/api/index.js";
|
||||
import { sendSms } from "@/api/common.js";
|
||||
import verify from "@/views/my-components/verify";
|
||||
|
||||
export default {
|
||||
name: 'ForgetPassword',
|
||||
components: { verify },
|
||||
data () {
|
||||
name: "ForgetPassword",
|
||||
components: { verify, Iphone, Message, Lock },
|
||||
data() {
|
||||
return {
|
||||
config:require('@/config'),
|
||||
loading: false, // 加载状态
|
||||
loading1: false, // 第二步加载状态
|
||||
formFirst: { // 手机验证码表单
|
||||
// 注册表单
|
||||
mobile: '',
|
||||
code: ''
|
||||
config: require("@/config"),
|
||||
loading: false,
|
||||
loading1: false,
|
||||
formFirst: {
|
||||
mobile: "",
|
||||
code: "",
|
||||
},
|
||||
form: { // 密码
|
||||
password: '',
|
||||
oncePasd: ''
|
||||
form: {
|
||||
password: "",
|
||||
oncePasd: "",
|
||||
},
|
||||
year: new Date().getFullYear(), // 当前年份
|
||||
step: 0, // 步骤
|
||||
year: new Date().getFullYear(),
|
||||
step: 0,
|
||||
ruleInline: {
|
||||
// 验证规则
|
||||
mobile: [
|
||||
{ required: true, message: '请输入手机号码' },
|
||||
{ required: true, message: "请输入手机号码" },
|
||||
{
|
||||
pattern: RegExp.mobile,
|
||||
trigger: 'blur',
|
||||
message: '请输入正确的手机号'
|
||||
}
|
||||
trigger: "blur",
|
||||
message: "请输入正确的手机号",
|
||||
},
|
||||
],
|
||||
code: [{ required: true, message: "请输入手机验证码" }],
|
||||
password: [
|
||||
{ required: true, message: "密码不能为空" },
|
||||
{ pattern: RegExp.password, message: "密码不能少于6位" },
|
||||
],
|
||||
code: [{ required: true, message: '请输入手机验证码' }],
|
||||
password: [{required: true, message: '密码不能为空'}, {pattern: RegExp.password, message: '密码不能少于6位'}]
|
||||
},
|
||||
verifyStatus: false, // 图片验证状态
|
||||
verifyType: 'FIND_USER', // 图片验证类型
|
||||
codeMsg: '发送验证码', // 验证码文字
|
||||
interval: '', // 定时器
|
||||
time: 60 // 倒计时时间
|
||||
verifyStatus: false,
|
||||
verifyType: "FIND_USER",
|
||||
codeMsg: "发送验证码",
|
||||
interval: "",
|
||||
time: 60,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 提交短信验证码,修改密码
|
||||
next () {
|
||||
next() {
|
||||
this.$refs.formFirst.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
let data = JSON.parse(JSON.stringify(this.formFirst));
|
||||
apiLogin.validateCode(data).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
// this.$Message.success('');
|
||||
this.step = 1;
|
||||
} else {
|
||||
this.$Message.warning(res.message);
|
||||
}
|
||||
}).catch(() => { this.loading = false; });
|
||||
} else {}
|
||||
const data = JSON.parse(JSON.stringify(this.formFirst));
|
||||
apiLogin
|
||||
.validateCode(data)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.step = 1;
|
||||
} else {
|
||||
this.$Message.warning(res.message);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
handleSubmit () { // 提交密码
|
||||
this.$refs.form.validate(valid => {
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
let params = JSON.parse(JSON.stringify(this.form));
|
||||
const params = JSON.parse(JSON.stringify(this.form));
|
||||
if (params.password !== params.oncePasd) {
|
||||
this.$Message.warning('两次输入密码不一致');
|
||||
this.$Message.warning("两次输入密码不一致");
|
||||
return;
|
||||
};
|
||||
}
|
||||
params.mobile = this.formFirst.mobile;
|
||||
params.password = this.md5(params.password);
|
||||
delete params.oncePasd;
|
||||
this.loading1 = true;
|
||||
|
||||
apiLogin.forgetAndModify(params).then(res => {
|
||||
this.loading1 = false;
|
||||
if (res.success) {
|
||||
this.$Message.success('修改密码成功');
|
||||
this.$router.push('login');
|
||||
}
|
||||
}).catch(() => { this.loading = false; });
|
||||
};
|
||||
apiLogin
|
||||
.forgetAndModify(params)
|
||||
.then((res) => {
|
||||
this.loading1 = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改密码成功");
|
||||
this.$router.push("login");
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
sendCode () { // 发送验证码
|
||||
sendCode() {
|
||||
if (this.time === 60) {
|
||||
if (this.formFirst.mobile === '') {
|
||||
this.$Message.warning('请先填写手机号');
|
||||
if (this.formFirst.mobile === "") {
|
||||
this.$Message.warning("请先填写手机号");
|
||||
return;
|
||||
}
|
||||
if (!this.verifyStatus) {
|
||||
this.$Message.warning('请先完成安全验证');
|
||||
this.$Message.warning("请先完成安全验证");
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
const params = {
|
||||
mobile: this.formFirst.mobile,
|
||||
verificationEnums: 'FIND_USER'
|
||||
verificationEnums: "FIND_USER",
|
||||
};
|
||||
sendSms(params).then(res => {
|
||||
sendSms(params).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success('验证码发送成功');
|
||||
let that = this;
|
||||
this.$Message.success("验证码发送成功");
|
||||
const that = this;
|
||||
this.interval = setInterval(() => {
|
||||
that.time--;
|
||||
if (that.time === 0) {
|
||||
that.time = 60;
|
||||
that.codeMsg = '重新发送';
|
||||
that.codeMsg = "重新发送";
|
||||
that.verifyStatus = false;
|
||||
clearInterval(that.interval);
|
||||
} else {
|
||||
@@ -229,28 +247,26 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
verifyChange (con) { // 验证通过
|
||||
verifyChange(con) {
|
||||
if (!con.status) return;
|
||||
this.$refs.verify.show = false;
|
||||
this.verifyStatus = true;
|
||||
},
|
||||
verifyBtnClick () {
|
||||
verifyBtnClick() {
|
||||
if (!this.verifyStatus) {
|
||||
this.$refs.verify.init();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
document.querySelector('.forget-password').style.height = window.innerHeight + 'px'
|
||||
mounted() {
|
||||
document.querySelector(".forget-password").style.height = window.innerHeight + "px";
|
||||
this.$refs.formFirst.resetFields();
|
||||
},
|
||||
watch: {
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.forget-password{
|
||||
.forget-password {
|
||||
min-height: 700px;
|
||||
}
|
||||
.logo-box {
|
||||
@@ -276,38 +292,20 @@ export default {
|
||||
width: 600px;
|
||||
background-color: #fff;
|
||||
padding: 20px 150px;
|
||||
.login-btn{
|
||||
.login-btn {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: -45px;
|
||||
}
|
||||
}
|
||||
|
||||
.verify-con{
|
||||
.verify-con {
|
||||
position: absolute;
|
||||
left: 140px;
|
||||
top: -30px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.other-login {
|
||||
margin: 0 auto;
|
||||
.ivu-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
.regist {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: -10px;
|
||||
span {
|
||||
margin-left: 10px;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.foot {
|
||||
position: fixed;
|
||||
bottom: 4vh;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped>
|
||||
<style lang="scss">
|
||||
@import "./main.scss";
|
||||
</style>
|
||||
|
||||
@@ -8,177 +8,155 @@
|
||||
<div class="logo-con">
|
||||
<img :src="storeSideLogo" key="max-logo" />
|
||||
</div>
|
||||
<shrinkable-menu></shrinkable-menu>
|
||||
<shrinkable-menu />
|
||||
</div>
|
||||
<!-- 顶部标题栏主体 -->
|
||||
<div class="main-header-con" :style="{ height: setting.isUseTabsRouter ? '100px' : '60px' }">
|
||||
<div class="main-header">
|
||||
<div
|
||||
class="header-avator-con"
|
||||
>
|
||||
<!-- 左侧栏 -->
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<!-- 用户头像 -->
|
||||
<div class="header-avator-con">
|
||||
<div></div>
|
||||
<div class="user-dropdown-menu-con">
|
||||
<Row
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="end"
|
||||
align="middle"
|
||||
class="user-dropdown-innercon"
|
||||
>
|
||||
<ul class="nav-list">
|
||||
<li class="nav-item " @click="im">
|
||||
<Tooltip content="联系客服">
|
||||
<Button type="info" size="small" :loading='load' icon="md-chatbubbles">客服</Button>
|
||||
</Tooltip>
|
||||
<li class="nav-item" @click="im">
|
||||
<el-tooltip content="联系客服" placement="bottom">
|
||||
<el-button type="info" size="small" :loading="load">
|
||||
<el-icon><ChatDotRound /></el-icon>
|
||||
客服
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</li>
|
||||
<li class="nav-item " @click="handleClickSetting">
|
||||
<Tooltip content="设置">
|
||||
<Icon size="16" type="md-settings" />
|
||||
</Tooltip>
|
||||
<li class="nav-item" @click="handleClickSetting">
|
||||
<el-tooltip content="设置" placement="bottom">
|
||||
<el-icon :size="16"><Setting /></el-icon>
|
||||
</el-tooltip>
|
||||
</li>
|
||||
</ul>
|
||||
<Dropdown
|
||||
transfer
|
||||
trigger="hover"
|
||||
@on-click="handleClickUserDropdown"
|
||||
>
|
||||
<el-dropdown trigger="hover" @command="handleClickUserDropdown">
|
||||
<div class="dropList">
|
||||
|
||||
<Avatar
|
||||
icon="ios-person"
|
||||
<el-avatar
|
||||
:size="32"
|
||||
:src="userInfo.storeLogo"
|
||||
style="background: #fff; margin-left: 10px"
|
||||
></Avatar>
|
||||
>
|
||||
<el-icon><UserFilled /></el-icon>
|
||||
</el-avatar>
|
||||
</div>
|
||||
<DropdownMenu slot="list">
|
||||
<DropdownItem name="changePass">修改密码</DropdownItem>
|
||||
<DropdownItem name="loginOut" divided>退出</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</Row>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="changePass">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item divided command="loginOut">退出</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 已打开的页面标签 -->
|
||||
<div class="tags-con" v-if="setting.isUseTabsRouter">
|
||||
<tags-page-opened :pageTagsList="pageTagsList"></tags-page-opened>
|
||||
<tags-page-opened :pageTagsList="pageTagsList" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-page-con" :style="{ 'top': setting.isUseTabsRouter ? '100px' : '60px', height: setting.isUseTabsRouter ? 'calc(100% - 110px)' : 'calc(100% - 70px)' }">
|
||||
<div
|
||||
class="single-page-con"
|
||||
:style="{
|
||||
top: setting.isUseTabsRouter ? '100px' : '60px',
|
||||
height: setting.isUseTabsRouter ? 'calc(100% - 110px)' : 'calc(100% - 70px)',
|
||||
}"
|
||||
>
|
||||
<div class="single-page">
|
||||
<!-- <keep-alive :include="cachePage"> -->
|
||||
<!-- </keep-alive> -->
|
||||
<keep-alive>
|
||||
<router-view v-if="$route.meta.keepAlive"></router-view>
|
||||
</keep-alive>
|
||||
<router-view v-if="!$route.meta.keepAlive"></router-view>
|
||||
<router-view v-slot="{ Component }">
|
||||
<component :is="Component" v-if="Component" :key="$route.fullPath" />
|
||||
</router-view>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 全局加载动画 -->
|
||||
<circleLoading class="loading-position" v-show="loading" />
|
||||
<!-- 右侧抽屉配置 -->
|
||||
<configDrawer ref="config"/>
|
||||
<configDrawer ref="config" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ChatDotRound, Setting, UserFilled } from "@element-plus/icons-vue";
|
||||
import shrinkableMenu from "./main-components/shrinkable-menu/shrinkable-menu.vue";
|
||||
import tagsPageOpened from "./main-components/tags-page-opened.vue";
|
||||
import circleLoading from "@/views/my-components/lili/circle-loading.vue";
|
||||
import configDrawer from "@/views/main-components/config-drawer.vue";
|
||||
|
||||
import Cookies from "js-cookie";
|
||||
import util from "@/libs/util.js";
|
||||
import { logout } from "@/api/index";
|
||||
import { getIMDetail } from "@/api/common";
|
||||
import { userMsg } from "@/api/index";
|
||||
|
||||
const config = require("@/config/index.js");
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ChatDotRound,
|
||||
Setting,
|
||||
UserFilled,
|
||||
shrinkableMenu,
|
||||
tagsPageOpened,
|
||||
circleLoading,
|
||||
configDrawer
|
||||
configDrawer,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
sliceNum: 5, // 展示nav数量
|
||||
userInfo: {}, // 用户信息
|
||||
|
||||
storeSideLogo: "", //logo图片
|
||||
IMLink: "", // IM链接
|
||||
load: false, // 加载IM状态
|
||||
sliceNum: 5,
|
||||
userInfo: {},
|
||||
storeSideLogo: "",
|
||||
IMLink: "",
|
||||
load: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
setting(){
|
||||
let data = this.$store.state.setting
|
||||
|
||||
return data.setting
|
||||
setting() {
|
||||
return this.$store.state.setting.setting;
|
||||
},
|
||||
loading() {
|
||||
return this.$store.state.app.loading;
|
||||
},
|
||||
pageTagsList() {
|
||||
return this.$store.state.app.storeOpenedList; // 打开的页面的页面对象
|
||||
},
|
||||
cachePage() {
|
||||
return this.$store.state.app.cachePage;
|
||||
return this.$store.state.app.storeOpenedList;
|
||||
},
|
||||
lang() {
|
||||
return this.$store.state.app.lang;
|
||||
},
|
||||
mesCount() {
|
||||
return 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClickSetting() {
|
||||
this.$refs.config.open();
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击登录im的时候需要去判断一下当前店铺信息是否失效
|
||||
* 失效的话重新请求刷新token保证最新的token去访问im
|
||||
*/
|
||||
async im () {
|
||||
// 获取访问Token
|
||||
let accessToken = this.getStore("accessToken");
|
||||
this.load = true
|
||||
await this.getIMDetailMethods();
|
||||
const userInfo = await userMsg();
|
||||
this.load = false
|
||||
if (userInfo.success && this.IMLink) {
|
||||
window.open(`${this.IMLink}?token=` + accessToken);
|
||||
}
|
||||
else{
|
||||
this.$Message.error("请登录后再联系客服");
|
||||
}
|
||||
},
|
||||
|
||||
// 获取im信息
|
||||
async getIMDetailMethods () {
|
||||
let res = await getIMDetail();
|
||||
if (res.success) {
|
||||
this.IMLink = res.result;
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化方法
|
||||
async im() {
|
||||
const accessToken = this.getStore("accessToken");
|
||||
this.load = true;
|
||||
await this.getIMDetailMethods();
|
||||
const userInfo = await userMsg();
|
||||
this.load = false;
|
||||
if (userInfo.success && this.IMLink) {
|
||||
window.open(`${this.IMLink}?token=` + accessToken);
|
||||
} else {
|
||||
this.$Message.error("请登录后再联系客服");
|
||||
}
|
||||
},
|
||||
async getIMDetailMethods() {
|
||||
const res = await getIMDetail();
|
||||
if (res.success) {
|
||||
this.IMLink = res.result;
|
||||
}
|
||||
},
|
||||
init() {
|
||||
// 菜单
|
||||
let pathArr = util.setCurrentPath(this, this.$route.name);
|
||||
const pathArr = util.setCurrentPath(this, this.$route.name);
|
||||
if (pathArr.length >= 2) {
|
||||
this.$store.commit("addOpenSubmenu", pathArr[1].name);
|
||||
}
|
||||
this.storeSideLogo = localStorage.getItem("sellerlogoImg");
|
||||
window.document.title = localStorage.getItem("sellersiteName");
|
||||
//动态获取icon
|
||||
let link =
|
||||
const link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
@@ -186,47 +164,33 @@ export default {
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
|
||||
let userInfo = JSON.parse(Cookies.get("userInfoSeller"));
|
||||
const userInfo = JSON.parse(Cookies.get("userInfoSeller"));
|
||||
this.userInfo = userInfo;
|
||||
this.checkTag(this.$route.name);
|
||||
|
||||
let currWidth = document.body.clientWidth;
|
||||
const currWidth = document.body.clientWidth;
|
||||
if (currWidth <= 1200) {
|
||||
this.sliceNum = 2;
|
||||
}
|
||||
},
|
||||
// 用户头像下拉
|
||||
handleClickUserDropdown(name) {
|
||||
if (name == "ownSpace") {
|
||||
util.openNewPage(this, "personal-enter");
|
||||
this.$router.push({
|
||||
name: "personal-enter",
|
||||
});
|
||||
} else if (name == "changePass") {
|
||||
if (name === "changePass") {
|
||||
util.openNewPage(this, "change_pass");
|
||||
this.$router.push({
|
||||
name: "change_pass",
|
||||
});
|
||||
} else if (name == "loginOut") {
|
||||
logout().then(res => {
|
||||
this.$router.push({ name: "change_pass" });
|
||||
} else if (name === "loginOut") {
|
||||
logout().then(() => {
|
||||
Cookies.set("accessToken", "");
|
||||
this.$store.commit("logout", this);
|
||||
this.$store.commit("clearOpenedSubmenu");
|
||||
this.setStore("accessToken", "");
|
||||
this.setStore("refreshToken", "");
|
||||
this.$router.push({ path: "/login" });
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
// 快捷页签选中状态
|
||||
checkTag(name) {
|
||||
let openpageHasTag = this.pageTagsList.some((item) => {
|
||||
if (item.name == name) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const openpageHasTag = this.pageTagsList.some((item) => item.name === name);
|
||||
if (!openpageHasTag) {
|
||||
// 解决关闭当前标签后再点击回退按钮会退到当前页时没有标签的问题
|
||||
util.openNewPage(
|
||||
this,
|
||||
name,
|
||||
@@ -235,21 +199,16 @@ export default {
|
||||
);
|
||||
}
|
||||
},
|
||||
// 宽度变化
|
||||
resize() {
|
||||
let currWidth = document.body.clientWidth;
|
||||
let count = currWidth / 300;
|
||||
if (count > 6) {
|
||||
this.sliceNum = 6;
|
||||
} else {
|
||||
this.sliceNum = count;
|
||||
}
|
||||
const currWidth = document.body.clientWidth;
|
||||
const count = currWidth / 300;
|
||||
this.sliceNum = count > 6 ? 6 : count;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route(to) {
|
||||
this.$store.commit("setCurrentPageName", to.name);
|
||||
let pathArr = util.setCurrentPath(this, to.name);
|
||||
const pathArr = util.setCurrentPath(this, to.name);
|
||||
if (pathArr.length > 2) {
|
||||
this.$store.commit("addOpenSubmenu", pathArr[1].name);
|
||||
}
|
||||
@@ -257,20 +216,19 @@ export default {
|
||||
localStorage.currentPageName = to.name;
|
||||
},
|
||||
lang() {
|
||||
util.setCurrentPath(this, this.$route.name); // 在切换语言时用于刷新面包屑
|
||||
util.setCurrentPath(this, this.$route.name);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setOpenedList");
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
let that = this;
|
||||
this.resize();
|
||||
window.addEventListener("resize", function () {
|
||||
that.resize();
|
||||
});
|
||||
window.addEventListener("resize", this.resize);
|
||||
},
|
||||
created() {
|
||||
// 显示打开的页面的列表
|
||||
this.$store.commit("setOpenedList");
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("resize", this.resize);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,47 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card class="change-pass">
|
||||
<p slot="title"><Icon type="key"></Icon>修改密码</p>
|
||||
<div>
|
||||
<Form
|
||||
ref="editPasswordForm"
|
||||
:model="editPasswordForm"
|
||||
:label-width="100"
|
||||
label-position="right"
|
||||
:rules="passwordValidate"
|
||||
style="width:450px"
|
||||
>
|
||||
<FormItem label="原密码" prop="oldPass">
|
||||
<Input type="password" v-model="editPasswordForm.oldPass" placeholder="请输入现在使用的密码"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="新密码" prop="newPassword">
|
||||
<SetPassword style="width:350px;" v-model="editPasswordForm.newPassword" @on-change="changeInputPass" />
|
||||
</FormItem>
|
||||
<FormItem label="确认新密码" prop="rePass">
|
||||
<Input type="password" v-model="editPasswordForm.rePass" placeholder="请再次输入新密码"></Input>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button
|
||||
type="primary"
|
||||
style="width: 100px;margin-right:5px"
|
||||
:loading="savePassLoading"
|
||||
@click="editPassword"
|
||||
>保存</Button>
|
||||
<Button @click="cancelEditPass">取消</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</div>
|
||||
</Card>
|
||||
<el-card class="change-pass">
|
||||
<template #header>修改密码</template>
|
||||
<el-form
|
||||
ref="editPasswordForm"
|
||||
:model="editPasswordForm"
|
||||
label-width="100px"
|
||||
label-position="right"
|
||||
:rules="passwordValidate"
|
||||
style="width: 450px"
|
||||
class="mt_10"
|
||||
>
|
||||
<el-form-item label="原密码" prop="oldPass">
|
||||
<el-input
|
||||
v-model="editPasswordForm.oldPass"
|
||||
type="password"
|
||||
show-password
|
||||
placeholder="请输入现在使用的密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<SetPassword v-model="editPasswordForm.newPassword" @on-change="changeInputPass" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="rePass">
|
||||
<el-input
|
||||
v-model="editPasswordForm.rePass"
|
||||
type="password"
|
||||
show-password
|
||||
placeholder="请再次输入新密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="savePassLoading" @click="editPassword">
|
||||
保存
|
||||
</el-button>
|
||||
<el-button @click="cancelEditPass">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SetPassword from "@/views/my-components/lili/set-password";
|
||||
import SetPassword from "@/components/lili/set-password";
|
||||
import { changePass } from "@/api/index";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
|
||||
export default {
|
||||
name: "change_pass",
|
||||
components: {
|
||||
SetPassword
|
||||
SetPassword,
|
||||
},
|
||||
data() {
|
||||
const valideRePassword = (rule, value, callback) => {
|
||||
@@ -52,106 +60,67 @@ export default {
|
||||
}
|
||||
};
|
||||
return {
|
||||
savePassLoading: false, // 保存loading
|
||||
editPasswordForm: { // 修改密码表单
|
||||
oldPass: "", // 旧密码
|
||||
newPassword: "", // 新密码
|
||||
rePass: "" // 从新输入新密码
|
||||
savePassLoading: false,
|
||||
editPasswordForm: {
|
||||
oldPass: "",
|
||||
newPassword: "",
|
||||
rePass: "",
|
||||
},
|
||||
strength: "", // 密码强度
|
||||
// 验证规则
|
||||
strength: "",
|
||||
passwordValidate: {
|
||||
oldPass: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入原密码",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
oldPass: [{ required: true, message: "请输入原密码", trigger: "blur" }],
|
||||
newPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入新密码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
message: "请至少输入6个字符",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
max: 32,
|
||||
message: "最多输入32个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
{ required: true, message: "请输入新密码", trigger: "blur" },
|
||||
{ min: 6, message: "请至少输入6个字符", trigger: "blur" },
|
||||
{ max: 32, message: "最多输入32个字符", trigger: "blur" },
|
||||
],
|
||||
rePass: [
|
||||
{
|
||||
required: true,
|
||||
message: "请再次输入新密码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: valideRePassword,
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
}
|
||||
{ required: true, message: "请再次输入新密码", trigger: "blur" },
|
||||
{ validator: valideRePassword, trigger: "blur" },
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 新密码回调
|
||||
changeInputPass(v, grade, strength) {
|
||||
this.strength = strength;
|
||||
},
|
||||
// 修改密码
|
||||
editPassword() {
|
||||
let params = {
|
||||
const params = {
|
||||
password: this.md5(this.editPasswordForm.oldPass),
|
||||
newPassword: this.md5(this.editPasswordForm.newPassword)
|
||||
newPassword: this.md5(this.editPasswordForm.newPassword),
|
||||
};
|
||||
this.$refs["editPasswordForm"].validate(valid => {
|
||||
if (valid) {
|
||||
this.savePassLoading = true;
|
||||
changePass(params).then(res => {
|
||||
this.savePassLoading = false;
|
||||
if (res.success) {
|
||||
this.$Modal.success({
|
||||
title: "修改密码成功",
|
||||
content: "修改密码成功,需重新登录",
|
||||
onOk: () => {
|
||||
this.$store.commit("logout", this);
|
||||
this.$store.commit("clearOpenedSubmenu");
|
||||
this.$router.push({
|
||||
name: "login"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.$refs.editPasswordForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.savePassLoading = true;
|
||||
changePass(params).then((res) => {
|
||||
this.savePassLoading = false;
|
||||
if (res.success) {
|
||||
ElMessageBox.alert("修改密码成功,需重新登录", "修改密码成功", {
|
||||
confirmButtonText: "确定",
|
||||
callback: () => {
|
||||
this.$store.commit("logout", this);
|
||||
this.$store.commit("clearOpenedSubmenu");
|
||||
this.$router.push({ name: "login" });
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
// 取消修改密码
|
||||
cancelEditPass() {
|
||||
this.$store.commit("removeTag", "change_pass");
|
||||
localStorage.storeOpenedList = JSON.stringify(
|
||||
this.$store.state.app.storeOpenedList
|
||||
);
|
||||
let lastPageName = "";
|
||||
let length = this.$store.state.app.storeOpenedList.length;
|
||||
if (length > 1) {
|
||||
lastPageName = this.$store.state.app.storeOpenedList[length - 1].name;
|
||||
} else {
|
||||
lastPageName = this.$store.state.app.storeOpenedList[0].name;
|
||||
}
|
||||
this.$router.push({
|
||||
name: lastPageName
|
||||
});
|
||||
}
|
||||
}
|
||||
const list = this.$store.state.app.storeOpenedList;
|
||||
const lastPageName = list.length > 1 ? list[list.length - 1].name : list[0].name;
|
||||
this.$router.push({ name: lastPageName });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.change-pass {
|
||||
&-btn-box {
|
||||
|
||||
@@ -1,291 +1,238 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input type="text" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px"/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="add" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table" >
|
||||
<!-- 商品栏目格式化 -->
|
||||
<template slot="goodsSlot" slot-scope="{row}">
|
||||
<div style="margin-top: 5px;height: 70px; display: flex;">
|
||||
<div style="">
|
||||
<img :src="row.thumbnail" style="height: 60px;margin-top: 3px;width: 60px">
|
||||
</div>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter.prevent="handleSearch"
|
||||
>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div style="margin-left: 13px;">
|
||||
<div class="div-zoom">
|
||||
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
|
||||
</div>
|
||||
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
|
||||
<div slot="content">
|
||||
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
|
||||
</div>
|
||||
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
|
||||
</Poptip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10,20,50]" size="small" show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></liliDialog>
|
||||
<Modal
|
||||
:title="modalTitle"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
|
||||
<FormItem label="分销佣金" prop="commission">
|
||||
<Input v-model="form.commission" clearable style="width: 100%"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
|
||||
>提交
|
||||
</Button
|
||||
>
|
||||
<el-card>
|
||||
<div class="operation" style="margin: 10px 0">
|
||||
<el-button type="primary" @click="delAll">批量下架</el-button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="商品图片" width="120" align="center" fixed="left">
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
v-if="row"
|
||||
:src="row.thumbnail || ''"
|
||||
alt="商品图"
|
||||
style="cursor: pointer; width: 80px; height: 60px; margin: 10px 0; object-fit: contain"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" min-width="220" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<div class="div-zoom">
|
||||
<a class="link-text" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../assets/qrcode.svg"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="qrcode"
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" min-width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="quantity" label="库存" min-width="80" />
|
||||
<el-table-column prop="createTime" label="添加时间" min-width="160" />
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="佣金金额" min-width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">{{ $filters.unitPrice(row.commission, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="100" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a v-if="row" class="link-text" @click="remove(row)">下架</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getDistributionGoods,
|
||||
distributionGoodsCancel,
|
||||
distributionGoodsCheck
|
||||
} from "@/api/distribution";
|
||||
import liliDialog from "../lili-dialog/index";
|
||||
import { delDistributionGoods, getDistributionGoods } from "@/api/distribution";
|
||||
import vueQr from "vue-qr";
|
||||
|
||||
import {getShopListData} from '@/api/shops'
|
||||
export default {
|
||||
name: "distributionGoods",
|
||||
components: {
|
||||
liliDialog
|
||||
},
|
||||
components: { vueQr },
|
||||
data() {
|
||||
return {
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
shopList:[], // 店铺列表
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: { // 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
selectList: [], // 多选数据
|
||||
form:{
|
||||
commission : 1 // 分销金额
|
||||
},
|
||||
skuId:0, // 当前分销商品的skuId
|
||||
formValidate: {
|
||||
commission: [
|
||||
{ required: true, message: '请输入大于1小于9999的合法分销金额'},
|
||||
{
|
||||
pattern: /^[1-9]\d{0,3}(\.\d{1,2})?$/,
|
||||
message: "请输入大于1小于9999的合法分销金额",
|
||||
trigger: "change"
|
||||
}],
|
||||
},
|
||||
columns: [ // 表格表头
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 250,
|
||||
slot: "goodsSlot",
|
||||
},
|
||||
{
|
||||
title: "商品价格",
|
||||
key: "price",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "佣金金额",
|
||||
key: "commission",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if(params.row.commission !=null){
|
||||
return h("div", this.$options.filters.unitPrice(params.row.commission,'¥'));
|
||||
}else{
|
||||
return h("div", this.$options.filters.unitPrice(0,'¥'));
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 150,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0 // 表单数据总数
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() { // 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData(v){
|
||||
this.modalVisible = true
|
||||
this.form.commission = 1
|
||||
this.modalTitle = "保存分销商品"
|
||||
this.skuId = v[0].id
|
||||
},
|
||||
// 添加商品modal
|
||||
add(){
|
||||
this.$refs.liliDialog.flag = true;
|
||||
this.$refs.liliDialog.goodsFlag = true;
|
||||
this.$refs.liliDialog.singleGoods();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.$refs.table.selectAll(false);
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 添加商品
|
||||
handleSubmit(){
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
distributionGoodsCheck(this.skuId,this.form).then(res => {
|
||||
if(res.message === 'success') {
|
||||
this.$Message.success("添加成功");
|
||||
}
|
||||
this.modalVisible = false
|
||||
this.getDataList()
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取商品列表
|
||||
clearSelectAll() {
|
||||
this.$refs.table?.clearSelection();
|
||||
},
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
// 带多条件搜索参数获取表单数据 请自行修改接口
|
||||
getDistributionGoods(this.searchForm).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
getDistributionGoods(this.searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 删除商品
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
// 记得确认修改此处
|
||||
content: "您确认要删除此分销商品么?",
|
||||
title: "确认下架",
|
||||
content: "您确认要下架么?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
distributionGoodsCancel(v.id).then(res => {
|
||||
delDistributionGoods(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("删除成功");
|
||||
this.$Message.success("下架成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
// 获取店铺列表 搜索项用
|
||||
getShopList (val) {
|
||||
const params = {
|
||||
pageNumber:1,
|
||||
pageSize:10,
|
||||
storeName:''
|
||||
delAll() {
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要下架的数据");
|
||||
return;
|
||||
}
|
||||
if (val) {
|
||||
params.storeName = val;
|
||||
} else {
|
||||
params.storeName = ''
|
||||
}
|
||||
|
||||
getShopListData(params).then(res => {
|
||||
this.shopList = res.result.records
|
||||
})
|
||||
this.$Modal.confirm({
|
||||
title: "确认下架",
|
||||
content: "您确认要下架所选的 " + this.selectCount + " 条数据?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
const ids = this.selectList.map((item) => item.id);
|
||||
delDistributionGoods(ids.toString()).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("下架成功");
|
||||
this.clearSelectAll();
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
searchChange(val){
|
||||
this.getShopList(val)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
.search-form{
|
||||
width: 100%;
|
||||
}
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.div-zoom {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.hover-pointer {
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,173 +1,281 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" @keydown.enter.native="handleSearch" class="search-form">
|
||||
<Form-item label="订单编号" prop="orderSn">
|
||||
<Input type="text" v-model="searchForm.orderSn" placeholder="请输入订单编号" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="订单时间">
|
||||
<DatePicker type="daterange" v-model="timeRange" format="yyyy-MM-dd" placeholder="选择时间" style="width: 240px"></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10,20,50]" size="small"
|
||||
show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="订单编号" prop="orderSn">
|
||||
<el-input
|
||||
v-model="searchForm.orderSn"
|
||||
placeholder="请输入订单编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分销商" prop="distributionName">
|
||||
<el-input
|
||||
v-model="searchForm.distributionName"
|
||||
placeholder="请输入分销商名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称">
|
||||
<el-select
|
||||
v-model="searchForm.storeId"
|
||||
placeholder="请选择"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="searchChange"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in shopList"
|
||||
:key="item.id"
|
||||
:label="item.storeName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单时间">
|
||||
<el-date-picker
|
||||
v-model="timeRange"
|
||||
type="daterange"
|
||||
value-format="YYYY-MM-DD"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
placeholder="选择时间"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="orderSn"
|
||||
label="订单编号"
|
||||
min-width="180"
|
||||
fixed="left"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="商品信息" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="goods-msg">
|
||||
<img :src="row.image" width="60" height="60" alt="" />
|
||||
<div>
|
||||
<div class="div-zoom">
|
||||
<a class="link-text" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
<div style="color: #999; font-size: 10px">数量:x{{ row.num }}</div>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../assets/qrcode.svg"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="qrcode"
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="distributionName" label="分销商" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="状态" min-width="90">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="filterStatusTagType(row.distributionOrderStatus)">
|
||||
{{ filterStatus(row.distributionOrderStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="佣金金额" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.rebate, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="160" fixed="right" />
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDistributionOrder } from "@/api/distribution";
|
||||
import { orderStatusList } from "./dataJson";
|
||||
import { getShopListData } from "@/api/shops";
|
||||
import vueQr from "vue-qr";
|
||||
|
||||
export default {
|
||||
name: "distributionOrder",
|
||||
components: {},
|
||||
components: { vueQr },
|
||||
data() {
|
||||
return {
|
||||
timeRange: [], // 范围时间
|
||||
orderStatusList, // 订单状态列表
|
||||
distributionId: this.$route.query.id, // 分销id
|
||||
loading: true, // 表单加载状态
|
||||
timeRange: [],
|
||||
orderStatusList,
|
||||
shopList: [],
|
||||
distributionId: this.$route.query.id,
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort:"create_time",
|
||||
order:"desc"
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "订单编号",
|
||||
key: "orderSn",
|
||||
minWidth: 120,
|
||||
tooltip: true,
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "distributionOrderStatus",
|
||||
width: 100,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
if (params.row.distributionOrderStatus == "NO_COMPLETED") {
|
||||
return h("Tag", { props: { color: "orange" } }, "未完成");
|
||||
} else if (params.row.distributionOrderStatus == "COMPLETE") {
|
||||
return h("Tag", { props: { color: "green" } }, "完成");
|
||||
} else if (params.row.distributionOrderStatus == "REFUND") {
|
||||
return h("Tag", { props: { color: "red" } }, "退款");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "orange" } }, "未完成");
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "佣金金额",
|
||||
key: "rebate",
|
||||
width: 120,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
if (params.row.rebate == null) {
|
||||
return h("div", this.$options.filters.unitPrice(0, "¥"));
|
||||
} else {
|
||||
return h(
|
||||
"div",
|
||||
this.$options.filters.unitPrice(params.row.rebate, "¥")
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 180,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "解冻日期(T+1)",
|
||||
key: "settleCycle",
|
||||
width: 180,
|
||||
sortable: false,
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() { // 初始化数据
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取订单数据
|
||||
getDataList() {
|
||||
this.searchForm.distributionId = this.distributionId;
|
||||
this.loading = true;
|
||||
if (this.timeRange && this.timeRange[0]) {
|
||||
let startTime = this.timeRange[0];
|
||||
let endTime = this.timeRange[1];
|
||||
this.searchForm.startTime = this.$options.filters.unixToDate(
|
||||
startTime / 1000
|
||||
);
|
||||
this.searchForm.endTime = this.$options.filters.unixToDate(
|
||||
endTime / 1000
|
||||
);
|
||||
}
|
||||
// 带多条件搜索参数获取表单数据 请自行修改接口
|
||||
getDistributionOrder(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
watch: {
|
||||
$route(e) {
|
||||
this.distributionId = e.query.id ? e.query.id : undefined;
|
||||
this.getDataList();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getShopList();
|
||||
},
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.searchForm.distributionId = this.distributionId;
|
||||
this.loading = true;
|
||||
if (this.timeRange && this.timeRange[0] && this.timeRange[1]) {
|
||||
const startTime = new Date(this.timeRange[0]).getTime();
|
||||
const endTime = new Date(this.timeRange[1]).getTime();
|
||||
this.searchForm.startTime = this.$filters.unixToDate(startTime / 1000);
|
||||
this.searchForm.endTime = this.$filters.unixToDate(endTime / 1000);
|
||||
} else {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
}
|
||||
getDistributionOrder(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
getShopList(val) {
|
||||
const params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
storeName: val || "",
|
||||
};
|
||||
getShopListData(params).then((res) => {
|
||||
this.shopList = res.result.records;
|
||||
});
|
||||
},
|
||||
searchChange(val) {
|
||||
this.getShopList(val);
|
||||
},
|
||||
filterStatus(status) {
|
||||
const arr = [
|
||||
{ status: "NO_COMPLETED", title: "未完成" },
|
||||
{ status: "COMPLETE", title: "完成" },
|
||||
{ status: "REFUND", title: "退款" },
|
||||
];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i].status === status) {
|
||||
return arr[i].title;
|
||||
}
|
||||
}
|
||||
return "未完成";
|
||||
},
|
||||
filterStatusTagType(status) {
|
||||
const arr = [
|
||||
{ status: "NO_COMPLETED", type: "warning" },
|
||||
{ status: "COMPLETE", type: "success" },
|
||||
{ status: "REFUND", type: "danger" },
|
||||
];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i].status === status) {
|
||||
return arr[i].type;
|
||||
}
|
||||
}
|
||||
return "warning";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" >
|
||||
@import "@/styles/table-common.scss";
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.goods-msg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> div {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hover-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
|
||||
<template>
|
||||
<div class="error403">
|
||||
<div class="error403-body-con">
|
||||
<Card>
|
||||
<div class="error403-body-con-title">4<span class="error403-0-span">
|
||||
<Icon type="android-lock"></Icon>
|
||||
</span><span class="error403-key-span">
|
||||
<Icon size="220" type="ios-bolt"></Icon>
|
||||
</span></div>
|
||||
<el-card>
|
||||
<div class="error403-body-con-title">
|
||||
4<span class="error403-0-span">🔒</span><span class="error403-key-span">⚡</span>
|
||||
</div>
|
||||
<p class="error403-body-con-message">You don't have permission</p>
|
||||
<div class="error403-btn-con">
|
||||
<Button @click="goHome" size="large" style="width: 200px;" type="text">返回首页</Button>
|
||||
<Button @click="backPage" size="large" style="width: 200px;margin-left: 40px;" type="primary">返回上一页</Button>
|
||||
<el-button size="large" style="width: 200px" @click="goHome">返回首页</el-button>
|
||||
<el-button size="large" type="primary" style="width: 200px; margin-left: 40px" @click="backPage">
|
||||
返回上一页
|
||||
</el-button>
|
||||
</div>
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -33,6 +32,7 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes error403animation {
|
||||
0% {
|
||||
@@ -82,14 +82,8 @@ export default {
|
||||
border: 20px solid #ed3f14;
|
||||
color: #ed3f14;
|
||||
margin-right: 10px;
|
||||
i {
|
||||
display: inline-block;
|
||||
font-size: 120px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
font-size: 80px;
|
||||
line-height: 130px;
|
||||
}
|
||||
.error403-key-span {
|
||||
display: inline-block;
|
||||
@@ -98,15 +92,8 @@ export default {
|
||||
height: 190px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
i {
|
||||
display: inline-block;
|
||||
font-size: 190px;
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
transform: translate(-50%, -60%);
|
||||
transform-origin: center bottom;
|
||||
animation: error403animation 2.8s ease 0s infinite;
|
||||
}
|
||||
font-size: 80px;
|
||||
animation: error403animation 2.8s ease 0s infinite;
|
||||
}
|
||||
}
|
||||
&-message {
|
||||
@@ -125,4 +112,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,91 +1,95 @@
|
||||
|
||||
<template>
|
||||
<div class="error404">
|
||||
<div class="error404-body-con">
|
||||
<Card>
|
||||
<div class="error404-body-con-title">4<span><Icon type="ios-navigate-outline"></Icon></span>4</div>
|
||||
<p class="error404-body-con-message">YOU LOOK LOST</p>
|
||||
<div class="error404-btn-con">
|
||||
<Button @click="goHome" size="large" style="width: 200px;" type="text">返回首页</Button>
|
||||
<Button @click="backPage" size="large" style="width: 200px;margin-left: 40px;" type="primary">返回上一页</Button>
|
||||
</div>
|
||||
</Card>
|
||||
<div class="error404">
|
||||
<div class="error404-body-con">
|
||||
<el-card>
|
||||
<div class="error404-body-con-title">
|
||||
4<span>🧭</span>4
|
||||
</div>
|
||||
<p class="error404-body-con-message">YOU LOOK LOST</p>
|
||||
<div class="error404-btn-con">
|
||||
<el-button size="large" style="width: 200px" @click="goHome">返回首页</el-button>
|
||||
<el-button size="large" type="primary" style="width: 200px; margin-left: 40px" @click="backPage">
|
||||
返回上一页
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Error404',
|
||||
methods: {
|
||||
backPage () {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
goHome () {
|
||||
this.$router.push({
|
||||
name: 'home_index'
|
||||
});
|
||||
}
|
||||
}
|
||||
name: "Error404",
|
||||
methods: {
|
||||
backPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
goHome() {
|
||||
this.$router.push({
|
||||
name: "home_index",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes error404animation {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
20% {
|
||||
transform: rotateZ(-60deg);
|
||||
}
|
||||
40% {
|
||||
transform: rotateZ(-10deg);
|
||||
}
|
||||
60% {
|
||||
transform: rotateZ(50deg);
|
||||
}
|
||||
80% {
|
||||
transform: rotateZ(-20deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
@keyframes error404animation {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
20% {
|
||||
transform: rotateZ(-60deg);
|
||||
}
|
||||
40% {
|
||||
transform: rotateZ(-10deg);
|
||||
}
|
||||
60% {
|
||||
transform: rotateZ(50deg);
|
||||
}
|
||||
80% {
|
||||
transform: rotateZ(-20deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
}
|
||||
.error404{
|
||||
&-body-con{
|
||||
width: 700px;
|
||||
height: 500px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
&-title{
|
||||
text-align: center;
|
||||
font-size: 240px;
|
||||
font-weight: 700;
|
||||
color: #2d8cf0;
|
||||
height: 260px;
|
||||
line-height: 260px;
|
||||
margin-top: 40px;
|
||||
span{
|
||||
display: inline-block;
|
||||
color: #19be6b;
|
||||
font-size: 230px;
|
||||
animation: error404animation 3s ease 0s infinite alternate;
|
||||
}
|
||||
}
|
||||
&-message{
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 12px;
|
||||
color: #dddde2;
|
||||
}
|
||||
.error404 {
|
||||
&-body-con {
|
||||
width: 700px;
|
||||
height: 500px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
&-title {
|
||||
text-align: center;
|
||||
font-size: 240px;
|
||||
font-weight: 700;
|
||||
color: #2d8cf0;
|
||||
height: 260px;
|
||||
line-height: 260px;
|
||||
margin-top: 40px;
|
||||
span {
|
||||
display: inline-block;
|
||||
color: #19be6b;
|
||||
font-size: 120px;
|
||||
animation: error404animation 3s ease 0s infinite alternate;
|
||||
}
|
||||
}
|
||||
&-btn-con{
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
margin-bottom: 40px;
|
||||
&-message {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 12px;
|
||||
color: #dddde2;
|
||||
}
|
||||
}
|
||||
&-btn-con {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,107 +1,102 @@
|
||||
|
||||
|
||||
<template>
|
||||
<div class="error500">
|
||||
<div class="error500-body-con">
|
||||
<Card>
|
||||
<div class="error500-body-con-title">
|
||||
5<span class="error500-0-span"><Icon type="social-freebsd-devil"></Icon></span><span class="error500-0-span"><Icon type="social-freebsd-devil"></Icon></span>
|
||||
</div>
|
||||
<p class="error500-body-con-message">Oops! the server is wrong</p>
|
||||
<div class="error500-btn-con">
|
||||
<Button @click="goHome" size="large" style="width: 200px;" type="text">返回首页</Button>
|
||||
<Button @click="backPage" size="large" style="width: 200px;margin-left: 40px;" type="primary">返回上一页</Button>
|
||||
</div>
|
||||
</Card>
|
||||
<div class="error500">
|
||||
<div class="error500-body-con">
|
||||
<el-card>
|
||||
<div class="error500-body-con-title">
|
||||
5<span class="error500-0-span">😈</span><span class="error500-0-span">😈</span>
|
||||
</div>
|
||||
<p class="error500-body-con-message">Oops! the server is wrong</p>
|
||||
<div class="error500-btn-con">
|
||||
<el-button size="large" style="width: 200px" @click="goHome">返回首页</el-button>
|
||||
<el-button size="large" type="primary" style="width: 200px; margin-left: 40px" @click="backPage">
|
||||
返回上一页
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Error500',
|
||||
methods: {
|
||||
backPage () {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
goHome () {
|
||||
this.$router.push({
|
||||
name: 'home_index'
|
||||
});
|
||||
}
|
||||
}
|
||||
name: "Error500",
|
||||
methods: {
|
||||
backPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
goHome() {
|
||||
this.$router.push({
|
||||
name: "home_index",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes error500animation {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
20% {
|
||||
transform: rotateZ(-10deg);
|
||||
}
|
||||
40% {
|
||||
transform: rotateZ(5deg);
|
||||
}
|
||||
60% {
|
||||
transform: rotateZ(-5deg);
|
||||
}
|
||||
80% {
|
||||
transform: rotateZ(10deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
@keyframes error500animation {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
20% {
|
||||
transform: rotateZ(-10deg);
|
||||
}
|
||||
40% {
|
||||
transform: rotateZ(5deg);
|
||||
}
|
||||
60% {
|
||||
transform: rotateZ(-5deg);
|
||||
}
|
||||
80% {
|
||||
transform: rotateZ(10deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
}
|
||||
.error500{
|
||||
&-body-con{
|
||||
width: 700px;
|
||||
height: 500px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
&-title{
|
||||
text-align: center;
|
||||
font-size: 240px;
|
||||
font-weight: 700;
|
||||
color: #2d8cf0;
|
||||
height: 260px;
|
||||
line-height: 260px;
|
||||
margin-top: 40px;
|
||||
.error500-0-span{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 170px;
|
||||
height: 170px;
|
||||
border-radius: 50%;
|
||||
border: 20px solid #ed3f14;
|
||||
color: #ed3f14;
|
||||
margin-right: 10px;
|
||||
i{
|
||||
display: inline-block;
|
||||
font-size: 120px;
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 10px;
|
||||
transform-origin: center bottom;
|
||||
animation: error500animation 3s ease 0s infinite alternate;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-message{
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 4px;
|
||||
color: #dddde2;
|
||||
}
|
||||
.error500 {
|
||||
&-body-con {
|
||||
width: 700px;
|
||||
height: 500px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
&-title {
|
||||
text-align: center;
|
||||
font-size: 240px;
|
||||
font-weight: 700;
|
||||
color: #2d8cf0;
|
||||
height: 260px;
|
||||
line-height: 260px;
|
||||
margin-top: 40px;
|
||||
.error500-0-span {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
border: 20px solid #ed3f14;
|
||||
color: #ed3f14;
|
||||
margin-right: 10px;
|
||||
font-size: 60px;
|
||||
line-height: 80px;
|
||||
animation: error500animation 3s ease 0s infinite alternate;
|
||||
}
|
||||
}
|
||||
&-btn-con{
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
margin-bottom: 40px;
|
||||
&-message {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 4px;
|
||||
color: #dddde2;
|
||||
}
|
||||
}
|
||||
&-btn-con {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,251 +1,456 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<div class="operation">
|
||||
<Button @click="addParent">添加一级分类</Button>
|
||||
<Button @click="refresh">刷新列表</Button>
|
||||
<el-card>
|
||||
<div class="mb_10">
|
||||
<el-button type="primary" @click="addParent">添加一级分类</el-button>
|
||||
</div>
|
||||
<tree-table
|
||||
ref="treeTable"
|
||||
size="small"
|
||||
:loading="loading"
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
class="table"
|
||||
:data="tableData"
|
||||
row-key="id"
|
||||
border
|
||||
:tree-props="{ children: 'children' }"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="name" label="分类名称" min-width="200" />
|
||||
<el-table-column label="状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.deleteFlag"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
inline-prompt
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
:loading="!!row._statusLoading"
|
||||
@change="(val) => onStatusSwitchChange(row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="佣金" width="120">
|
||||
<template #default="{ row }">
|
||||
<span
|
||||
v-if="row"
|
||||
:style="row.commissionRate > 0 ? { color: $mainColor } : {}"
|
||||
>
|
||||
{{ row.commissionRate }}%
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
<template v-if="row.level != 2">
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="addChildren(row)">添加子分类</a>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
:columns="columns"
|
||||
:border="true"
|
||||
:show-index="false"
|
||||
:is-fold="true"
|
||||
:expand-type="false"
|
||||
primary-key="id">
|
||||
<template slot="action" slot-scope="scope">
|
||||
<a @click="edit(scope.row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">编辑</a>
|
||||
<span style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-show="scope.row.level != 1" @click="addChildren(scope.row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">添加子分类</a>
|
||||
<span style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a @click="remove(scope.row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">删除</a>
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="formAdd" label-width="100px" :rules="formValidate">
|
||||
<el-form-item v-if="showParent" label="上级分类" prop="parentId">
|
||||
{{ parentTitle }}
|
||||
<el-input v-model="formAdd.parentId" style="display: none" />
|
||||
</el-form-item>
|
||||
<el-form-item label="层级" prop="level" style="display: none">
|
||||
<el-input v-model="formAdd.level" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input v-model="formAdd.name" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formAdd.level !== 1" label="分类图标" prop="image">
|
||||
<upload-pic-input v-model="formAdd.image" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序值" prop="sortOrder">
|
||||
<el-input-number v-model="formAdd.sortOrder" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="佣金比例(%)" prop="commissionRate">
|
||||
<el-input-number v-model="formAdd.commissionRate" :min="0" :max="100" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用" prop="deleteFlag">
|
||||
<el-switch
|
||||
v-model="formAdd.deleteFlag"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
inline-prompt
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="Submit">提交</el-button>
|
||||
</template>
|
||||
</tree-table>
|
||||
</el-dialog>
|
||||
|
||||
<Modal :title="modalTitle" v-model="modalVisible" :mask-closable='false' :width="500">
|
||||
<Form ref="formAdd" :model="formAdd" :label-width="100" :rules="formValidate">
|
||||
<div v-if="showParent">
|
||||
<FormItem label="上级分类" prop="parentId">
|
||||
{{ parentTitle }}
|
||||
<Input v-model="formAdd.parentId" clearable style="width:100%;display:none"/>
|
||||
</FormItem>
|
||||
</div>
|
||||
<FormItem label="层级" prop="level" style="display:none">
|
||||
<Input v-model="formAdd.level" clearable style="width:100%"/>
|
||||
</FormItem>
|
||||
<FormItem label="分类名称" prop="labelName">
|
||||
<Input v-model="formAdd.labelName" maxlength="12" clearable style="width:100%"/>
|
||||
</FormItem>
|
||||
<FormItem label="排序值" prop="sortOrder" style="width:345px">
|
||||
<InputNumber v-model="formAdd.sortOrder" :min="1"></InputNumber>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible=false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="submit">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</Card>
|
||||
<el-dialog
|
||||
v-model="modalBrandVisible"
|
||||
:title="modalBrandTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="brandForm" :model="brandForm" label-width="100px">
|
||||
<el-select v-model="brandForm.categoryBrands" filterable multiple style="width: 100%">
|
||||
<el-option v-for="item in brandWay" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalBrandVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="saveCategoryBrand">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalSpecVisible"
|
||||
:title="modalSpecTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="specForm" :model="specForm" label-width="100px">
|
||||
<el-select v-model="specForm.categorySpecs" multiple style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in specifications"
|
||||
:key="item.id"
|
||||
:label="item.specName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalSpecVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="saveCategorySpec">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Goods from "@/api/goods";
|
||||
|
||||
import TreeTable from "@/views/my-components/tree-table/Table/Table";
|
||||
|
||||
import {
|
||||
delCategory,
|
||||
disableCategory,
|
||||
getBrandListData,
|
||||
getCategoryBrandListData,
|
||||
getCategorySpecListData,
|
||||
getCategoryTree,
|
||||
getSpecificationList,
|
||||
insertCategory,
|
||||
saveCategoryBrand,
|
||||
saveCategorySpec,
|
||||
updateCategory,
|
||||
} from "@/api/goods";
|
||||
import uploadPicInput from "@/views/my-components/lili/upload-pic-input";
|
||||
import { regular } from "@/utils";
|
||||
import {VARCHAR20} from "../../../utils/regular";
|
||||
|
||||
export default {
|
||||
name: "store-category",
|
||||
name: "goods-category",
|
||||
components: {
|
||||
TreeTable
|
||||
uploadPicInput,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
submitLoading: false, // 提交loading
|
||||
loading: false, //表格加载的loading
|
||||
modalType: 0, // 添加或编辑标识
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
showParent: false, // 是否展示上级菜单
|
||||
parentTitle: "", // 父级菜单名称
|
||||
formAdd: { // 添加或编辑表单对象初始化数据
|
||||
submitLoading: false,
|
||||
categoryList: [],
|
||||
loading: false,
|
||||
brands: [],
|
||||
specifications: [],
|
||||
categoryId: "",
|
||||
categorySpecs: [],
|
||||
modalType: 0,
|
||||
modalVisible: false,
|
||||
modalBrandVisible: false,
|
||||
modalSpecVisible: false,
|
||||
modalTitle: "",
|
||||
showParent: false,
|
||||
parentTitle: "",
|
||||
modalBrandTitle: "",
|
||||
modalSpecTitle: "",
|
||||
formAdd: {
|
||||
parentId: "",
|
||||
labelName: "",
|
||||
sortOrder: 1,
|
||||
name: "",
|
||||
image: "",
|
||||
sortOrder: 0,
|
||||
deleteFlag: false,
|
||||
commissionRate: 0,
|
||||
level: 0,
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
labelName: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
sortOrder: [
|
||||
regular.REQUIRED,
|
||||
regular.INTEGER
|
||||
],
|
||||
brandForm: {
|
||||
categoryBrands: [],
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "分类名称",
|
||||
key: "labelName",
|
||||
align: "left",
|
||||
minWidth: "120px",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "left",
|
||||
headerAlign: "center",
|
||||
width: "280px",
|
||||
type: "template",
|
||||
template: "action",
|
||||
}
|
||||
],
|
||||
// 表格数据
|
||||
tableData: []
|
||||
brandWay: [],
|
||||
specForm: {
|
||||
categorySpecs: [],
|
||||
},
|
||||
formValidate: {
|
||||
commissionRate: [regular.REQUIRED, regular.INTEGER],
|
||||
name: [regular.REQUIRED, regular.VARCHAR20],
|
||||
sortOrder: [regular.REQUIRED, regular.INTEGER],
|
||||
},
|
||||
tableData: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
normalizeCategoryTree(list) {
|
||||
if (!Array.isArray(list) || list.length === 0) return;
|
||||
list.forEach((item) => {
|
||||
if (!item || typeof item !== "object") return;
|
||||
if (item.deleteFlag === 0) item.deleteFlag = false;
|
||||
else if (item.deleteFlag === 1) item.deleteFlag = true;
|
||||
else item.deleteFlag = !!item.deleteFlag;
|
||||
if (Array.isArray(item.children) && item.children.length) {
|
||||
this.normalizeCategoryTree(item.children);
|
||||
}
|
||||
});
|
||||
},
|
||||
onStatusSwitchChange(row, nextDeleteFlag) {
|
||||
const previousDeleteFlag = !nextDeleteFlag;
|
||||
const isClosing = nextDeleteFlag === true;
|
||||
this.$Modal.confirm({
|
||||
title: isClosing ? "确认关闭" : "确认开启",
|
||||
content: `您是否要${isClosing ? "关闭" : "开启"}当前分类 ${row.name} 及其子分类?`,
|
||||
loading: true,
|
||||
okText: "是",
|
||||
cancelText: "否",
|
||||
onOk: () => {
|
||||
row._statusLoading = true;
|
||||
disableCategory(row.id, { enableOperations: isClosing ? true : 0 }).then((res) => {
|
||||
this.$Modal.remove();
|
||||
row._statusLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList();
|
||||
return;
|
||||
}
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
},
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.getAllList();
|
||||
this.getBrandList();
|
||||
this.getSpecList();
|
||||
},
|
||||
// 刷新列表
|
||||
refresh() {
|
||||
this.loading = true;
|
||||
let that = this;
|
||||
setTimeout(function () {
|
||||
that.init();
|
||||
that.$Message.success("刷新成功");
|
||||
that.loading = false;
|
||||
}, 500);
|
||||
getBrandList() {
|
||||
getBrandListData().then((res) => {
|
||||
this.brandWay = res;
|
||||
});
|
||||
},
|
||||
getSpecList() {
|
||||
getSpecificationList().then((res) => {
|
||||
if (res.length != 0) {
|
||||
this.specifications = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
brandOperation(v) {
|
||||
getCategoryBrandListData(v.id).then((res) => {
|
||||
this.categoryId = v.id;
|
||||
this.modalBrandTitle = "品牌关联";
|
||||
this.brandForm.categoryBrands = res.result.map((item) => item.id);
|
||||
this.modalBrandVisible = true;
|
||||
});
|
||||
},
|
||||
specOperation(v) {
|
||||
getCategorySpecListData(v.id).then((res) => {
|
||||
this.categoryId = v.id;
|
||||
this.modalSpecTitle = "规格关联";
|
||||
this.specForm.categorySpecs = res.map((item) => item.id);
|
||||
this.modalSpecVisible = true;
|
||||
});
|
||||
},
|
||||
saveCategorySpec() {
|
||||
saveCategorySpec(this.categoryId, this.specForm).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.modalSpecVisible = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
saveCategoryBrand() {
|
||||
saveCategoryBrand(this.categoryId, this.brandForm).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.modalBrandVisible = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
//添加子分类
|
||||
addChildren(v) {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加子分类";
|
||||
this.parentTitle = v.labelName;
|
||||
this.formAdd.level = eval(v.level + "+1");
|
||||
this.formAdd.labelName = "";
|
||||
this.parentTitle = v.name;
|
||||
this.formAdd.level = Number(v.level) + 1;
|
||||
this.formAdd.commissionRate = v.commissionRate;
|
||||
this.showParent = true;
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = v.id || 0;
|
||||
this.formAdd.parentId = v.id;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 编辑分类
|
||||
edit(v) {
|
||||
this.modalType = 1;
|
||||
this.modalTitle = "编辑";
|
||||
this.formAdd.id = v.id;
|
||||
this.formAdd.labelName = v.labelName;
|
||||
this.formAdd.name = v.name;
|
||||
this.formAdd.level = v.level;
|
||||
this.formAdd.parentId = v.parentId || 0;
|
||||
this.formAdd.parentId = v.parentId;
|
||||
this.formAdd.sortOrder = v.sortOrder;
|
||||
this.formAdd.commissionRate = v.commissionRate;
|
||||
this.formAdd.deleteFlag = v.deleteFlag;
|
||||
this.formAdd.image = v.image;
|
||||
this.showParent = false;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
//添加一级分类
|
||||
addParent() {
|
||||
this.modalType = 0;
|
||||
this.formAdd.labelName = "";
|
||||
this.modalTitle = "添加一级分类";
|
||||
this.parentTitle = "顶级分类";
|
||||
this.showParent = true;
|
||||
this.$refs.form?.resetFields();
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = 0;
|
||||
this.formAdd.sortOrder = 1;
|
||||
this.formAdd.level = 0;
|
||||
this.modalVisible = true;
|
||||
|
||||
},
|
||||
//提交编辑和添加
|
||||
submit() {
|
||||
this.$refs.formAdd.validate(valid => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.formAdd.id;
|
||||
API_Goods.addShopGoodsLabel(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getAllList(0);
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
API_Goods.editShopGoodsLabel(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getAllList(0);
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
Submit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
delete this.formAdd.id;
|
||||
insertCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
updateCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 确认删除分类
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
// 记得确认修改此处
|
||||
content: "您确认要删除 " + v.labelName + " ?",
|
||||
content: "您确认要删除 " + v.name + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
API_Goods.delCategdelShopGoodsLabel(v.id).then(res => {
|
||||
delCategory(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
// 获取分类
|
||||
getAllList() {
|
||||
this.loading = true;
|
||||
API_Goods.getShopGoodsLabelList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
res.result.forEach(firstCate => {
|
||||
if (firstCate.children && firstCate.children.length) {
|
||||
firstCate.children.forEach(secondCate => {
|
||||
secondCate.parentId = firstCate.id
|
||||
})
|
||||
getCategoryTree()
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
localStorage.setItem("category", JSON.stringify(res.result));
|
||||
this.normalizeCategoryTree(res.result);
|
||||
this.categoryList = JSON.parse(JSON.stringify(res.result));
|
||||
this.tableData = JSON.parse(JSON.stringify(res.result));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
enable(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认启用",
|
||||
content: "您是否要启用当前分类 " + v.name + " 及其子分类?",
|
||||
loading: true,
|
||||
okText: "是",
|
||||
cancelText: "否",
|
||||
onOk: () => {
|
||||
disableCategory(v.id, { enableOperations: 0 }).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList();
|
||||
}
|
||||
});
|
||||
this.tableData = res.result;
|
||||
}
|
||||
},
|
||||
onCancel: () => {
|
||||
this.getAllList();
|
||||
},
|
||||
});
|
||||
},
|
||||
disable(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认禁用",
|
||||
content: "您是否要禁用当前分类 " + v.name + " 及其子分类?",
|
||||
loading: true,
|
||||
okText: "是",
|
||||
cancelText: "否",
|
||||
onOk: () => {
|
||||
disableCategory(v.id, { enableOperations: true }).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList();
|
||||
}
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
this.getAllList();
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .ivu-table-wrapper {
|
||||
:deep(.el-table__body-wrapper) {
|
||||
overflow: auto;
|
||||
}
|
||||
.table {
|
||||
min-height: 100vh;
|
||||
height: auto;
|
||||
min-height: 60vh;
|
||||
}
|
||||
.operation {
|
||||
.mb_10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
flex-wrap: wrap !important;
|
||||
}
|
||||
|
||||
::v-deep .sku-item-content-val {
|
||||
:deep(.sku-item-content-val) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
@@ -215,7 +215,7 @@ div.base-info-item {
|
||||
}
|
||||
|
||||
/*teatarea*/
|
||||
::v-deep .el-textarea {
|
||||
:deep(.el-textarea) {
|
||||
width: 150%;
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ div.base-info-item {
|
||||
|
||||
/*折叠面板*/
|
||||
.el-collapse-item {
|
||||
::v-deep .el-collapse-item__header {
|
||||
:deep(.el-collapse-item__header) {
|
||||
text-align: left;
|
||||
background-color: #f8f8f8;
|
||||
padding: 0 10px;
|
||||
@@ -240,7 +240,7 @@ div.base-info-item {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item__content {
|
||||
:deep(.el-form-item__content) {
|
||||
margin-left: 120px;
|
||||
text-align: left;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ div.base-info-item {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__content {
|
||||
:deep(.el-collapse-item__content) {
|
||||
padding: 10px 0;
|
||||
text-align: left;
|
||||
}
|
||||
@@ -279,6 +279,11 @@ div.base-info-item {
|
||||
}
|
||||
|
||||
/** 底部步骤 */
|
||||
.footer-btns {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
@@ -296,11 +301,11 @@ div.base-info-item {
|
||||
|
||||
/*图片上传组件第一张图设置封面*/
|
||||
.goods-images {
|
||||
::v-deep li.el-upload-list__item:first-child {
|
||||
:deep(li.el-upload-list__item:first-child) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
::v-deep li.el-upload-list__item:first-child:after {
|
||||
:deep(li.el-upload-list__item:first-child:after) {
|
||||
content: "封";
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
@@ -394,7 +399,7 @@ div.base-info-item {
|
||||
}
|
||||
|
||||
.required {
|
||||
::v-deep .ivu-form-item-label::before {
|
||||
:deep(.el-form-item__label::before) {
|
||||
content: "*";
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
@@ -483,7 +488,7 @@ div.base-info-item {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
::v-deep img {
|
||||
:deep(img) {
|
||||
margin-right: 20px;
|
||||
width: 100px;
|
||||
margin-left: 10px;
|
||||
@@ -491,7 +496,7 @@ div.base-info-item {
|
||||
|
||||
|
||||
|
||||
::v-deep p {
|
||||
:deep(p) {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
margin-top: 10px;
|
||||
|
||||
@@ -1,185 +1,187 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="商品编号" prop="goodsId">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.goodsId"
|
||||
placeholder="请输入商品编号"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="状态" prop="status">
|
||||
<Select
|
||||
v-model="searchForm.marketEnable"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
>
|
||||
<Option value="DOWN">下架</Option>
|
||||
<Option value="UPPER">上架</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="商品分类" prop="category">
|
||||
<Cascader
|
||||
<el-card>
|
||||
<div @keyup.enter="handleSearch">
|
||||
<el-form ref="searchForm" :model="searchForm" inline label-width="70px" class="search-form">
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编号" prop="goodsId">
|
||||
<el-input v-model="searchForm.goodsId" placeholder="请输入商品编号" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="searchForm.marketEnable" placeholder="请选择" clearable style="width: 200px">
|
||||
<el-option label="下架" value="DOWN" />
|
||||
<el-option label="上架" value="UPPER" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分类" prop="category">
|
||||
<el-cascader
|
||||
v-model="category"
|
||||
:options="categoryList"
|
||||
placeholder="请选择商品分类"
|
||||
style="width: 200px"
|
||||
:data="categoryList"
|
||||
></Cascader>
|
||||
</Form-item>
|
||||
<Form-item label="货号" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.skuSn"
|
||||
placeholder="请输入货号"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
<Tabs @on-click="switchTabs" value="updateStock" v-model="stockType">
|
||||
<TabPane label="商品库存管理" name="stockManage">
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="exportStock" type="primary" class="export">批量导出</Button>
|
||||
<Button @click="openImportStock" class="export">批量导入</Button>
|
||||
</Row>
|
||||
<Table
|
||||
class="mt_10"
|
||||
border
|
||||
:loading="loading"
|
||||
:columns="stockManageColumns"
|
||||
:data="stockAllData"
|
||||
ref="table"
|
||||
>
|
||||
<template slot="goodsSlot" slot-scope="{ row }">
|
||||
<div style="margin-top: 5px; height: 90px; display: flex">
|
||||
<div style="">
|
||||
<img :src="row.thumbnail" style="height: 80px; margin-top: 3px; width: 70px"/>
|
||||
</div>
|
||||
<div style="margin-left: 13px;margin-top: 5px;">
|
||||
<div class="div-zoom" style="color: black;">
|
||||
{{ row.goodsName }}
|
||||
</div>
|
||||
<div class="div-zoom" style="margin-top: 5px;">
|
||||
ID: {{ row.goodsId }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="skuSlot" slot-scope="{ row }">
|
||||
<div style="margin-top: 5px; height: 90px; display: flex">
|
||||
<div style="margin-left: 13px;margin-top: 5px;">
|
||||
<div class="div-zoom" style="color: black;">
|
||||
{{ row.simpleSpecs }}
|
||||
</div>
|
||||
<div class="div-zoom" style="margin-top: 5px;">
|
||||
ID: {{ row.id }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
</TabPane>
|
||||
<TabPane label="预警商品" name="warnList">
|
||||
<Table
|
||||
class="mt_10"
|
||||
border
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="warnData"
|
||||
ref="table"
|
||||
>
|
||||
</Table>
|
||||
</TabPane>
|
||||
<TabPane label="设置预警" name="warnSetting">
|
||||
<Table
|
||||
class="mt_10"
|
||||
border
|
||||
:loading="loading"
|
||||
:columns="settingColumns"
|
||||
:data="skuAllData"
|
||||
ref="table"
|
||||
>
|
||||
<template slot="alertQuantitySlot" slot-scope="{ row }">
|
||||
<Input type="number" v-model="row.alertQuantity" clearable placeholder="请输入预警库存"
|
||||
@on-blur="updateWarnStock(row)" @on-change="checkVal(row)"/>
|
||||
</template>
|
||||
</Table>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<Modal
|
||||
title="更新库存"
|
||||
v-model="updateStockModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="610"
|
||||
>
|
||||
<Table
|
||||
class="mt_10"
|
||||
:columns="updateStockColumns"
|
||||
:data="stockList"
|
||||
border
|
||||
></Table>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="updateStockModalVisible = false">取消</Button>
|
||||
<Button type="primary" @click="updateStock">更新</Button>
|
||||
</el-form-item>
|
||||
<el-form-item label="货号" prop="id">
|
||||
<el-input v-model="searchForm.skuSn" placeholder="请输入货号" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
<el-button class="search-btn" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Modal title="导入商品信息" v-model="importModal" :mask-closable="false">
|
||||
<div style="text-align: center">
|
||||
<Upload :before-upload="handleUpload" name="files"
|
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
multiple type="drag" :action="action" :headers="accessToken">
|
||||
<el-tabs v-model="stockType" @tab-click="switchTabs">
|
||||
<el-tab-pane label="商品库存管理" name="stockManage">
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" class="export" @click="exportStock">批量导出</el-button>
|
||||
<el-button class="export" @click="openImportStock">批量导入</el-button>
|
||||
</div>
|
||||
<el-table ref="table" v-loading="loading" border :data="stockAllData" class="mt_10" style="width: 100%">
|
||||
<el-table-column label="商品信息" min-width="400">
|
||||
<template #default="{ row }">
|
||||
<div style="margin-top: 5px; height: 90px; display: flex">
|
||||
<img :src="row.thumbnail" style="height: 80px; margin-top: 3px; width: 70px" alt="" />
|
||||
<div style="margin-left: 13px; margin-top: 5px">
|
||||
<div class="div-zoom" style="color: black">{{ row.goodsName }}</div>
|
||||
<div class="div-zoom" style="margin-top: 5px">ID: {{ row.goodsId }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="SKU信息" min-width="400">
|
||||
<template #default="{ row }">
|
||||
<div style="margin-top: 5px">
|
||||
<div class="div-zoom" style="color: black">{{ row.simpleSpecs }}</div>
|
||||
<div class="div-zoom" style="margin-top: 5px">ID: {{ row.id }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架状态" width="130">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.marketEnable === 'DOWN' ? 'danger' : 'success'">
|
||||
{{ row.marketEnable === "DOWN" ? "下架" : "上架" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag
|
||||
:type="
|
||||
row.authFlag === 'PASS' ? 'success' : row.authFlag === 'TOBEAUDITED' ? 'warning' : 'danger'
|
||||
"
|
||||
>
|
||||
{{
|
||||
row.authFlag === "PASS" ? "通过" : row.authFlag === "TOBEAUDITED" ? "待审核" : "审核拒绝"
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" min-width="120">
|
||||
<template #default="{ row }">{{ row.quantity || 0 }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="预警商品" name="warnList">
|
||||
<el-table v-loading="loading" border :data="warnData" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="400" show-overflow-tooltip />
|
||||
<el-table-column label="库存" min-width="120">
|
||||
<template #default="{ row }">{{ row.quantity || 0 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预警值" min-width="120">
|
||||
<template #default="{ row }">{{ row.alertQuantity || 0 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="openUpdataStockModal(row)">库存</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="设置预警" name="warnSetting">
|
||||
<el-table v-loading="loading" border :data="skuAllData" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="goodsName" label="商品名称" />
|
||||
<el-table-column label="库存" width="200">
|
||||
<template #default="{ row }">{{ row.quantity || 0 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预警值" width="200">
|
||||
<template #default="{ row }">
|
||||
<el-input
|
||||
v-model="row.alertQuantity"
|
||||
type="number"
|
||||
clearable
|
||||
placeholder="请输入预警库存"
|
||||
@blur="updateWarnStock(row)"
|
||||
@change="checkVal(row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="updateStockModalVisible" title="更新库存" width="610px" :close-on-click-modal="false">
|
||||
<el-table :data="stockList" border class="mt_10" style="width: 100%">
|
||||
<el-table-column label="sku规格" min-width="120">
|
||||
<template #default="{ row }">{{ row.simpleSpecs }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" width="130">
|
||||
<template #default="{ row }">
|
||||
<el-tag
|
||||
:type="
|
||||
row.authFlag === 'PASS' ? 'success' : row.authFlag === 'TOBEAUDITED' ? 'primary' : 'danger'
|
||||
"
|
||||
>
|
||||
{{
|
||||
row.authFlag === "TOBEAUDITED" ? "待审核" : row.authFlag === "PASS" ? "通过" : "审核拒绝"
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input-number v-model="row.quantity" :min="0" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<el-button @click="updateStockModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="updateStock">更新</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="importModal" title="导入商品信息" :close-on-click-modal="false">
|
||||
<div v-loading="spinShow" style="text-align: center">
|
||||
<el-upload drag :before-upload="handleUpload" :show-file-list="false" accept=".xlsx,.xls">
|
||||
<div style="padding: 50px 0">
|
||||
<Icon type="ios-cloud-upload" size="102" style="color: #3399ff"></Icon>
|
||||
<div style="font-size: 48px; color: #3399ff">↑</div>
|
||||
<h2>选择或拖拽文件上传</h2>
|
||||
</div>
|
||||
<Spin fix v-if="spinShow"></Spin>
|
||||
</Upload>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="importModal = false">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="importModal = false">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -191,7 +193,7 @@ import {
|
||||
importStockExcel,
|
||||
queryExportStock,
|
||||
updateGoodsAlertStocks,
|
||||
updateGoodsSkuStocks
|
||||
updateGoodsSkuStocks,
|
||||
} from "@/api/goods";
|
||||
|
||||
export default {
|
||||
@@ -199,227 +201,44 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
importModal: false,
|
||||
id: "", //要操作的id
|
||||
loading: true, // 表单加载状态
|
||||
updateStockModalVisible: false, // 更新库存模态框显隐
|
||||
stockAllUpdate: undefined, // 更新库存数量
|
||||
stockType: 'stockManage',
|
||||
spinShow: false,
|
||||
loading: true,
|
||||
updateStockModalVisible: false,
|
||||
stockType: "stockManage",
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
checkFlag: false, //检测成功标志
|
||||
// 表单验证规则
|
||||
formValidate: {},
|
||||
//修改库存的数据
|
||||
checkFlag: false,
|
||||
stockList: [],
|
||||
stockManageColumns: [
|
||||
{
|
||||
title: "商品信息",
|
||||
key: "goodsName",
|
||||
midwidth: 400,
|
||||
slot: "goodsSlot",
|
||||
}, {
|
||||
title: "SKU信息",
|
||||
key: "simpleSpecs",
|
||||
midwidth: 400,
|
||||
tooltip: true,
|
||||
slot: "skuSlot",
|
||||
}, {
|
||||
title: "上架状态",
|
||||
key: "marketEnable",
|
||||
width: 130,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
if (params.row.marketEnable == "DOWN") {
|
||||
return h("Tag", {props: {color: "red"}}, "下架");
|
||||
} else if (params.row.marketEnable == "UPPER") {
|
||||
return h("Tag", {props: {color: "green"}}, "上架");
|
||||
}
|
||||
},
|
||||
}, {
|
||||
title: "审核状态",
|
||||
key: "authFlag",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.authFlag == "PASS") {
|
||||
return h("Tag", {props: {color: "green"}}, "通过");
|
||||
} else if (params.row.authFlag == "TOBEAUDITED") {
|
||||
return h("Tag", {props: {color: "volcano"}}, "待审核");
|
||||
} else if (params.row.authFlag == "REFUSE") {
|
||||
return h("Tag", {props: {color: "red"}}, "审核拒绝");
|
||||
}
|
||||
},
|
||||
}, {
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
midwidth: 280,
|
||||
render: (h, params) => {
|
||||
if (params.row.quantity) {
|
||||
return h("div", params.row.quantity);
|
||||
} else {
|
||||
return h("div", 0);
|
||||
}
|
||||
},
|
||||
},],
|
||||
//列表名称
|
||||
columns: [
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
midwidth: 400,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
midwidth: 280,
|
||||
render: (h, params) => {
|
||||
if (params.row.quantity) {
|
||||
return h("div", params.row.quantity);
|
||||
} else {
|
||||
return h("div", 0);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "预警值",
|
||||
key: "alertQuantity",
|
||||
midwidth: 280,
|
||||
render: (h, params) => {
|
||||
if (params.row.alertQuantity) {
|
||||
return h("div", params.row.alertQuantity);
|
||||
} else {
|
||||
return h("div", 0);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.openUpdataStockModal(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"库存"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
settingColumns: [
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
width: 400,
|
||||
render: (h, params) => {
|
||||
if (params.row.quantity) {
|
||||
return h("div", params.row.quantity);
|
||||
} else {
|
||||
return h("div", 0);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "预警值",
|
||||
key: "alertQuantity",
|
||||
width: 400,
|
||||
slot: 'alertQuantitySlot',
|
||||
},
|
||||
],
|
||||
updateStockColumns: [
|
||||
{
|
||||
title: "sku规格",
|
||||
key: "sn",
|
||||
minWidth: 120,
|
||||
render: (h, params) => {
|
||||
return h("div", {}, params.row.simpleSpecs);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "审核状态",
|
||||
key: "authFlag",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
if (params.row.authFlag == "TOBEAUDITED") {
|
||||
return h("Tag", {props: {color: "blue"}}, "待审核");
|
||||
} else if (params.row.authFlag == "PASS") {
|
||||
return h("Tag", {props: {color: "green"}}, "通过");
|
||||
} else if (params.row.authFlag == "REFUSE") {
|
||||
return h("Tag", {props: {color: "red"}}, "审核拒绝");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
let vm = this;
|
||||
return h("InputNumber", {
|
||||
props: {
|
||||
value: params.row.quantity,
|
||||
},
|
||||
on: {
|
||||
"on-change": (event) => {
|
||||
vm.stockList[params.index].quantity = event;
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
warnData: [], // 表单数据
|
||||
skuAllData: [], //SKU数据
|
||||
stockAllData: [],//SKU库存数据
|
||||
total: 0, //sku数据总数
|
||||
categoryList: [], //分类列表
|
||||
category: '', //选中分类
|
||||
warnData: [],
|
||||
skuAllData: [],
|
||||
stockAllData: [],
|
||||
total: 0,
|
||||
categoryList: [],
|
||||
category: [],
|
||||
selectedSku: {},
|
||||
file: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// 初始化数据
|
||||
this.getDataList();
|
||||
this.deepGroup();
|
||||
},
|
||||
openUpdataStockModal(row) {
|
||||
this.stockList = []
|
||||
this.stockList = [];
|
||||
this.selectedSku = JSON.parse(JSON.stringify(row));
|
||||
this.stockList.push(this.selectedSku);
|
||||
this.updateStockModalVisible = true;
|
||||
},
|
||||
// 更新库存
|
||||
updateStock() {
|
||||
let updateStockList = this.stockList.map((i) => {
|
||||
let j = {skuId: i.id, quantity: i.quantity};
|
||||
return j;
|
||||
});
|
||||
const updateStockList = this.stockList.map((i) => ({
|
||||
skuId: i.id,
|
||||
quantity: i.quantity,
|
||||
}));
|
||||
updateGoodsSkuStocks(updateStockList).then((res) => {
|
||||
if (res.success) {
|
||||
this.updateStockModalVisible = false;
|
||||
@@ -428,192 +247,144 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//修改预警值
|
||||
updateWarnStock(row) {
|
||||
if (this.checkFlag) {
|
||||
let submit = {skuId: row.id, alertQuantity: row.alertQuantity}
|
||||
updateGoodsAlertStocks(submit).then(res => {
|
||||
updateGoodsAlertStocks({ skuId: row.id, alertQuantity: row.alertQuantity }).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success('更新成功')
|
||||
this.$Message.success("更新成功");
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
//检测输入值是否正确
|
||||
checkVal(row) {
|
||||
if (
|
||||
!/^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/.test(row.alertQuantity) ||
|
||||
parseInt(row.alertQuantity) < 0 ||
|
||||
parseInt(row.alertQuantity) > 99999999
|
||||
) {
|
||||
// 校验未通过 进行提示
|
||||
this.$Message.error("请输入0~99999999之间的数字值")
|
||||
row.alertQuantity = 0
|
||||
this.$Message.error("请输入0~99999999之间的数字值");
|
||||
row.alertQuantity = 0;
|
||||
this.checkFlag = false;
|
||||
return;
|
||||
}
|
||||
this.checkFlag = true;
|
||||
},
|
||||
//切换分页
|
||||
switchTabs() {
|
||||
this.handleReset();
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
//改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm.categoryPath = this.category ? this.category.join(",") : null;
|
||||
this.searchForm.categoryPath = this.category?.length ? this.category.join(",") : null;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置搜索条件
|
||||
handleReset() {
|
||||
this.searchForm = {};
|
||||
this.searchForm = {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
};
|
||||
this.category = [];
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
// 重新加载数据
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取商品列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
// 带多条件搜索参数获取表单数据
|
||||
if (this.stockType == 'warnList') {
|
||||
//调用预警库存
|
||||
getGoodsListDataByStockSeller(this.searchForm).then(res => {
|
||||
if (this.stockType === "warnList") {
|
||||
getGoodsListDataByStockSeller(this.searchForm).then((res) => {
|
||||
if (res.success) {
|
||||
this.warnData = res.result.records
|
||||
this.total = res.result.total
|
||||
this.loading = false;
|
||||
this.warnData = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
} else if (this.stockType == 'warnSetting') {
|
||||
//调用获取全部sku
|
||||
getGoodsSkuListDataSeller(this.searchForm).then(res => {
|
||||
this.loading = false;
|
||||
});
|
||||
} else if (this.stockType === "warnSetting") {
|
||||
getGoodsSkuListDataSeller(this.searchForm).then((res) => {
|
||||
if (res.success) {
|
||||
this.skuAllData = res.result.records
|
||||
this.total = res.result.total
|
||||
this.loading = false;
|
||||
this.skuAllData = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
} else if (this.stockType == 'stockManage') {
|
||||
//调用获取全部sku
|
||||
getGoodsSkuListDataSeller(this.searchForm).then(res => {
|
||||
this.loading = false;
|
||||
});
|
||||
} else {
|
||||
getGoodsSkuListDataSeller(this.searchForm).then((res) => {
|
||||
if (res.success) {
|
||||
this.stockAllData = res.result.records
|
||||
this.total = res.result.total
|
||||
this.loading = false;
|
||||
this.stockAllData = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
//组织分类树
|
||||
deepGroup() {
|
||||
getGoodsCategoryAll().then(res => {
|
||||
getGoodsCategoryAll().then((res) => {
|
||||
if (res.success) {
|
||||
res.result.forEach((item) => {
|
||||
let childWay = []; //第二级
|
||||
// 第二层
|
||||
if (item.children) {
|
||||
item.children.forEach((child) => {
|
||||
// // 第三层
|
||||
if (child.children) {
|
||||
child.children.forEach((grandson, index, arr) => {
|
||||
arr[index] = {
|
||||
value: grandson.id,
|
||||
label: grandson.name,
|
||||
children: "",
|
||||
};
|
||||
});
|
||||
}
|
||||
let children = {
|
||||
value: child.id,
|
||||
label: child.name,
|
||||
children: child.children,
|
||||
};
|
||||
childWay.push(children);
|
||||
});
|
||||
}
|
||||
// 第一层
|
||||
let way = {
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
children: childWay,
|
||||
};
|
||||
this.categoryList.push(way);
|
||||
});
|
||||
this.categoryList = res.result.map((item) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
children: (item.children || []).map((child) => ({
|
||||
value: child.id,
|
||||
label: child.name,
|
||||
children: (child.children || []).map((grandson) => ({
|
||||
value: grandson.id,
|
||||
label: grandson.name,
|
||||
})),
|
||||
})),
|
||||
}));
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
// 导出订单
|
||||
async exportStock() {
|
||||
let randomNumber = '';
|
||||
let randomNumber = "";
|
||||
for (let i = 0; i < 10; i++) {
|
||||
randomNumber += Math.floor(Math.random() * 10);
|
||||
}
|
||||
;
|
||||
queryExportStock(this.searchForm)
|
||||
.then((res) => {
|
||||
const blob = new Blob([res], {
|
||||
type: "application/vnd.ms-excel;charset=utf-8",
|
||||
});
|
||||
//对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性
|
||||
//IE10以上支持blob但是依然不支持download
|
||||
const blob = new Blob([res], { type: "application/vnd.ms-excel;charset=utf-8" });
|
||||
if ("download" in document.createElement("a")) {
|
||||
//支持a标签download的浏览器
|
||||
const link = document.createElement("a"); //创建a标签
|
||||
link.download = randomNumber + ".xlsx"; //a标签添加属性
|
||||
const link = document.createElement("a");
|
||||
link.download = randomNumber + ".xlsx";
|
||||
link.style.display = "none";
|
||||
link.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(link);
|
||||
link.click(); //执行下载
|
||||
URL.revokeObjectURL(link.href); //释放url
|
||||
document.body.removeChild(link); //释放标签
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
document.body.removeChild(link);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
navigator.msSaveBlob(blob, randomNumber + ".xlsx");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
.catch((err) => console.log(err));
|
||||
},
|
||||
openImportStock() {
|
||||
this.importModal = true;
|
||||
},
|
||||
// 上传数据
|
||||
handleUpload(file) {
|
||||
this.file = file;
|
||||
this.upload();
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* 上传文件
|
||||
*/
|
||||
upload() {
|
||||
let fd = new FormData();
|
||||
const fd = new FormData();
|
||||
fd.append("files", this.file);
|
||||
this.spinShow = true;
|
||||
|
||||
importStockExcel(fd).then(res => {
|
||||
importStockExcel(fd).then((res) => {
|
||||
this.spinShow = false;
|
||||
if (res.success) {
|
||||
this.spinShow = false;
|
||||
this.$Message.success("导入成功");
|
||||
this.importModal = false;
|
||||
this.getDataList();
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
@@ -623,4 +394,9 @@ export default {
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
.link-text {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,174 +1,104 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form mb_10"
|
||||
@keydown.enter.native="handleSearch">
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input type="text" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="商品编号" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.id"
|
||||
placeholder="商品编号"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item style="margin-left: -35px" class="br">
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
<Button @click="handleReset">重置</Button>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small" show-total show-elevator
|
||||
show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form mb_10"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编号" prop="id">
|
||||
<el-input v-model="searchForm.id" placeholder="商品编号" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table v-loading="loading" border :data="data" ref="table" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="id" label="编号" min-width="120" />
|
||||
<el-table-column label="商品原图" width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
:src="row.original"
|
||||
alt="加载图片失败"
|
||||
style="cursor: pointer; width: 80px; height: 60px; margin: 10px 0; object-fit: contain"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="商品价格" width="120">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme :value="row.price || 0" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="120" />
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="editGoods(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="removeDraft(row.id)">删除</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDraftGoodsListData, deleteDraftGoods } from "@/api/goods";
|
||||
|
||||
export default {
|
||||
name: "goods",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
saveType: "TEMPLATE",
|
||||
},
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "编号",
|
||||
key: "id",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "商品原图",
|
||||
key: "original",
|
||||
width: 120,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h("img", {
|
||||
attrs: {
|
||||
src: params.row.original,
|
||||
alt: "加载图片失败",
|
||||
},
|
||||
style: {
|
||||
cursor: "pointer",
|
||||
width: "80px",
|
||||
height: "60px",
|
||||
margin: "10px 0",
|
||||
"object-fit": "contain",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "商品价格",
|
||||
key: "price",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price || 0,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 150,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.editGoods(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"编辑"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{
|
||||
style: { margin: "0 8px", color: "#dcdee2" },
|
||||
},
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.removeDraft(params.row.id);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// 初始化数据
|
||||
this.getDataList();
|
||||
},
|
||||
// 编辑模板
|
||||
editGoods(v) {
|
||||
this.$router.push({
|
||||
name: "goods-template-operation-edit",
|
||||
query: { draftId: v.id },
|
||||
});
|
||||
},
|
||||
// 删除模板
|
||||
removeDraft(id) {
|
||||
let showType = "模版";
|
||||
this.$Modal.confirm({
|
||||
title: "确认审核",
|
||||
content: "您确认要删除id为 " + id + " 的" + showType + "吗?",
|
||||
content: "您确认要删除id为 " + id + " 的模版吗?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
deleteDraftGoods(id).then((res) => {
|
||||
@@ -181,34 +111,25 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 改变页数
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
changePageSize() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.$refs.searchForm.resetFields();
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
// 重新加载数据
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
// 带多条件搜索参数获取表单数据
|
||||
getDraftGoodsListData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
@@ -222,11 +143,21 @@ export default {
|
||||
this.init();
|
||||
},
|
||||
watch: {
|
||||
$route(to, from) {
|
||||
$route() {
|
||||
this.init();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="goods-operation">
|
||||
<div class="step-list">
|
||||
<steps :current="activestep" style="height:60px;margin-top: 10px">
|
||||
<step title="选择商品品类"/>
|
||||
<step title="填写商品详情"/>
|
||||
<step title="商品发布成功"/>
|
||||
</steps>
|
||||
<el-steps :active="activestep" align-center style="height: 60px; margin-top: 10px">
|
||||
<el-step title="选择商品品类" />
|
||||
<el-step title="填写商品详情" />
|
||||
<el-step title="商品发布成功" />
|
||||
</el-steps>
|
||||
</div>
|
||||
<!-- 第一步 选择分类 -->
|
||||
<first-step ref='first' v-show="activestep === 0" @change="getFirstData"></first-step>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 选择商品类型 -->
|
||||
<Modal v-model="selectGoodsType" width="550" :closable="false">
|
||||
<el-dialog v-model="selectGoodsType" width="550px" :show-close="false">
|
||||
<div class="goods-type-list">
|
||||
<div
|
||||
class="goods-type-item"
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 商品分类 -->
|
||||
<div class="content-goods-publish">
|
||||
<div class="goods-category">
|
||||
@@ -63,10 +63,10 @@
|
||||
</div>
|
||||
<!-- 底部按钮 -->
|
||||
<div class="footer">
|
||||
<ButtonGroup>
|
||||
<Button type="primary" @click="selectGoodsType = true">商品类型</Button>
|
||||
<Button type="primary" @click="next">下一步</Button>
|
||||
</ButtonGroup>
|
||||
<div class="footer-btns">
|
||||
<el-button type="primary" @click="selectGoodsType = true">商品类型</el-button>
|
||||
<el-button type="primary" @click="next">下一步</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,115 +1,124 @@
|
||||
<template>
|
||||
<div>
|
||||
<Modal v-model="visible" title="预览图片">
|
||||
<el-dialog v-model="visible" title="预览图片">
|
||||
<img v-if="visible" :src="previewPicture" style="width: 100%">
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<div class="content-goods-publish">
|
||||
<Form ref="baseInfoForm" :label-width="120" :model="baseInfoForm" :rules="baseInfoFormRule">
|
||||
<el-form ref="baseInfoForm" label-width="120px" :model="baseInfoForm" :rules="baseInfoFormRule">
|
||||
<div class="base-info-item">
|
||||
<h4>基本信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="商品分类">
|
||||
<el-form-item label="商品分类">
|
||||
<span class="goods-category-name">{{
|
||||
this.baseInfoForm.categoryName[0]
|
||||
}}</span>
|
||||
<span> > {{ this.baseInfoForm.categoryName[1] }}</span>
|
||||
<span> > {{ this.baseInfoForm.categoryName[2] }}</span>
|
||||
</FormItem>
|
||||
<FormItem label="商品名称" prop="goodsName">
|
||||
<Input v-model="baseInfoForm.goodsName" clearable placeholder="商品名称" style="width: 260px" type="text" />
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input v-model="baseInfoForm.goodsName" clearable placeholder="商品名称" style="width: 260px" type="text" />
|
||||
</el-form-item>
|
||||
|
||||
<FormItem label="商品价格" prop="price">
|
||||
<Input v-model="baseInfoForm.price" clearable placeholder="商品价格" style="width: 260px" type="text" />
|
||||
</FormItem>
|
||||
<FormItem label="商品卖点" prop="sellingPoint">
|
||||
<Input v-model="baseInfoForm.sellingPoint" :rows="4" style="width: 260px" type="textarea" />
|
||||
</FormItem>
|
||||
<FormItem label="商品品牌" prop="brandId">
|
||||
<Select v-model="baseInfoForm.brandId" filterable style="width: 200px">
|
||||
<Option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"></Option>
|
||||
</Select>
|
||||
<Button class="refresh-icon" icon="md-refresh" shape="circle" type="text"
|
||||
@click="refresh('brand')"></Button>
|
||||
</FormItem>
|
||||
<el-form-item label="商品价格" prop="price">
|
||||
<el-input v-model="baseInfoForm.price" clearable placeholder="商品价格" style="width: 260px" type="text" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品卖点" prop="sellingPoint">
|
||||
<el-input v-model="baseInfoForm.sellingPoint" :rows="4" style="width: 260px" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品品牌" prop="brandId">
|
||||
<el-select v-model="baseInfoForm.brandId" filterable style="width: 200px">
|
||||
<el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-button class="refresh-icon" circle link @click="refresh('brand')">
|
||||
<el-icon><Refresh /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<FormItem class="form-item-view-el" label="计量单位" prop="goodsUnit">
|
||||
<Select v-model="baseInfoForm.goodsUnit" style="width: 100px">
|
||||
<Option v-for="(item, index) in goodsUnitList" :key="index" :value="item">{{ item }}
|
||||
</Option>
|
||||
</Select>
|
||||
<Button class="refresh-icon" icon="md-refresh" shape="circle" type="text"
|
||||
@click="refresh('goodsUnit')"></Button>
|
||||
</FormItem>
|
||||
<FormItem class="form-item-view-el" label="销售模式" prop="salesModel">
|
||||
<RadioGroup v-if="baseInfoForm.goodsType != 'VIRTUAL_GOODS'" v-model="baseInfoForm.salesModel"
|
||||
button-style="solid" type="button" @on-change="handleSalesModeChange">
|
||||
<Radio label="RETAIL" title="零售型">零售型</Radio>
|
||||
<Radio label="WHOLESALE" title="批发型">批发型</Radio>
|
||||
</RadioGroup>
|
||||
<RadioGroup v-else v-model="baseInfoForm.salesModel" button-style="solid" type="button">
|
||||
<Radio label="RETAIL" title="零售型">
|
||||
<span>虚拟型</span>
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem v-if="baseInfoForm.salesModel == 'WHOLESALE'" class="form-item-view-el" label="销售规则"
|
||||
<el-form-item class="form-item-view-el" label="计量单位" prop="goodsUnit">
|
||||
<el-select v-model="baseInfoForm.goodsUnit" style="width: 100px">
|
||||
<el-option v-for="(item, index) in goodsUnitList" :key="index" :label="item" :value="item" />
|
||||
</el-select>
|
||||
<el-button class="refresh-icon" circle link @click="refresh('goodsUnit')">
|
||||
<el-icon><Refresh /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item class="form-item-view-el" label="销售模式" prop="salesModel">
|
||||
<el-radio-group
|
||||
v-if="baseInfoForm.goodsType != 'VIRTUAL_GOODS'"
|
||||
v-model="baseInfoForm.salesModel"
|
||||
@change="handleSalesModeChange"
|
||||
>
|
||||
<el-radio-button value="RETAIL">零售型</el-radio-button>
|
||||
<el-radio-button value="WHOLESALE">批发型</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-radio-group v-else v-model="baseInfoForm.salesModel">
|
||||
<el-radio-button value="RETAIL">虚拟型</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="baseInfoForm.salesModel == 'WHOLESALE'" class="form-item-view-el" label="销售规则"
|
||||
prop="wholesaleRule">
|
||||
<div class="form-item-view-wholesale">
|
||||
<div>
|
||||
<Table :columns="wholesaleColumns" :data="wholesaleData" border>
|
||||
<template slot="wholesaleNum" slot-scope="{ row, index }">
|
||||
<div>
|
||||
<Input v-model="wholesaleData[index].num" min="1" number type="number"
|
||||
@on-blur="checkWholesaleNum(index)">
|
||||
<span slot="append">{{
|
||||
baseInfoForm.goodsUnit || ""
|
||||
}}</span>
|
||||
</Input>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="wholesalePrice" slot-scope="{ row, index }">
|
||||
<div style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
">
|
||||
<Input v-model="wholesaleData[index].price" min="1" number style="width: 190px" type="number"
|
||||
@on-blur="checkWholesalePrice(index)">
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
<Button v-if="index > 0" size="small" style="margin-left: 5px" type="error"
|
||||
@click="handleDeleteWholesaleData(index)">删除
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<el-table :data="wholesaleData" border style="width: 100%">
|
||||
<el-table-column label="购买数量" align="center">
|
||||
<template #default="{ $index }">
|
||||
<el-input v-model="wholesaleData[$index].num" type="number" @blur="checkWholesaleNum($index)">
|
||||
<template #append>{{ baseInfoForm.goodsUnit || "" }}</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品单价" align="center" width="280">
|
||||
<template #default="{ $index }">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<el-input
|
||||
v-model="wholesaleData[$index].price"
|
||||
type="number"
|
||||
style="width: 190px"
|
||||
@blur="checkWholesalePrice($index)"
|
||||
>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
<el-button
|
||||
v-if="$index > 0"
|
||||
size="small"
|
||||
style="margin-left: 5px"
|
||||
type="danger"
|
||||
@click="handleDeleteWholesaleData($index)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Button v-if="wholesaleData.length < 3" icon="md-add" style="margin-top: 10px"
|
||||
@click="handleAddWholesaleData()">
|
||||
<el-button v-if="wholesaleData.length < 3" style="margin-top: 10px" @click="handleAddWholesaleData()">
|
||||
<el-icon><Plus /></el-icon>
|
||||
添加价格区间
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="form-item-view-wholesale-preview">
|
||||
<Table :columns="wholesalePreviewColumns" :data="wholesaleData" border></Table>
|
||||
<el-table :data="wholesaleData" border style="width: 100%">
|
||||
<el-table-column label="销售规则" width="300">
|
||||
<template #default="{ row }">
|
||||
当商品购买数量 ≥{{ row.num }} 时,售价为 ¥{{ row.price }}/{{ baseInfoForm.goodsUnit }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem class="form-item-view-el" label="商品发布" prop="release">
|
||||
<RadioGroup v-model="baseInfoForm.release" button-style="solid" type="button">
|
||||
<Radio :label="1" title="上架">
|
||||
<span>上架</span>
|
||||
</Radio>
|
||||
<Radio :label="0" title="下架">
|
||||
<span>下架</span>
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
<el-form-item class="form-item-view-el" label="商品发布" prop="release">
|
||||
<el-radio-group v-model="baseInfoForm.release">
|
||||
<el-radio-button :value="1">上架</el-radio-button>
|
||||
<el-radio-button :value="0">下架</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<h4>商品规格及图片</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem class="form-item-view-el required" label="主图" prop="goodsGalleryFiles">
|
||||
<el-form-item class="form-item-view-el required" label="主图" prop="goodsGalleryFiles">
|
||||
<div style="display: flex; flex-wrap: wrap;">
|
||||
<vuedraggable :animation="200" :list="baseInfoForm.goodsGalleryFiles">
|
||||
<div v-for="(item, __index) in baseInfoForm.goodsGalleryFiles" :key="__index"
|
||||
@@ -118,8 +127,8 @@
|
||||
<img :src="item" />
|
||||
<div class="demo-upload-list-cover">
|
||||
<div>
|
||||
<Icon size="30" type="md-search" @click.native="handleViewGoodsPicture(item)"></Icon>
|
||||
<Icon size="30" type="md-trash" @click.native="handleRemoveGoodsPicture(item)"></Icon>
|
||||
<el-button link type="primary" @click="handleViewGoodsPicture(item)">预览</el-button>
|
||||
<el-button link type="danger" @click="handleRemoveGoodsPicture(item)">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -140,85 +149,96 @@
|
||||
<!--</Upload>-->
|
||||
</div>
|
||||
<div style="width: 100%;display: flex;justify-content: start;margin-top: 10px;">
|
||||
<Button @click="handleCLickImg('goodsGalleryFiles')" type="primary">上传图片</Button>
|
||||
<el-button @click="handleCLickImg('goodsGalleryFiles')" type="primary">上传图片</el-button>
|
||||
</div>
|
||||
<Modal v-model="goodsPictureVisible" title="View Image">
|
||||
<el-dialog v-model="goodsPictureVisible" title="View Image">
|
||||
<img v-if="goodsPictureVisible" :src="previewGoodsPicture" style="width: 100%" />
|
||||
</Modal>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div style="color: grey">主图仅支持png,jpg,jpeg格式,宽高至少600*600px,大小2M内,可拖拽调整主图顺序</div>
|
||||
</FormItem>
|
||||
<FormItem class="form-item-view-el" label="主图视频" prop="goodsVideo">
|
||||
</el-form-item>
|
||||
<el-form-item class="form-item-view-el" label="主图视频" prop="goodsVideo">
|
||||
<div class="goods-video">
|
||||
<div v-if="baseInfoForm.goodsVideo">
|
||||
<div>
|
||||
<video :src="baseInfoForm.goodsVideo" class="video" controls style="max-width: 300px;" />
|
||||
</div>
|
||||
</div>
|
||||
<Upload ref="upload" :action="uploadFileUrl" :format="['avi', 'wmv', 'mpeg', 'mp4', 'mov']"
|
||||
:headers="{ ...accessToken }" :max-size="10240" :on-error="() => { loadingVideo = false }"
|
||||
:on-exceeded-size="handleVideoMaxSize" :on-format-error="handleFormatError"
|
||||
:on-progress="() => { loadingVideo = true }" :on-success="handleSuccessGoodsVideo"
|
||||
:show-upload-list="false" multiple style="margin-left: 10px" type="drag">
|
||||
<Button :loading="loadingVideo" icon="ios-cloud-upload-outline" type="text">
|
||||
<span v-if="!loadingVideo">
|
||||
{{ baseInfoForm.goodsVideo ? "已" : "" }}上传视频
|
||||
</span>
|
||||
<span v-else>
|
||||
正在上传...
|
||||
</span>
|
||||
</Button>
|
||||
</Upload>
|
||||
<el-upload
|
||||
:action="uploadFileUrl"
|
||||
:headers="{ ...accessToken }"
|
||||
accept=".avi,.wmv,.mpeg,.mp4,.mov"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeVideoUpload"
|
||||
:on-success="handleSuccessGoodsVideo"
|
||||
:on-error="() => { loadingVideo = false }"
|
||||
style="margin-left: 10px; display: inline-block"
|
||||
>
|
||||
<el-button :loading="loadingVideo" type="primary" link>
|
||||
{{ loadingVideo ? "正在上传..." : `${baseInfoForm.goodsVideo ? "已" : ""}上传视频` }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
<div class="layout" style="width: 100%">
|
||||
<Collapse v-model="open_panel">
|
||||
<Panel name="1">
|
||||
自定义规格项
|
||||
<div slot="content">
|
||||
<Form>
|
||||
<el-collapse v-model="open_panel">
|
||||
<el-collapse-item title="自定义规格项" name="1">
|
||||
<div>
|
||||
<div v-for="(item, $index) in skuInfo" :key="$index" class="sku-item-content">
|
||||
<Card :bordered="true" class="ivu-card-body">
|
||||
<a slot="extra" style="margin-left: 6px">
|
||||
<Icon size="20" type="md-trash" @click="handleCloseSkuItem($index, item)"></Icon>
|
||||
</a>
|
||||
<el-card class="ivu-card-body">
|
||||
<template #header>
|
||||
<el-button link type="danger" @click="handleCloseSkuItem($index, item)">删除规格项</el-button>
|
||||
</template>
|
||||
<div>
|
||||
<div style="display: flex;margin-bottom: 10px;font-weight: bold">规格项</div>
|
||||
<FormItem class="sku-item-content-val flex" label="">
|
||||
<el-form-item class="sku-item-content-val flex" label="">
|
||||
|
||||
<div>
|
||||
<AutoComplete v-model="item.name" :filter-method="filterMethod" :maxlength="30"
|
||||
placeholder="请输入规格项名称" style="width: 150px" @on-focus="changeSkuItem(item.name)"
|
||||
@on-change="editSkuItem(item.name, $index, item)">
|
||||
</AutoComplete>
|
||||
<el-autocomplete
|
||||
v-model="item.name"
|
||||
:fetch-suggestions="(q, cb) => cb([])"
|
||||
maxlength="30"
|
||||
placeholder="请输入规格项名称"
|
||||
style="width: 150px"
|
||||
@focus="changeSkuItem(item.name)"
|
||||
@change="editSkuItem(item.name, $index, item)"
|
||||
/>
|
||||
|
||||
<iSwitch v-if="$index === 0" style="margin-left: 10px" size="small"
|
||||
@on-change="changeSkuOpenImage" v-model="openImage" /><span v-if="$index === 0"
|
||||
style="margin-left: 5px">添加规格图片</span>
|
||||
<el-switch
|
||||
v-if="$index === 0"
|
||||
v-model="openImage"
|
||||
style="margin-left: 10px"
|
||||
@change="changeSkuOpenImage"
|
||||
/>
|
||||
<span v-if="$index === 0" style="margin-left: 5px">添加规格图片</span>
|
||||
</div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
|
||||
</div>
|
||||
<div class="sku-val">
|
||||
<div style="margin-bottom: 10px;font-weight: bold;display: flex">规格值 (输入完成后,鼠标点击其他地方后生效)</div>
|
||||
<Form :model="item" class="flex">
|
||||
<el-form :model="item" class="flex">
|
||||
<!--规格值文本列表-->
|
||||
<FormItem v-for="(val, index) in item.spec_values" :key="index"
|
||||
<el-form-item v-for="(val, index) in item.spec_values" :key="index"
|
||||
class="sku-item-content-val flex" label="" style="line-height: 32px;">
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
|
||||
|
||||
<AutoComplete ref="input" v-model="val.value" :disabled="containsSameSkuItem"
|
||||
:filter-method="filterMethod" :maxlength="30" placeholder="请输入规格值"
|
||||
style="width: 180px" @on-focus="changeSkuVals(val, item.name)"
|
||||
@on-blur="checkSkuVal(val, $index, item)"
|
||||
@on-change="skuValueChange(val, index, item)">
|
||||
</AutoComplete>
|
||||
<a style="margin-left: 6px" >
|
||||
<Icon size="15" type="md-trash" @click="handleCloseSkuValue(val, index, item)">
|
||||
</Icon>
|
||||
</a>
|
||||
<el-autocomplete
|
||||
v-model="val.value"
|
||||
:disabled="containsSameSkuItem"
|
||||
:fetch-suggestions="(q, cb) => cb([])"
|
||||
maxlength="30"
|
||||
placeholder="请输入规格值"
|
||||
style="width: 180px"
|
||||
@focus="changeSkuVals(val, item.name)"
|
||||
@blur="checkSkuVal(val, $index, item)"
|
||||
@change="skuValueChange(val, index, item)"
|
||||
/>
|
||||
<el-button link type="danger" style="margin-left: 6px" @click="handleCloseSkuValue(val, index, item)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 内联错误提示 -->
|
||||
@@ -231,205 +251,251 @@
|
||||
<img :src="img" style="width: 180px;height: 140px" />
|
||||
<div class="sku-upload-list-cover">
|
||||
<div style="margin-top: 50px">
|
||||
<Icon size="25" type="md-search" @click="handleView(img)"></Icon>
|
||||
<Icon size="25" type="md-trash" @click="handleRemove(val.images, __index)">
|
||||
</Icon>
|
||||
<el-icon :size="25" style="cursor:pointer;margin-right:8px" @click="handleView(img)"><ZoomIn /></el-icon>
|
||||
<el-icon :size="25" style="cursor:pointer" @click="handleRemove(val.images, __index)"><Delete /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
<Upload ref="uploadSku" :action="uploadFileUrl" v-if="val.images < 1"
|
||||
:before-upload="handleBeforeUpload" :format="['jpg', 'jpeg', 'png', 'webp']"
|
||||
:headers="{ ...accessToken }" :max-size="2048" :on-error="() => { $Spin.hide(); }"
|
||||
:on-exceeded-size="handleMaxSize" :on-format-error="handleFormatError"
|
||||
:on-progress="() => { $Spin.show(); }" :on-success="(res, file) => {
|
||||
handleSuccess(res, file, val.images)
|
||||
}" :show-upload-list="false" style="width: 180px;height: 140px;margin-right: 10px"
|
||||
type="drag">
|
||||
<div>
|
||||
<Icon size="136" type="ios-camera"></Icon>
|
||||
</div>
|
||||
</Upload>
|
||||
<el-upload
|
||||
v-if="val.images.length < 1"
|
||||
:action="uploadFileUrl"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:headers="{ ...accessToken }"
|
||||
:on-error="() => {}"
|
||||
:on-exceeded-size="handleMaxSize"
|
||||
:on-success="(res, file) => handleSuccess(res, file, val.images)"
|
||||
:show-file-list="false"
|
||||
accept=".jpg,.jpeg,.png,.webp"
|
||||
drag
|
||||
style="width: 180px;height: 140px;margin-right: 10px"
|
||||
>
|
||||
<el-icon :size="40"><Camera /></el-icon>
|
||||
</el-upload>
|
||||
</div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
|
||||
<FormItem
|
||||
<el-form-item
|
||||
v-if="item.spec_values.length < 10 && item.spec_values.length >= 1 && item.spec_values[0].value !== ''"
|
||||
class="sku-item-content-val flex" label="" style="line-height: 32px;">
|
||||
<AutoComplete ref="input" v-model="newSkuValues[$index]" :disabled="containsSameSkuItem"
|
||||
:filter-method="filterMethod" :maxlength="30" placeholder="自定义规格值"
|
||||
style="width: 180px" @on-blur="addSpec($index, item)"
|
||||
v-on:keyup.native.enter="addSpec($index, item)">
|
||||
</AutoComplete>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<el-autocomplete
|
||||
v-model="newSkuValues[$index]"
|
||||
:disabled="containsSameSkuItem"
|
||||
:fetch-suggestions="(q, cb) => cb([])"
|
||||
maxlength="30"
|
||||
placeholder="自定义规格值"
|
||||
style="width: 180px"
|
||||
@blur="addSpec($index, item)"
|
||||
@keyup.enter="addSpec($index, item)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</Form>
|
||||
<div style="display: flex">
|
||||
<Button class="add-sku-btn" type="primary" @click="addSkuItem">添加规格项
|
||||
</Button>
|
||||
<el-button class="add-sku-btn" type="primary" @click="addSkuItem">添加规格项
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- <Button class="add-sku-btn" size="small" type="warning" @click="handleClearSku">清空规格项-->
|
||||
<!-- </Button>-->
|
||||
</div>
|
||||
</Panel>
|
||||
<Panel name="2">
|
||||
规格详细
|
||||
<div slot="content">
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="规格详细" name="2">
|
||||
<div v-if="needToloadSku" class="topinfo" @click="handleLoadingSkuData">点击加载sku数据</div>
|
||||
<div slot="content" :class="needToloadSku ? 'mask' : ''">
|
||||
<Table :columns="skuTableColumn" :data="skuTableData" class="mt_10" style="
|
||||
width: 100%;
|
||||
.ivu-table-overflowX {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
">
|
||||
<template slot="sn" slot-scope="{ row }">
|
||||
<Input v-model="row.sn" clearable placeholder="请输入货号"
|
||||
@on-change="updateSkuTable(row, 'sn')" />
|
||||
</template>
|
||||
<div v-if="baseInfoForm.goodsType !== 'VIRTUAL_GOODS'" slot="weight" slot-scope="{ row }">
|
||||
<Input v-model="row.weight" clearable placeholder="请输入重量"
|
||||
@on-change="updateSkuTable(row, 'weight')">
|
||||
<span slot="append">kg</span>
|
||||
</Input>
|
||||
</div>
|
||||
<template slot="quantity" slot-scope="{ row }">
|
||||
<Input v-model="row.quantity" clearable placeholder="请输入库存"
|
||||
@on-change="updateSkuTable(row, 'quantity')">
|
||||
<span slot="append">{{
|
||||
baseInfoForm.goodsUnit || ""
|
||||
}}</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot="cost" slot-scope="{ row }">
|
||||
<Input v-model="row.cost" clearable placeholder="请输入成本价"
|
||||
@on-change="updateSkuTable(row, 'cost')">
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot="price" slot-scope="{ row }">
|
||||
<Input v-model="row.price" clearable placeholder="请输入价格"
|
||||
@on-change="updateSkuTable(row, 'price')">
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot="wholePrice0" slot-scope="{ row }">
|
||||
<Input v-if="wholesaleData[0]" v-model="wholesaleData[0].price" clearable disabled>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot="wholePrice1" slot-scope="{ row }">
|
||||
<Input v-if="wholesaleData[1]" v-model="wholesaleData[1].price" clearable disabled>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot="wholePrice2" slot-scope="{ row }">
|
||||
<Input v-if="wholesaleData[2]" v-model="wholesaleData[2].price" clearable disabled>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
</Table>
|
||||
<div :class="needToloadSku ? 'mask' : ''">
|
||||
<el-table :data="skuTableData" border class="mt_10" style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="(col, colIndex) in skuTableColumn"
|
||||
:key="colIndex"
|
||||
:label="col.title"
|
||||
:prop="col.key"
|
||||
min-width="120"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span v-if="col.key && !col.slot">{{ row[col.key] }}</span>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'sn'"
|
||||
v-model="row.sn"
|
||||
clearable
|
||||
placeholder="请输入货号"
|
||||
@change="updateSkuTable(row, 'sn')"
|
||||
/>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'weight' && baseInfoForm.goodsType !== 'VIRTUAL_GOODS'"
|
||||
v-model="row.weight"
|
||||
clearable
|
||||
placeholder="请输入重量"
|
||||
@change="updateSkuTable(row, 'weight')"
|
||||
>
|
||||
<template #append>kg</template>
|
||||
</el-input>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'quantity'"
|
||||
v-model="row.quantity"
|
||||
clearable
|
||||
placeholder="请输入库存"
|
||||
@change="updateSkuTable(row, 'quantity')"
|
||||
>
|
||||
<template #append>{{ baseInfoForm.goodsUnit || "" }}</template>
|
||||
</el-input>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'cost'"
|
||||
v-model="row.cost"
|
||||
clearable
|
||||
placeholder="请输入成本价"
|
||||
@change="updateSkuTable(row, 'cost')"
|
||||
>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'price'"
|
||||
v-model="row.price"
|
||||
clearable
|
||||
placeholder="请输入价格"
|
||||
@change="updateSkuTable(row, 'price')"
|
||||
>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'wholePrice0' && wholesaleData[0]"
|
||||
v-model="wholesaleData[0].price"
|
||||
disabled
|
||||
>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'wholePrice1' && wholesaleData[1]"
|
||||
v-model="wholesaleData[1].price"
|
||||
disabled
|
||||
>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
<el-input
|
||||
v-else-if="col.slot === 'wholePrice2' && wholesaleData[2]"
|
||||
v-model="wholesaleData[2].price"
|
||||
disabled
|
||||
>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</div>
|
||||
<h4 v-if="showContent">规格描述内容</h4>
|
||||
<div v-if="showContent" class="form-item-view">
|
||||
<div>
|
||||
<FormItem :label="contentImage" class="form-item-view-el">
|
||||
<el-form-item :label="contentImage" class="form-item-view-el">
|
||||
<!-- {{item.url}} -->
|
||||
<div v-for="(item, index) in listImages.images" :key="index" style="width:100%;display:flex;">
|
||||
<img :src="item.url" style="width:100px;flex:1;margin-top:10px;cursor:pointer;"
|
||||
@click="handleView(item.url)" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<h4>商品详情描述</h4>
|
||||
<div class="form-item-view">
|
||||
<div class="tree-bar">
|
||||
<FormItem class="form-item-view-el" label="店内分类" prop="shopCategory">
|
||||
<Tree ref="tree" :check-strictly="false" :data="shopCategory" show-checkbox style="text-align: left"
|
||||
@on-select-change="selectTree" @on-check-change="changeSelect"></Tree>
|
||||
</FormItem>
|
||||
<el-form-item class="form-item-view-el" label="店内分类" prop="shopCategory">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
:data="shopCategory"
|
||||
show-checkbox
|
||||
node-key="id"
|
||||
:props="{ label: 'title', children: 'children' }"
|
||||
style="text-align: left"
|
||||
@node-click="(data) => selectTree([data])"
|
||||
@check="(_, ctx) => changeSelect(ctx.checkedNodes)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<FormItem class="form-item-view-el" label="PC商品描述" prop="intro" style="width: 100%">
|
||||
<el-form-item class="form-item-view-el" label="PC商品描述" prop="intro" style="width: 100%">
|
||||
<editor ref="editor" v-model="baseInfoForm.intro" height="800px" openXss></editor>
|
||||
<div class="promise-intro-btn">
|
||||
<Button type="primary" @click="promiseIntroEditor">将PC商品描述同步到移动端描述
|
||||
</Button>
|
||||
<el-button type="primary" @click="promiseIntroEditor">将PC商品描述同步到移动端描述
|
||||
</el-button>
|
||||
</div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
|
||||
<FormItem class="form-item-view-el" label="移动端描述" prop="skuList" style="width: 100%">
|
||||
<el-form-item class="form-item-view-el" label="移动端描述" prop="skuList" style="width: 100%">
|
||||
<editor ref="introEditor" v-model="baseInfoForm.mobileIntro" height="800px" openXss></editor>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-if="baseInfoForm.goodsType != 'VIRTUAL_GOODS'">
|
||||
<h4>商品物流信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem class="form-item-view-el" label="物流模板" prop="templateId">
|
||||
<Select v-model="baseInfoForm.templateId" style="width: 200px">
|
||||
<Option v-for="item in logisticsTemplate" :key="item.id" :value="item.id">{{ item.name }}
|
||||
</Option>
|
||||
</Select>
|
||||
<Button class="refresh-icon" icon="md-refresh" shape="circle" type="text"
|
||||
@click="refresh('template')"></Button>
|
||||
</FormItem>
|
||||
<FormItem v-if="baseInfoForm.salesModel == 'WHOLESALE'" class="form-item-view-el" label="商品重量"
|
||||
<el-form-item class="form-item-view-el" label="物流模板" prop="templateId">
|
||||
<el-select v-model="baseInfoForm.templateId" style="width: 200px">
|
||||
<el-option v-for="item in logisticsTemplate" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-button class="refresh-icon" circle link @click="refresh('template')">
|
||||
<el-icon><Refresh /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="baseInfoForm.salesModel == 'WHOLESALE'" class="form-item-view-el" label="商品重量"
|
||||
prop="weight">
|
||||
<Input v-model="baseInfoForm.weight" placeholder="请输入商品重量">
|
||||
<span slot="append">kg</span></Input>
|
||||
</FormItem>
|
||||
<el-input v-model="baseInfoForm.weight" placeholder="请输入商品重量">
|
||||
<template #append>kg</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<h4>参数信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem v-for="(paramsItem, paramsIndex) in goodsParams" :key="paramsItem.id || paramsIndex"
|
||||
<el-form-item v-for="(paramsItem, paramsIndex) in goodsParams" :key="paramsItem.id || paramsIndex"
|
||||
:label="`${paramsItem.paramName}:`"
|
||||
:prop="`goodsParams.${paramsIndex}.paramValue`"
|
||||
:rules="paramsItem.required ? { required: true, message: `${paramsItem.paramName}不能为空`, trigger: 'change' } : {}">
|
||||
<Select v-model="baseInfoForm.goodsParams[paramsIndex].paramValue" clearable placeholder="请选择" style="width: 200px"
|
||||
@on-change="(val) => selectParams(paramsItem, val, paramsIndex)">
|
||||
<Option v-for="option in getParamOptions(paramsItem.options)" :key="option" :label="option"
|
||||
:value="option">
|
||||
</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<el-select v-model="baseInfoForm.goodsParams[paramsIndex].paramValue" clearable placeholder="请选择" style="width: 200px"
|
||||
@change="(val) => selectParams(paramsItem, val, paramsIndex)">
|
||||
<el-option
|
||||
v-for="option in getParamOptions(paramsItem.options)"
|
||||
:key="option"
|
||||
:label="option"
|
||||
:value="option"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</el-form>
|
||||
</div>
|
||||
<!-- 底部按钮 -->
|
||||
<div class="footer">
|
||||
<ButtonGroup>
|
||||
<Button type="primary" @click="pre">上一步</Button>
|
||||
<Button :loading="submitLoading" type="primary" @click="save">
|
||||
<div class="footer-btns">
|
||||
<el-button type="primary" @click="pre">上一步</el-button>
|
||||
<el-button :loading="submitLoading" type="primary" @click="save">
|
||||
{{ this.$route.query.id ? "保存" : "保存商品" }}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal v-model="showGoodsVideo" title="查看视频">
|
||||
<el-dialog v-model="showGoodsVideo" title="查看视频">
|
||||
<div id="dplayer">
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
|
||||
<!--<Modal width="1200px" v-model="picModelFlag">-->
|
||||
<!--<el-dialog width="1200px" v-model="picModelFlag">-->
|
||||
<!--<ossManage @callback="callbackSelected" ref="ossManage" />-->
|
||||
<!--</Modal>-->
|
||||
<Modal v-model="picModelFlag" width="1200px" @on-ok="confirmUrls">
|
||||
<ossManage ref="ossManage" :isComponent="true" :initialize="picModelFlag" @callback="callbackSelected"
|
||||
@selected="(list) => { selectedImage = list }" />
|
||||
</Modal>
|
||||
<!--</el-dialog>-->
|
||||
<el-dialog v-model="picModelFlag" width="1200px" title="选择图片" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
:isComponent="true"
|
||||
:initialize="picModelFlag"
|
||||
@callback="callbackSelected"
|
||||
@selected="(list) => { selectedImage = list }"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="picModelFlag = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmUrls">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
@@ -437,6 +503,7 @@
|
||||
import * as API_GOODS from "@/api/goods";
|
||||
import * as API_Shop from "@/api/shops";
|
||||
import cloneObj from "@/utils/index";
|
||||
import { Camera, Delete, Plus, Refresh, ZoomIn } from "@element-plus/icons-vue";
|
||||
import vuedraggable from "vuedraggable";
|
||||
import tinymec from "@/views/lili-components/editor/index.vue";
|
||||
|
||||
@@ -450,9 +517,14 @@ import ossManage from "@/views/shop/ossManages";
|
||||
export default {
|
||||
name: "goodsOperationSec",
|
||||
components: {
|
||||
Camera,
|
||||
Delete,
|
||||
Plus,
|
||||
Refresh,
|
||||
ZoomIn,
|
||||
editor: tinymec,
|
||||
vuedraggable,
|
||||
ossManage
|
||||
ossManage,
|
||||
},
|
||||
props: {
|
||||
firstData: {
|
||||
@@ -745,21 +817,21 @@ export default {
|
||||
},
|
||||
selectParams(params, value, paramsIndex) {
|
||||
if (!Array.isArray(this.baseInfoForm.goodsParamsDTOList)) {
|
||||
this.$set(this.baseInfoForm, "goodsParamsDTOList", []);
|
||||
this.baseInfoForm.goodsParamsDTOList = [];
|
||||
}
|
||||
|
||||
// 确保baseInfoForm.goodsParams存在
|
||||
if (!Array.isArray(this.baseInfoForm.goodsParams)) {
|
||||
this.$set(this.baseInfoForm, "goodsParams", []);
|
||||
this.baseInfoForm.goodsParams = [];
|
||||
}
|
||||
|
||||
// 确保对应索引的参数项存在
|
||||
if (!this.baseInfoForm.goodsParams[paramsIndex]) {
|
||||
this.$set(this.baseInfoForm.goodsParams, paramsIndex, {});
|
||||
this.baseInfoForm.goodsParams[paramsIndex] = {};
|
||||
}
|
||||
|
||||
// 更新baseInfoForm中的值用于验证
|
||||
this.$set(this.baseInfoForm.goodsParams[paramsIndex], 'paramValue', value || '');
|
||||
this.baseInfoForm.goodsParams[paramsIndex].paramValue = value || '';
|
||||
|
||||
const list = this.baseInfoForm.goodsParamsDTOList;
|
||||
const paramId = params && params.id ? String(params.id) : "";
|
||||
@@ -770,7 +842,7 @@ export default {
|
||||
list.splice(index, 1);
|
||||
}
|
||||
// 清空表单项的值
|
||||
this.$set(params, 'paramValue', '');
|
||||
params.paramValue = '';
|
||||
return;
|
||||
}
|
||||
const newItem = {
|
||||
@@ -783,13 +855,13 @@ export default {
|
||||
};
|
||||
|
||||
if (index >= 0) {
|
||||
this.$set(list, index, newItem);
|
||||
list[index] = newItem;
|
||||
} else {
|
||||
list.push(newItem);
|
||||
}
|
||||
|
||||
// 同步更新表单项的值
|
||||
this.$set(params, 'paramValue', value);
|
||||
params.paramValue = value;
|
||||
},
|
||||
// 编辑sku图片
|
||||
editSkuPicture(row) {
|
||||
@@ -844,7 +916,6 @@ export default {
|
||||
},
|
||||
// sku图片上传成功
|
||||
handleSuccess(res, file, images) {
|
||||
this.$Spin.hide();
|
||||
if (file.response) {
|
||||
file.url = file.response.result;
|
||||
if (images) {
|
||||
@@ -942,7 +1013,6 @@ export default {
|
||||
},
|
||||
// 商品图片上传成功
|
||||
handleSuccessGoodsPicture(res, file) {
|
||||
this.$Spin.hide();
|
||||
if (file.response) {
|
||||
file.url = file.response.result;
|
||||
this.baseInfoForm.goodsGalleryFiles.push(file.url);
|
||||
@@ -1263,11 +1333,11 @@ export default {
|
||||
.sort((a, b) => Number(a.sort || 0) - Number(b.sort || 0));
|
||||
|
||||
// 初始化baseInfoForm.goodsParams用于表单验证
|
||||
this.$set(this.baseInfoForm, 'goodsParams', []);
|
||||
this.baseInfoForm.goodsParams = [];
|
||||
this.goodsParams.forEach((param, index) => {
|
||||
this.$set(this.baseInfoForm.goodsParams, index, {
|
||||
this.baseInfoForm.goodsParams[index] = {
|
||||
paramValue: param.paramValue || ''
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
// 确保表单验证能正确初始化
|
||||
@@ -1297,8 +1367,7 @@ export default {
|
||||
this.$Message.error("规格项不能为空!");
|
||||
return;
|
||||
}
|
||||
// 写入对象,下标,具体对象
|
||||
this.$set(this.skuInfo, this.skuInfo.length, {
|
||||
this.skuInfo.push({
|
||||
spec_values: [{ name: "", value: "", images: [] }],
|
||||
name: "",
|
||||
});
|
||||
@@ -1420,7 +1489,7 @@ export default {
|
||||
checkSkuVal(val, groupIndex, spec) {
|
||||
if (val.value === "") {
|
||||
// 内联错误提示,不使用弹窗
|
||||
this.$set(val, '_error', '规格值不能为空!');
|
||||
val._error = '规格值不能为空!';
|
||||
|
||||
// 如果规格项和规格名称存在,从表格数据中移除包含该空规格值的行
|
||||
if (spec && spec.name && this.skuInfo[groupIndex]) {
|
||||
@@ -1568,7 +1637,7 @@ export default {
|
||||
} else {
|
||||
itemValue.images = this.baseInfoForm.goodsGalleryFiles
|
||||
}
|
||||
this.$set(item.spec_values, item.spec_values.length, itemValue);
|
||||
item.spec_values.push(itemValue);
|
||||
|
||||
// 生成新的规格组合
|
||||
const newCombinations = this.generateSkuCombinations(this.skuInfo);
|
||||
@@ -1952,7 +2021,8 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
this.skuTableData[index][item] = row[item];
|
||||
});
|
||||
// this.$set(this.skuTableData,[index][item],row[item])
|
||||
// // migrated
|
||||
(this.skuTableData,[index][item],row[item])
|
||||
},
|
||||
// 店内分类选择
|
||||
selectTree(v) {
|
||||
|
||||
@@ -11,7 +11,7 @@ h4 {
|
||||
margin: 20px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
::v-deep .ivu-icon {
|
||||
:deep(.el-icon) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.rate-box {
|
||||
@@ -82,7 +82,7 @@ h4 {
|
||||
font-weight: bold;
|
||||
width: 286px;
|
||||
display: flex;
|
||||
::v-deep span {
|
||||
:deep(span) {
|
||||
color: $theme_color;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@@ -1,58 +1,72 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<Modal v-model="noticeFlage" :title="noticesDetail.title">
|
||||
<div v-if="noticesDetail" class="noticesDetail" v-html="noticesDetail.content">
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
<el-dialog v-model="noticeFlage" :title="noticesDetail.title">
|
||||
<div v-if="noticesDetail" class="noticesDetail" v-html="noticesDetail.content"></div>
|
||||
</el-dialog>
|
||||
<div class="box flex">
|
||||
<div class="box-left">
|
||||
<div class="card shop flex">
|
||||
<div>
|
||||
<h4>Hi,<span style="margin-left:5px;">{{ userData.nickName }}</span></h4>
|
||||
<img class="shop-logo" :src="userData.storeLogo || require('@/assets/logo1.png')" alt="">
|
||||
<h4>Hi,<span style="margin-left: 5px">{{ userData.nickName }}</span></h4>
|
||||
<img
|
||||
class="shop-logo"
|
||||
:src="userData.storeLogo || require('@/assets/logo1.png')"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div class="shop-box">
|
||||
<div class="box-item">
|
||||
<div>店铺名称:{{ userData.storeName || '暂无' }}</div>
|
||||
<div>店铺名称:{{ userData.storeName || "暂无" }}</div>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<div>店铺状态:{{ userData.storeDisable == 'OPEN' ? '开启中' : '关闭' }}</div>
|
||||
<div>店铺状态:{{ userData.storeDisable == "OPEN" ? "开启中" : "关闭" }}</div>
|
||||
</div>
|
||||
<div class="box-item" @click="im()">
|
||||
<Button type="info" :loading='load'>点击登录客服</Button>
|
||||
<el-button type="info" :loading="load">点击登录客服</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rate-box">
|
||||
<div>
|
||||
<i-circle :size="120" stroke-color="#fecb89" :trail-width="4" :stroke-width="5"
|
||||
:percent="(userData.serviceScore * 20)" stroke-linecap="square">
|
||||
<div class="demo-Circle-custom">
|
||||
|
||||
<el-progress
|
||||
type="circle"
|
||||
:width="120"
|
||||
:stroke-width="5"
|
||||
:percentage="userData.serviceScore * 20"
|
||||
color="#fecb89"
|
||||
>
|
||||
<template #default>
|
||||
<p class="bold">{{ userData.serviceScore }}分</p>
|
||||
</div>
|
||||
</i-circle>
|
||||
</template>
|
||||
</el-progress>
|
||||
<h5>服务得分</h5>
|
||||
</div>
|
||||
<div>
|
||||
<i-circle :size="120" stroke-color="#a7c5eb" :trail-width="4" :stroke-width="5"
|
||||
:percent="(userData.deliveryScore * 20)" stroke-linecap="square">
|
||||
<div>
|
||||
|
||||
<el-progress
|
||||
type="circle"
|
||||
:width="120"
|
||||
:stroke-width="5"
|
||||
:percentage="userData.deliveryScore * 20"
|
||||
color="#a7c5eb"
|
||||
>
|
||||
<template #default>
|
||||
<p class="bold">{{ userData.deliveryScore }}分</p>
|
||||
</div>
|
||||
</i-circle>
|
||||
</template>
|
||||
</el-progress>
|
||||
<h5>交货得分</h5>
|
||||
</div>
|
||||
<div>
|
||||
<i-circle :size="120" stroke-color="#848ccf" :trail-width="4" :stroke-width="5"
|
||||
:percent="(userData.descriptionScore * 20)" stroke-linecap="square">
|
||||
<div>
|
||||
<el-progress
|
||||
type="circle"
|
||||
:width="120"
|
||||
:stroke-width="5"
|
||||
:percentage="userData.descriptionScore * 20"
|
||||
color="#848ccf"
|
||||
>
|
||||
<template #default>
|
||||
<p class="bold">{{ userData.descriptionScore }}分</p>
|
||||
</div>
|
||||
</i-circle>
|
||||
</template>
|
||||
</el-progress>
|
||||
<h5>评价得分</h5>
|
||||
</div>
|
||||
</div>
|
||||
@@ -66,9 +80,7 @@
|
||||
<span>{{ homeData.unPaidOrder || 0 }}</span>
|
||||
<div>待付款</div>
|
||||
</div>
|
||||
<div class="detail-title">
|
||||
交易前
|
||||
</div>
|
||||
<div class="detail-title">交易前</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-item" @click="navigateTo('orderList')">
|
||||
@@ -80,9 +92,7 @@
|
||||
<span>{{ homeData.deliveredOrder || 0 }}</span>
|
||||
<div>待收货</div>
|
||||
</div>
|
||||
<div class="detail-title">
|
||||
交易中
|
||||
</div>
|
||||
<div class="detail-title">交易中</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div @click="navigateTo('returnMoneyOrder')">
|
||||
@@ -97,21 +107,16 @@
|
||||
<span>{{ homeData.memberEvaluation || 0 }}</span>
|
||||
<div>待评价</div>
|
||||
</div>
|
||||
<div class="detail-title">
|
||||
交易后
|
||||
</div>
|
||||
<div class="detail-title">交易后</div>
|
||||
</div>
|
||||
<div class="detail-item" @click="navigateTo('orderComplaint')">
|
||||
<div>
|
||||
<span>{{ homeData.complaint || 0 }}</span>
|
||||
<div>待处理</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-title">
|
||||
投诉
|
||||
</div>
|
||||
<div class="detail-title">投诉</div>
|
||||
</div>
|
||||
<div class="detail-item" >
|
||||
<div class="detail-item">
|
||||
<div @click="navigateTo('alert-goods-quantity')">
|
||||
<span>{{ homeData.alertQuantityNum || 0 }}</span>
|
||||
<div>库存预警</div>
|
||||
@@ -120,9 +125,7 @@
|
||||
<span>{{ homeData.waitAuth || 0 }}</span>
|
||||
<div>审核中</div>
|
||||
</div>
|
||||
<div class="detail-title">
|
||||
商品
|
||||
</div>
|
||||
<div class="detail-title">商品</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
@@ -134,15 +137,11 @@
|
||||
<span>{{ homeData.waitPayBill || 0 }}</span>
|
||||
<div>等待对账</div>
|
||||
</div>
|
||||
<div class="detail-title">
|
||||
其他
|
||||
</div>
|
||||
<div class="detail-title">其他</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 公告 -->
|
||||
<div class="card box-right">
|
||||
<h4>平台公告</h4>
|
||||
<div>
|
||||
@@ -153,49 +152,46 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card ">
|
||||
<div class="card">
|
||||
<h4>统计数据</h4>
|
||||
<div class="count-list flex">
|
||||
<div class="count-item" @click="navigateTo('goods')">
|
||||
<div>
|
||||
<Icon class="icon" size="31" type="md-photos" />
|
||||
<el-icon class="icon" :size="31"><Picture /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.goodsNum || 0 }}</div>
|
||||
<div>上架商品数量</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="count-item" @click="navigateTo('orderStatistics')">
|
||||
<div>
|
||||
<Icon class="icon" size="31" type="ios-card" />
|
||||
<el-icon class="icon" :size="31"><CreditCard /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.orderPrice || 0 | unitPrice('¥') }}</div>
|
||||
<div class="counts">
|
||||
{{ $filters.unitPrice(homeData.orderPrice || 0, "¥") }}
|
||||
</div>
|
||||
<div>今日订单总额</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="count-item" @click="navigateTo('orderList')">
|
||||
<div>
|
||||
|
||||
<Icon class="icon" size="31" type="md-list" />
|
||||
<el-icon class="icon" :size="31"><List /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.orderNum || 0 }}</div>
|
||||
<div>今日订单数量</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="count-item" @click="navigateTo('trafficStatistics')">
|
||||
<div>
|
||||
<Icon class="icon" size="31" type="md-person" />
|
||||
<el-icon class="icon" :size="31"><User /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.storeUV || 0 }}</div>
|
||||
<div>今日访客数量</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,99 +199,90 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Picture, CreditCard, List, User } from "@element-plus/icons-vue";
|
||||
import { getSellerHomeData, getHomeNotice } from "@/api/index";
|
||||
import { getIMDetail } from "@/api/common"
|
||||
import { getIMDetail } from "@/api/common";
|
||||
import { seeArticle } from "@/api/pages";
|
||||
import Cookies from "js-cookie";
|
||||
import { userMsg } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
data () {
|
||||
components: {
|
||||
Picture,
|
||||
CreditCard,
|
||||
List,
|
||||
User,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
noticeFlage: false, // 控制平台公告显隐
|
||||
|
||||
homeData: {}, // 首页数据
|
||||
userData: "", // 店铺信息
|
||||
notices: "", // 平台公告列表
|
||||
noticesDetail: { // 平台公告详情
|
||||
noticeFlage: false,
|
||||
homeData: {},
|
||||
userData: "",
|
||||
notices: "",
|
||||
noticesDetail: {
|
||||
title: "",
|
||||
},
|
||||
IMLink: "",
|
||||
load:false, //加载Im
|
||||
load: false,
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 跳转页面
|
||||
navigateTo (name) {
|
||||
this.$router.push({
|
||||
name,
|
||||
});
|
||||
navigateTo(name) {
|
||||
this.$router.push({ name });
|
||||
},
|
||||
// 初始化数据
|
||||
async init () {
|
||||
let userInfo = JSON.parse(Cookies.get("userInfoSeller"));
|
||||
|
||||
async init() {
|
||||
const userInfo = JSON.parse(Cookies.get("userInfoSeller"));
|
||||
this.userData = userInfo;
|
||||
|
||||
let res = await getHomeNotice();
|
||||
const res = await getHomeNotice();
|
||||
if (res.success) {
|
||||
this.notices = res.result.records;
|
||||
}
|
||||
},
|
||||
// 跳转文章页
|
||||
async clickLinkNotices (val) {
|
||||
let res = await seeArticle(val.id);
|
||||
async clickLinkNotices(val) {
|
||||
const res = await seeArticle(val.id);
|
||||
if (res.success) {
|
||||
this.noticesDetail = res.result;
|
||||
this.noticeFlage = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击登录im的时候需要去判断一下当前店铺信息是否失效
|
||||
* 失效的话重新请求刷新token保证最新的token去访问im
|
||||
*/
|
||||
async im () {
|
||||
// 获取访问Token
|
||||
let accessToken = this.getStore("accessToken");
|
||||
this.load = true
|
||||
async im() {
|
||||
const accessToken = this.getStore("accessToken");
|
||||
this.load = true;
|
||||
await this.getIMDetailMethods();
|
||||
const userInfo = await userMsg();
|
||||
this.load = false
|
||||
this.load = false;
|
||||
if (userInfo.success && this.IMLink) {
|
||||
window.open(`${this.IMLink}?token=` + accessToken);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
this.$Message.error("请登录后再联系客服");
|
||||
}
|
||||
},
|
||||
|
||||
// 获取im信息
|
||||
async getIMDetailMethods () {
|
||||
let res = await getIMDetail();
|
||||
async getIMDetailMethods() {
|
||||
const res = await getIMDetail();
|
||||
if (res.success) {
|
||||
this.IMLink = res.result;
|
||||
}
|
||||
},
|
||||
// 获取首页数据
|
||||
async getHomeData () {
|
||||
let res = await getSellerHomeData();
|
||||
async getHomeData() {
|
||||
const res = await getSellerHomeData();
|
||||
if (res.success) {
|
||||
this.homeData = res.result;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.init();
|
||||
this.getHomeData();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "./home.scss";
|
||||
.noticesDetail{
|
||||
::v-deep img{
|
||||
.noticesDetail {
|
||||
:deep(img) {
|
||||
max-width: 100%;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
@@ -1,89 +1,85 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="breadcrumb">
|
||||
<span @click="clickBreadcrumb(item, index)" :class="{ 'active': item.selected }" v-for="(item, index) in dateList"
|
||||
:key="index"> {{ item.title }}</span>
|
||||
<span
|
||||
v-for="(item, index) in dateList"
|
||||
:key="index"
|
||||
:class="{ active: item.selected }"
|
||||
@click="clickBreadcrumb(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</span>
|
||||
<div class="date-picker">
|
||||
<Select @on-change="changeSelect($event, selectedWay)" :value="month" placeholder="年月查询"
|
||||
style="width:200px;margin-left:10px;">
|
||||
<Option v-for="(item, index) in dates" :value="item.year + '-' + item.month" :key="index">{{
|
||||
item.year + '年' + item.month + '月' }}</Option>
|
||||
</Select>
|
||||
<el-select
|
||||
v-model="month"
|
||||
placeholder="年月查询"
|
||||
clearable
|
||||
style="width: 200px; margin-left: 10px"
|
||||
@change="changeSelect"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, i) in dates"
|
||||
:key="i"
|
||||
:label="item.year + '年' + item.month + '月'"
|
||||
:value="item.year + '-' + item.month"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div v-if="!closeShop" class="shop-list">
|
||||
<el-select
|
||||
v-model="storeId"
|
||||
placeholder="店铺查询"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px; margin-left: 10px"
|
||||
@change="changeshop"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in shopsData"
|
||||
:key="index"
|
||||
:label="item.storeName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getShopListData } from "@/api/shops.js";
|
||||
|
||||
export default {
|
||||
props: ["closeShop"],
|
||||
data() {
|
||||
return {
|
||||
month: "", // 月份
|
||||
|
||||
month: "",
|
||||
selectedWay: {
|
||||
// 可选时间项
|
||||
title: "过去7天",
|
||||
selected: true,
|
||||
searchType: "LAST_SEVEN",
|
||||
},
|
||||
storeId: "", // 店铺id
|
||||
dates: [], // 日期列表
|
||||
storeId: "",
|
||||
dates: [],
|
||||
params: {
|
||||
// 请求参数
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 100,
|
||||
storeName: "",
|
||||
},
|
||||
dateList: [
|
||||
// 筛选条件
|
||||
{
|
||||
title: "今天",
|
||||
selected: false,
|
||||
searchType: "TODAY",
|
||||
},
|
||||
{
|
||||
title: "昨天",
|
||||
selected: false,
|
||||
searchType: "YESTERDAY",
|
||||
},
|
||||
{
|
||||
title: "过去7天",
|
||||
selected: true,
|
||||
searchType: "LAST_SEVEN",
|
||||
},
|
||||
{
|
||||
title: "过去30天",
|
||||
selected: false,
|
||||
searchType: "LAST_THIRTY",
|
||||
},
|
||||
{ title: "今天", selected: false, searchType: "TODAY" },
|
||||
{ title: "昨天", selected: false, searchType: "YESTERDAY" },
|
||||
{ title: "过去7天", selected: true, searchType: "LAST_SEVEN" },
|
||||
{ title: "过去30天", selected: false, searchType: "LAST_THIRTY" },
|
||||
],
|
||||
originDateList: [
|
||||
// 筛选条件
|
||||
{
|
||||
title: "今天",
|
||||
selected: false,
|
||||
searchType: "TODAY",
|
||||
},
|
||||
{
|
||||
title: "昨天",
|
||||
selected: false,
|
||||
searchType: "YESTERDAY",
|
||||
},
|
||||
{
|
||||
title: "过去7天",
|
||||
selected: true,
|
||||
searchType: "LAST_SEVEN",
|
||||
},
|
||||
{
|
||||
title: "过去30天",
|
||||
selected: false,
|
||||
searchType: "LAST_THIRTY",
|
||||
},
|
||||
{ title: "今天", selected: false, searchType: "TODAY" },
|
||||
{ title: "昨天", selected: false, searchType: "YESTERDAY" },
|
||||
{ title: "过去7天", selected: true, searchType: "LAST_SEVEN" },
|
||||
{ title: "过去30天", selected: false, searchType: "LAST_THIRTY" },
|
||||
],
|
||||
|
||||
shopTotal: "", // 店铺总数
|
||||
shopsData: [], // 店铺数据
|
||||
shopTotal: 0,
|
||||
shopsData: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -91,58 +87,35 @@ export default {
|
||||
this.getShopList();
|
||||
},
|
||||
methods: {
|
||||
// 页面触底
|
||||
handleReachBottom() {
|
||||
setTimeout(() => {
|
||||
if (this.params.pageNumber * this.params.pageSize <= this.shopTotal) {
|
||||
this.params.pageNumber++;
|
||||
this.getShopList();
|
||||
}
|
||||
}, 1500);
|
||||
},
|
||||
// 查询店铺列表
|
||||
getShopList() {
|
||||
getShopListData(this.params).then((res) => {
|
||||
if (res.success) {
|
||||
/**
|
||||
* 解决数据请求中,滚动栏会一直上下跳动
|
||||
*/
|
||||
this.shopTotal = res.result.total;
|
||||
|
||||
this.shopsData.push(...res.result.records);
|
||||
this.shopsData = res.result.records || [];
|
||||
}
|
||||
});
|
||||
},
|
||||
// 变更店铺
|
||||
changeshop(val) {
|
||||
changeshop() {
|
||||
this.selectedWay.storeId = this.storeId;
|
||||
this.$emit("selected", this.selectedWay);
|
||||
},
|
||||
|
||||
// 获取近5年 年月
|
||||
getFiveYears() {
|
||||
let getYear = new Date().getFullYear();
|
||||
|
||||
let lastFiveYear = getYear - 5;
|
||||
let maxMonth = new Date().getMonth() + 1;
|
||||
let dates = [];
|
||||
// 循环出过去5年
|
||||
const getYear = new Date().getFullYear();
|
||||
const lastFiveYear = getYear - 5;
|
||||
const maxMonth = new Date().getMonth() + 1;
|
||||
const dates = [];
|
||||
for (let year = lastFiveYear; year <= getYear; year++) {
|
||||
for (let month = 1; month <= 12; month++) {
|
||||
if (year == getYear && month > maxMonth) {
|
||||
} else {
|
||||
dates.push({
|
||||
year: year,
|
||||
month: month,
|
||||
});
|
||||
if (year === getYear && month > maxMonth) {
|
||||
continue;
|
||||
}
|
||||
dates.push({ year, month });
|
||||
}
|
||||
}
|
||||
this.dates = dates.reverse();
|
||||
},
|
||||
// 改变已选店铺
|
||||
changeSelect(e) {
|
||||
this.month = e
|
||||
this.month = e;
|
||||
if (this.month) {
|
||||
this.dateList.forEach((res) => {
|
||||
res.selected = false;
|
||||
@@ -150,54 +123,44 @@ export default {
|
||||
this.selectedWay.year = this.month.split("-")[0];
|
||||
this.selectedWay.month = this.month.split("-")[1];
|
||||
this.selectedWay.searchType = "";
|
||||
|
||||
this.$emit("selected", this.selectedWay);
|
||||
} else {
|
||||
|
||||
const current = this.dateList.find(item => { return item.selected })
|
||||
this.selectedWay = current
|
||||
this.clickBreadcrumb(current)
|
||||
const current = this.dateList.find((item) => item.selected);
|
||||
this.selectedWay = current;
|
||||
this.clickBreadcrumb(current);
|
||||
this.$emit("selected", this.selectedWay);
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
// 变更时间
|
||||
clickBreadcrumb(item) {
|
||||
|
||||
let currentIndex;
|
||||
this.dateList.forEach((res,index) => {
|
||||
this.dateList.forEach((res, index) => {
|
||||
res.selected = false;
|
||||
if(res.title === item.title){
|
||||
currentIndex = index
|
||||
if (res.title === item.title) {
|
||||
currentIndex = index;
|
||||
}
|
||||
});
|
||||
item.selected = true;
|
||||
item.storeId = this.storeId;
|
||||
this.month = "";
|
||||
if (item.searchType == "") {
|
||||
let currentDate = this.originDateList[currentIndex].searchType
|
||||
if (currentDate) {
|
||||
item.searchType = currentDate
|
||||
} else {
|
||||
item.searchType = "LAST_SEVEN";
|
||||
}
|
||||
if (item.searchType === "") {
|
||||
const currentDate = this.originDateList[currentIndex].searchType;
|
||||
item.searchType = currentDate || "LAST_SEVEN";
|
||||
}
|
||||
this.selectedWay = item;
|
||||
this.selectedWay.year = new Date().getFullYear();
|
||||
this.selectedWay.month = "";
|
||||
|
||||
this.$emit("selected", this.selectedWay);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
>span {
|
||||
> span {
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -208,8 +171,6 @@ export default {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.date-picker {}
|
||||
|
||||
.active:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
|
||||
@@ -123,7 +123,7 @@ export default {
|
||||
deactivated() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,86 +1,112 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<Button @click="handleClickUploadImage">上传图片</Button>
|
||||
<Modal v-model="show" width="850" @on-ok="callback" title="上传图片">
|
||||
<div class="import-oss" @click="importOSS">
|
||||
从资源库中导入
|
||||
</div>
|
||||
<el-button @click="handleClickUploadImage">上传图片</el-button>
|
||||
<el-dialog v-model="show" width="850px" title="上传图片" append-to-body :z-index="3500">
|
||||
<div class="import-oss" @click="importOSS">从资源库中导入</div>
|
||||
<div style="display: flex; flex-wrap: wrap">
|
||||
<vuedraggable
|
||||
:animation="200"
|
||||
:list="images"
|
||||
>
|
||||
<vuedraggable :animation="200" :list="images">
|
||||
<div
|
||||
v-for="(item, __index) in images"
|
||||
:key="__index"
|
||||
class="upload-list"
|
||||
>
|
||||
<template>
|
||||
<img alt="image" :src="item.url"/>
|
||||
<div class="upload-list-cover">
|
||||
<div>
|
||||
<Icon
|
||||
size="30"
|
||||
type="md-search"
|
||||
@click.native="$previewImage(item.url)"
|
||||
></Icon>
|
||||
<Icon
|
||||
size="30"
|
||||
type="md-trash"
|
||||
@click.native="handleRemoveGoodsPicture(__index)"
|
||||
></Icon>
|
||||
</div>
|
||||
<img alt="image" :src="item.url" />
|
||||
<div class="upload-list-cover">
|
||||
<div>
|
||||
<el-icon class="action-icon" :size="30" @click="handleView(item.url)">
|
||||
<ZoomIn />
|
||||
</el-icon>
|
||||
<el-icon
|
||||
class="action-icon"
|
||||
:size="30"
|
||||
@click="handleRemoveGoodsPicture(__index)"
|
||||
>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
<div class="upload-box">
|
||||
<Upload
|
||||
<el-upload
|
||||
ref="upload"
|
||||
:action="uploadFileUrl"
|
||||
:format="['jpg', 'jpeg', 'png']"
|
||||
:headers="{ ...accessToken }"
|
||||
:max-size="10240"
|
||||
:on-exceeded-size="handleMaxSize"
|
||||
:on-format-error="handleFormatError"
|
||||
:on-success="handleSuccessGoodsPicture"
|
||||
:show-upload-list="false"
|
||||
:headers="accessToken"
|
||||
:show-file-list="false"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
drag
|
||||
multiple
|
||||
type="drag"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:on-success="handleSuccessGoodsPicture"
|
||||
:on-error="handleUploadError"
|
||||
>
|
||||
<div style="width: 148px; height: 148px; line-height: 148px">
|
||||
<Icon size="20" type="md-add"></Icon>
|
||||
<div class="upload-trigger">
|
||||
<el-icon :size="20"><Plus /></el-icon>
|
||||
</div>
|
||||
</Upload>
|
||||
</el-upload>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="show = false">取消</el-button>
|
||||
<el-button type="primary" @click="callback">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<Modal width="1000" v-model="showOssManager" @on-ok="confirmUrls">
|
||||
<OssManage ref="ossManage" :isComponent="true" :initialize="showOssManager" @selected="(list)=>{ selectedImage = list}" @callback="handleCallback" />
|
||||
</Modal>
|
||||
<el-dialog
|
||||
v-model="showOssManager"
|
||||
width="1000px"
|
||||
append-to-body
|
||||
:z-index="3600"
|
||||
destroy-on-close
|
||||
@closed="confirmUrls"
|
||||
>
|
||||
<OssManage
|
||||
ref="ossManage"
|
||||
:is-component="true"
|
||||
:initialize="showOssManager"
|
||||
@selected="(list) => { selectedImage = list }"
|
||||
@callback="handleCallback"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="showOssManager = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmUrls">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="viewImage" title="图片预览" width="520px" append-to-body :z-index="3700">
|
||||
<img :src="previewUrl" alt="预览" style="width: 100%; display: block; margin: 0 auto" />
|
||||
<template #footer>
|
||||
<el-button @click="viewImage = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { Delete, Plus, ZoomIn } from "@element-plus/icons-vue";
|
||||
import vuedraggable from "vuedraggable";
|
||||
import {uploadFile} from "@/libs/axios";
|
||||
// import OssManage from "@/views/sys/oss-manage/ossManage";
|
||||
import { uploadFile } from "@/libs/axios";
|
||||
import OssManage from "@/views/shop/ossManage";
|
||||
|
||||
export default {
|
||||
name: "upload-image",
|
||||
components: {
|
||||
OssManage,
|
||||
vuedraggable,
|
||||
Delete,
|
||||
Plus,
|
||||
ZoomIn,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false, // 是否显示弹窗
|
||||
uploadFileUrl: uploadFile, // 上传地址
|
||||
accessToken:"",
|
||||
showOssManager:false, // 是否显示oss管理弹窗
|
||||
images:[],
|
||||
selectedImage:[]
|
||||
}
|
||||
show: false,
|
||||
uploadFileUrl: uploadFile,
|
||||
accessToken: {},
|
||||
showOssManager: false,
|
||||
images: [],
|
||||
selectedImage: [],
|
||||
viewImage: false,
|
||||
previewUrl: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.accessToken = {
|
||||
@@ -88,71 +114,78 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClickUploadImage(){
|
||||
handleClickUploadImage() {
|
||||
this.show = true;
|
||||
},
|
||||
// 回调给父级
|
||||
callback() {
|
||||
// 先给数据做一下处理 然后将数据传给父级
|
||||
const formatImages = this.images.map((item) => item.url);
|
||||
this.$emit('callback',formatImages)
|
||||
handleView(url) {
|
||||
this.previewUrl = url;
|
||||
this.viewImage = true;
|
||||
},
|
||||
callback() {
|
||||
const formatImages = this.images.map((item) => item.url);
|
||||
this.$emit("callback", formatImages);
|
||||
this.show = false;
|
||||
},
|
||||
// 移除商品图片
|
||||
handleRemoveGoodsPicture(__index) {
|
||||
this.images.splice(__index, 1);
|
||||
},
|
||||
// 图片大小不正确
|
||||
handleMaxSize(file) {
|
||||
this.$Notice.warning({
|
||||
title: "超过文件大小限制",
|
||||
desc: "图片大小不能超过10MB",
|
||||
});
|
||||
handleBeforeUpload(file) {
|
||||
const okType = ["image/jpeg", "image/png", "image/jpg"].includes(file.type);
|
||||
if (!okType) {
|
||||
this.$Message.warning("文件 " + file.name + " 的格式不正确,请选择 jpg/jpeg/png");
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 10) {
|
||||
this.$Message.warning("图片大小不能超过10MB");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 图片格式不正确
|
||||
handleFormatError(file) {
|
||||
this.$Notice.warning({
|
||||
title: "文件格式不正确",
|
||||
desc: "文件 " + file.name + " 的格式不正确",
|
||||
});
|
||||
},
|
||||
// sku图片上传成功
|
||||
handleSuccessGoodsPicture(res, file) {
|
||||
if (file.response) {
|
||||
file.url = file.response.result;
|
||||
this.images.push(file);
|
||||
handleSuccessGoodsPicture(res) {
|
||||
const url = res?.result ?? res?.data?.result;
|
||||
if (url) {
|
||||
this.images.push({ url });
|
||||
} else {
|
||||
this.$Message.error(res?.message || "上传失败");
|
||||
}
|
||||
},
|
||||
confirmUrls(){
|
||||
this.selectedImage.length ? this.selectedImage.forEach(element => {
|
||||
this.images.push({ url: element.url })
|
||||
}):''
|
||||
this.showOssManager = false
|
||||
handleUploadError(err) {
|
||||
this.$Message.error(err?.message || String(err));
|
||||
},
|
||||
handleCallback(val){
|
||||
this.$Message.success("导入成功")
|
||||
this.images.push({url:val.url})
|
||||
confirmUrls() {
|
||||
if (this.selectedImage.length) {
|
||||
this.selectedImage.forEach((element) => {
|
||||
this.images.push({ url: element.url });
|
||||
});
|
||||
}
|
||||
this.showOssManager = false;
|
||||
},
|
||||
// 从资源库中导入图片
|
||||
importOSS(){
|
||||
handleCallback(val) {
|
||||
this.$Message.success("导入成功");
|
||||
this.images.push({ url: val.url });
|
||||
},
|
||||
importOSS() {
|
||||
this.showOssManager = true;
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.ossManage) {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.import-oss{
|
||||
.import-oss {
|
||||
margin-bottom: 10px;
|
||||
text-align: right;
|
||||
color: $theme_color;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
.wrapper{
|
||||
.wrapper {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.upload-list {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
@@ -165,47 +198,48 @@ export default {
|
||||
margin-right: 4px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.upload-box{
|
||||
.upload-box {
|
||||
margin: 10px 0;
|
||||
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.upload-trigger {
|
||||
width: 148px;
|
||||
height: 148px;
|
||||
line-height: 148px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.upload-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.upload-list-cover {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.upload-list:hover .upload-list-cover {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.upload-list-cover div {
|
||||
margin-top: 50px;
|
||||
width: 100%;
|
||||
|
||||
>i {
|
||||
width: 50%;
|
||||
margin-top: 8px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.action-icon {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,57 +1,66 @@
|
||||
<template>
|
||||
<Modal :mask-closable="false" :value="switched" v-model="switched" title="选择地址" @on-ok="submit" @on-cancel="cancel">
|
||||
<div class="flex">
|
||||
<Spin size="large" fix v-if="spinShow"></Spin>
|
||||
<Tree ref="tree" class="tree" :data="data" expand-node show-checkbox multiple></Tree>
|
||||
<el-dialog
|
||||
v-model="switched"
|
||||
title="选择地址"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@close="cancel"
|
||||
>
|
||||
<div v-loading="spinShow" class="flex">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
class="tree"
|
||||
:data="data"
|
||||
:props="treeProps"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="submit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import { getAllCity } from "@/api/index";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
switched: false, // 控制模态框显隐
|
||||
spinShow: false, // 加载loading
|
||||
data: [], // 地区数据
|
||||
selectedWay: [], // 选择的地区
|
||||
callBackData: "", // 打开组件的回显数据
|
||||
switched: false,
|
||||
spinShow: false,
|
||||
data: [],
|
||||
selectedWay: [],
|
||||
callBackData: "",
|
||||
treeProps: {
|
||||
label: "title",
|
||||
children: "children",
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
clear() { // 引用该组件的父组件会调用
|
||||
clear() {
|
||||
this.data = [];
|
||||
this.selectedWay = [];
|
||||
this.init();
|
||||
},
|
||||
/**
|
||||
* 关闭
|
||||
*/
|
||||
cancel() {
|
||||
this.switched = false;
|
||||
|
||||
// 关闭的时候所有数据设置成disabled为true
|
||||
this.data.forEach((item) => {
|
||||
this.$set(item, "disabled", false);
|
||||
item.disabled = false;
|
||||
item.children.forEach((child) => {
|
||||
this.$set(child, "disabled", false);
|
||||
child.disabled = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开地图选择器
|
||||
* @param {val} 回调的数据
|
||||
* @param {index} 当前操作的运费模板的索引
|
||||
*/
|
||||
open(val, index) {
|
||||
if (val) {
|
||||
//已选中的地址
|
||||
let checkedData = this.$store.state.shipTemplate;
|
||||
|
||||
let checkData = [];
|
||||
let disabledData = checkedData.filter((item, i) => {
|
||||
if (i != index) {
|
||||
@@ -60,140 +69,127 @@ export default {
|
||||
checkData.push(item);
|
||||
}
|
||||
});
|
||||
// 选中
|
||||
checkData.forEach((check) => {
|
||||
// 循环出已经选中的地址id
|
||||
check.areaId.split(",").forEach((ids) => {
|
||||
this.data.forEach((item) => {
|
||||
// 如果当前省份下市区全部选中则选中该省份
|
||||
if (check.selectedAll) {
|
||||
check.area.split(",").forEach((area) => {
|
||||
if (area == item.name) {
|
||||
this.$set(item, "checked", true);
|
||||
item.checked = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 将市区继续循环
|
||||
item.children.forEach((child, childIndex) => {
|
||||
// 判断当前市区是否是已选中状态
|
||||
item.children.forEach((child) => {
|
||||
if (item.checked) {
|
||||
this.$set(child, "checked", true);
|
||||
child.checked = true;
|
||||
}
|
||||
if (child.id == ids) {
|
||||
this.$set(child, "checked", true);
|
||||
child.checked = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 禁用
|
||||
disabledData.forEach((dis) => {
|
||||
// 循环出已经选中的地址id
|
||||
dis.areaId.split(",").forEach((ids) => {
|
||||
// 循环出省份
|
||||
this.data.forEach((item) => {
|
||||
// 如果当前省份下市区全部选中则禁用该省份
|
||||
if (dis.selectedAll) {
|
||||
dis.area.split(",").forEach((area) => {
|
||||
if (area == item.name) {
|
||||
this.$set(item, "disabled", true);
|
||||
item.disabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 将市区继续循环
|
||||
item.children.forEach((child, childIndex) => {
|
||||
// 判断当前市区是否是已禁用状态
|
||||
item.children.forEach((child) => {
|
||||
if (item.disabled) {
|
||||
this.$set(child, "disabled", true);
|
||||
} else {
|
||||
if (child.id == ids) {
|
||||
this.$set(child, "disabled", true);
|
||||
}
|
||||
child.disabled = true;
|
||||
} else if (child.id == ids) {
|
||||
child.disabled = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
this.syncTreeCheckedKeys();
|
||||
}
|
||||
this.switched ? (this.switched = true) : (this.switched = true);
|
||||
this.switched = true;
|
||||
},
|
||||
syncTreeCheckedKeys() {
|
||||
this.$nextTick(() => {
|
||||
const keys = [];
|
||||
this.data.forEach((item) => {
|
||||
if (item.checked) {
|
||||
keys.push(item.id);
|
||||
}
|
||||
item.children.forEach((child) => {
|
||||
if (child.checked) {
|
||||
keys.push(child.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
if (this.$refs.tree) {
|
||||
this.$refs.tree.setCheckedKeys(keys);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交并筛选出省市
|
||||
*/
|
||||
submit() {
|
||||
// 筛选出省市
|
||||
let list = this.$refs.tree.getCheckedAndIndeterminateNodes();
|
||||
const checkedNodes = this.$refs.tree.getCheckedNodes(false, true);
|
||||
const halfCheckedNodes = this.$refs.tree.getHalfCheckedNodes();
|
||||
let list = [...checkedNodes, ...halfCheckedNodes];
|
||||
|
||||
let sort = [];
|
||||
list.forEach((item, i) => {
|
||||
list.forEach((item) => {
|
||||
item.selectedList = [];
|
||||
item.selectedAll = false;
|
||||
// 筛选出当前的省份
|
||||
if (item.level == "province" && !item.disabled) {
|
||||
sort.push({
|
||||
...item,
|
||||
});
|
||||
sort.push({ ...item });
|
||||
}
|
||||
|
||||
// 筛选出当前选中的市
|
||||
sort.forEach((sortItem, sortIndex) => {
|
||||
if (
|
||||
item.level != "province" &&
|
||||
sortItem.id == item.parentId &&
|
||||
!item.disabled
|
||||
) {
|
||||
sortItem.selectedList.push({
|
||||
...item,
|
||||
});
|
||||
sort.forEach((sortItem) => {
|
||||
if (item.level != "province" && sortItem.id == item.parentId && !item.disabled) {
|
||||
sortItem.selectedList.push({ ...item });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 判断如果当前省是否全选
|
||||
this.data.forEach((whether) => {
|
||||
sort.forEach((item) => {
|
||||
// 如果当前省匹配
|
||||
if (
|
||||
item.id == whether.id &&
|
||||
item.selectedList.length == whether.children.length
|
||||
) {
|
||||
// 给一个全选子级的标识符
|
||||
item.selectedList.forEach((child) => {
|
||||
this.$set(child, "selectedAll", true);
|
||||
child.selectedAll = true;
|
||||
});
|
||||
this.$set(item, "selectedAll", true);
|
||||
item.selectedAll = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.$emit("selected", sort);
|
||||
|
||||
this.cancel();
|
||||
},
|
||||
// 初始化地区数据
|
||||
init() {
|
||||
getAllCity().then((res) => {
|
||||
if (res.result) {
|
||||
res.result.forEach((item) => {
|
||||
item.children.forEach((child) => {
|
||||
child.title = child.name;
|
||||
this.spinShow = true;
|
||||
getAllCity()
|
||||
.then((res) => {
|
||||
if (res.result) {
|
||||
this.data = [];
|
||||
res.result.forEach((item) => {
|
||||
item.children.forEach((child) => {
|
||||
child.title = child.name;
|
||||
});
|
||||
this.data.push({
|
||||
title: item.name,
|
||||
...item,
|
||||
});
|
||||
this.selectedWay.push({ name: item.name, id: item.id });
|
||||
});
|
||||
|
||||
let data = {
|
||||
title: item.name,
|
||||
|
||||
...item,
|
||||
};
|
||||
this.data.push(data);
|
||||
|
||||
this.selectedWay.push({ name: data.title, id: data.id });
|
||||
});
|
||||
this.$store.state.regions = this.data;
|
||||
}
|
||||
});
|
||||
this.$store.state.regions = this.data;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.spinShow = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -202,21 +198,14 @@ export default {
|
||||
.flex {
|
||||
display: flex;
|
||||
position: relative;
|
||||
min-height: 400px;
|
||||
}
|
||||
.tree {
|
||||
flex: 2;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
.form {
|
||||
flex: 8;
|
||||
}
|
||||
.button-list {
|
||||
margin-left: 80px;
|
||||
> * {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
::v-deep .ivu-modal-body {
|
||||
height: 400px !important;
|
||||
:deep(.el-dialog__body) {
|
||||
max-height: 450px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,37 +4,68 @@
|
||||
<div class="query-wrapper">
|
||||
<div class="query-item">
|
||||
<div>搜索范围</div>
|
||||
<Input placeholder="商品名称" @on-clear="goodsData=[]; goodsParams.goodsName=''; goodsParams.pageNumber = 1; getQueryGoodsList()" @on-enter="()=>{goodsData=[]; goodsParams.pageNumber = 1; getQueryGoodsList();}" clearable style="width: 150px"
|
||||
v-model="goodsParams.goodsName" />
|
||||
<el-input
|
||||
v-model="goodsParams.goodsName"
|
||||
placeholder="商品名称"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
@clear="onSearchGoods"
|
||||
@keyup.enter="onSearchGoods"
|
||||
/>
|
||||
</div>
|
||||
<div class="query-item">
|
||||
<Cascader v-model="category" placeholder="请选择商品分类" style="width: 150px" :data="cateList"></Cascader>
|
||||
<el-cascader
|
||||
v-model="category"
|
||||
:options="skuList"
|
||||
placeholder="请选择商品分类"
|
||||
style="width: 250px"
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
<div class="query-item">
|
||||
<Button type="primary" @click="goodsData=[]; goodsParams.pageNumber = 1; getQueryGoodsList();" icon="ios-search">搜索</Button>
|
||||
<el-button type="primary" @click="onSearchGoods">搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div >
|
||||
<Scroll class="wap-content-list" :on-reach-bottom="handleReachBottom" :distance-to-edge="[3,3]">
|
||||
|
||||
<div class="wap-content-item" :class="{ active: item.selected }" @click="checkedGoods(item, index)" v-for="(item, index) in goodsData" :key="index">
|
||||
<div>
|
||||
<div class="wap-content-list">
|
||||
<div
|
||||
class="wap-content-item"
|
||||
:class="{ active: item.selected }"
|
||||
@click="checkedGoods(item, index)"
|
||||
v-for="(item, index) in goodsData"
|
||||
:key="index"
|
||||
>
|
||||
<div>
|
||||
<img :src="item.thumbnail" alt="" />
|
||||
</div>
|
||||
<div class="wap-content-desc">
|
||||
<div class="wap-content-desc-title">{{ item.goodsName }}</div>
|
||||
<div class="wap-sku">{{ item.goodsUnit }}</div>
|
||||
<div class="wap-sku"><Tag :color="item.salesModel === 'RETAIL' ? 'default' : 'geekblue'">{{item.salesModel === "RETAIL" ? "零售型" : "批发型"}}</Tag></div>
|
||||
<div class="wap-sku">
|
||||
{{ item.goodsUnit }}
|
||||
<el-tag
|
||||
style="margin-left: 10px"
|
||||
:type="item.salesModel === 'RETAIL' ? 'info' : 'primary'"
|
||||
>
|
||||
{{ item.salesModel === "RETAIL" ? "零售型" : "批发型" }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="wap-content-desc-bottom">
|
||||
<div>¥{{ item.price | unitPrice }}</div>
|
||||
<div>¥{{ $filters.unitPrice(item.price) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Spin size="large" fix v-if="loading"></Spin>
|
||||
|
||||
<div v-if="loading" v-loading="loading" class="loading-mask" />
|
||||
<div v-if="empty" class="empty">暂无商品信息</div>
|
||||
</Scroll>
|
||||
|
||||
</div>
|
||||
<el-pagination
|
||||
v-model:current-page="goodsParams.pageNumber"
|
||||
class="pageration"
|
||||
:total="total"
|
||||
:page-size="goodsParams.pageSize"
|
||||
layout="total, prev, pager, next"
|
||||
size="small"
|
||||
@current-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,33 +76,29 @@ export default {
|
||||
props: {
|
||||
selectedWay: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: "multiple", //单选或者多选 single multiple
|
||||
|
||||
cateList: [], // 商品分类列表
|
||||
total: "", // 商品总数
|
||||
type: "multiple",
|
||||
skuList: [],
|
||||
total: 0,
|
||||
goodsParams: {
|
||||
// 请求商品列表参数
|
||||
pageNumber: 1,
|
||||
pageSize: 18,
|
||||
pageSize: 15,
|
||||
order: "desc",
|
||||
goodsName: "",
|
||||
sn: "",
|
||||
categoryPath: "",
|
||||
marketEnable: "UPPER",
|
||||
authFlag: "PASS",
|
||||
sort:"createTime"
|
||||
sort: "createTime",
|
||||
},
|
||||
category: [], // 选中的商品分类
|
||||
goodsData: [], // 商品列表
|
||||
empty: false, // 是否空数据
|
||||
loading: false, // 商品加载loading
|
||||
category: [],
|
||||
goodsData: [],
|
||||
empty: false,
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@@ -79,16 +106,17 @@ export default {
|
||||
this.goodsParams.categoryPath = val[2];
|
||||
},
|
||||
selectedWay: {
|
||||
handler(val) {
|
||||
handler() {
|
||||
this.$emit("selected", this.selectedWay);
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
"goodsParams.categoryPath": {
|
||||
handler: function () {
|
||||
handler() {
|
||||
this.goodsData = [];
|
||||
(this.goodsParams.pageNumber = 0), this.getQueryGoodsList();
|
||||
this.goodsParams.pageNumber = 1;
|
||||
this.getQueryGoodsList();
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
@@ -97,106 +125,82 @@ export default {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
handleReachBottom() {
|
||||
// 页面触底触发加载
|
||||
setTimeout(() => {
|
||||
if (
|
||||
this.goodsParams.pageNumber * this.goodsParams.pageSize <=
|
||||
this.total
|
||||
) {
|
||||
this.goodsParams.pageNumber++;
|
||||
this.getQueryGoodsList();
|
||||
}
|
||||
}, 1500);
|
||||
onSearchGoods() {
|
||||
this.goodsData = [];
|
||||
this.goodsParams.pageNumber = 1;
|
||||
this.getQueryGoodsList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.goodsParams.pageNumber = v;
|
||||
this.getQueryGoodsList();
|
||||
},
|
||||
getQueryGoodsList() {
|
||||
// 根据商品分类筛选商品
|
||||
API_Goods.getGoodsSkuData(this.goodsParams).then((res) => {
|
||||
this.initGoods(res);
|
||||
});
|
||||
this.loading = true;
|
||||
API_Goods.getGoodsSkuData(this.goodsParams)
|
||||
.then((res) => {
|
||||
this.initGoods(res);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
initGoods(res) {
|
||||
// 获取商品列表
|
||||
if (res.result.records.length != 0) {
|
||||
let data = res.result.records;
|
||||
data.forEach((item) => {
|
||||
res.result.records.forEach((item) => {
|
||||
item.selected = false;
|
||||
item.___type = "goods"; //设置为goods让pc wap知道标识
|
||||
|
||||
item.___type = "goods";
|
||||
this.selectedWay.forEach((e) => {
|
||||
if (e.id === item.id) {
|
||||
if (e.id && e.id === item.id) {
|
||||
item.selected = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
/**
|
||||
* 解决数据请求中,滚动栏会一直上下跳动
|
||||
*/
|
||||
this.total = res.result.total;
|
||||
this.goodsData.push(...res.result.records);
|
||||
this.goodsData = res.result.records;
|
||||
this.empty = false;
|
||||
} else {
|
||||
this.goodsData = [];
|
||||
this.empty = true;
|
||||
}
|
||||
},
|
||||
|
||||
// 查询商品
|
||||
init() {
|
||||
Promise.all([
|
||||
API_Goods.getGoodsSkuData(this.goodsParams),
|
||||
API_Goods.getGoodsCategoryAll(0),
|
||||
]).then((res) => {
|
||||
// 商品
|
||||
this.initGoods(res[0]);
|
||||
|
||||
// 分类
|
||||
if (res[1].result) {
|
||||
this.deepGroup(res[1].result);
|
||||
API_Goods.getGoodsSkuData(this.goodsParams).then((res) => {
|
||||
this.initGoods(res);
|
||||
});
|
||||
API_Goods.getGoodsCategoryAll(0).then((res) => {
|
||||
if (res.result) {
|
||||
this.deepGroup(res.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
deepGroup(val) {
|
||||
val.forEach((item) => {
|
||||
let childWay = []; //第二级
|
||||
// 第二层
|
||||
let childWay = [];
|
||||
if (item.children) {
|
||||
item.children.forEach((child) => {
|
||||
// // 第三层
|
||||
if (child.children) {
|
||||
child.children.forEach((grandson, index, arr) => {
|
||||
arr[index] = {
|
||||
value: grandson.id,
|
||||
label: grandson.name,
|
||||
children: "",
|
||||
};
|
||||
});
|
||||
}
|
||||
let children = {
|
||||
childWay.push({
|
||||
value: child.id,
|
||||
label: child.name,
|
||||
children: child.children,
|
||||
};
|
||||
childWay.push(children);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 第一层
|
||||
let way = {
|
||||
this.skuList.push({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
children: childWay,
|
||||
};
|
||||
|
||||
this.cateList.push(way);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击商品
|
||||
*/
|
||||
checkedGoods(val, index) {
|
||||
// 如果单选的话
|
||||
checkedGoods(val) {
|
||||
if (this.type != "multiple") {
|
||||
this.goodsData.forEach((item) => {
|
||||
item.selected = false;
|
||||
@@ -204,10 +208,8 @@ export default {
|
||||
this.selectedWay = [];
|
||||
val.selected = true;
|
||||
this.selectedWay.push(val);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val.selected == false) {
|
||||
val.selected = true;
|
||||
this.selectedWay.push(val);
|
||||
@@ -239,17 +241,27 @@ export default {
|
||||
padding: 0;
|
||||
}
|
||||
.wap-content-list {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-wrap: wrap;
|
||||
height: 340px;
|
||||
}
|
||||
.wap-content-item {
|
||||
width: 210px;
|
||||
margin: 10px 7px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: url("../../assets/selected.png") no-repeat;
|
||||
background-position: right;
|
||||
background-size: 10%;
|
||||
}
|
||||
.loading-mask {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
.pageration {
|
||||
margin-top: 12px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,26 +1,40 @@
|
||||
<template>
|
||||
<Modal
|
||||
:title="title"
|
||||
:styles="{ top: '120px' }"
|
||||
width="750"
|
||||
@on-cancel="clickClose"
|
||||
@on-ok="clickOK"
|
||||
<el-dialog
|
||||
v-model="flag"
|
||||
:mask-closable="false"
|
||||
scrollable
|
||||
width="1160px"
|
||||
top="120px"
|
||||
:z-index="10000"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
@close="clickClose"
|
||||
>
|
||||
<goodsDialog
|
||||
@selected="(val) => {goodsData = val;}"
|
||||
:selectedWay='goodsData'
|
||||
ref="goodsDialog"
|
||||
v-if="goodsFlag"
|
||||
/>
|
||||
<linkDialog
|
||||
@selectedLink="(val) => {linkData = val;}"
|
||||
v-else
|
||||
class="linkDialog"
|
||||
/>
|
||||
</Modal>
|
||||
<template v-if="flag">
|
||||
<goodsDialog
|
||||
@selected="
|
||||
(val) => {
|
||||
goodsData = val;
|
||||
}
|
||||
"
|
||||
v-if="goodsFlag"
|
||||
ref="goodsDialog"
|
||||
:selectedWay="goodsData"
|
||||
/>
|
||||
<linkDialog
|
||||
@selectedLink="
|
||||
(val) => {
|
||||
linkData = val;
|
||||
}
|
||||
"
|
||||
v-else
|
||||
class="linkDialog"
|
||||
/>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="clickClose">取消</el-button>
|
||||
<el-button type="primary" @click="clickOK">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import goodsDialog from "./goods-dialog";
|
||||
@@ -32,31 +46,29 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: "选择", // 模态框标题
|
||||
goodsFlag: false, // 是否商品选择器
|
||||
goodsData: [], //选择的商品
|
||||
linkData: "", //选择的链接
|
||||
flag: false, // 控制模态框显隐
|
||||
goodsFlag: false,
|
||||
goodsData: [],
|
||||
linkData: "",
|
||||
flag: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 关闭弹窗
|
||||
clearGoodsSelected() {
|
||||
this.goodsData = [];
|
||||
},
|
||||
clickClose() {
|
||||
this.$emit("closeFlag", false);
|
||||
this.goodsFlag = false;
|
||||
},
|
||||
|
||||
// 单选商品
|
||||
singleGoods(){
|
||||
singleGoods() {
|
||||
var timer = setInterval(() => {
|
||||
if (this.$refs.goodsDialog) {
|
||||
|
||||
this.$refs.goodsDialog.type = "single";
|
||||
clearInterval(timer);
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
clickOK() { // 确定按钮回调,
|
||||
clickOK() {
|
||||
if (this.goodsFlag) {
|
||||
this.$emit("selectedGoodsData", this.goodsData);
|
||||
} else {
|
||||
@@ -64,27 +76,25 @@ export default {
|
||||
}
|
||||
this.clickClose();
|
||||
},
|
||||
open (type) { // 父组件通过ref调用,打开商品选择器
|
||||
open(type, mutiple) {
|
||||
this.flag = true;
|
||||
if(type == 'goods'){
|
||||
if (type == "goods") {
|
||||
this.goodsFlag = true;
|
||||
if (mutiple) {
|
||||
this.singleGoods();
|
||||
}
|
||||
} else {
|
||||
this.goodsFlag = false
|
||||
this.goodsFlag = false;
|
||||
}
|
||||
|
||||
},
|
||||
close(){ // 关闭组件
|
||||
close() {
|
||||
this.flag = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
::v-deep .ivu-modal {
|
||||
overflow: hidden;
|
||||
height: 650px !important;
|
||||
}
|
||||
::v-deep .ivu-modal-body {
|
||||
:deep(.el-dialog__body) {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
|
||||
<Tabs :value="wap[0].title" class="tabs">
|
||||
|
||||
<TabPane :label="item.title" :name="item.title" @click="clickTag(item, i)" v-for="(item, i) in wap" :key="i">
|
||||
<component ref="lili-component" :is="templateWay[item.name]" @selected="
|
||||
(val) => {
|
||||
changed = val;
|
||||
}
|
||||
" />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
|
||||
<el-tabs v-model="activeTab" class="tabs">
|
||||
<el-tab-pane
|
||||
:label="item.title"
|
||||
:name="item.title"
|
||||
v-for="(item, i) in wap"
|
||||
:key="i"
|
||||
>
|
||||
<component
|
||||
ref="lili-component"
|
||||
:is="templateWay[item.name]"
|
||||
@selected="
|
||||
(val) => {
|
||||
changed = val;
|
||||
}
|
||||
"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -22,33 +28,38 @@ export default {
|
||||
components: {
|
||||
goodsDialog,
|
||||
},
|
||||
setup() {
|
||||
return { templateWay };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
templateWay, // 模板数据
|
||||
changed: "", // 变更模板
|
||||
selected: 0, // 已选数据
|
||||
selectedLink: "", //选中的链接
|
||||
wap // tab标签
|
||||
changed: "",
|
||||
selected: 0,
|
||||
selectedLink: "",
|
||||
wap,
|
||||
activeTab: wap[0]?.title || "",
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
changed: {
|
||||
handler(val) {
|
||||
this.$emit("selectedLink", val[0]); //因为是单选,所以直接返回第一个
|
||||
this.$emit("selectedLink", val[0]);
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs["lili-component"][0].type = "single"; //商品页面设置成为单选
|
||||
if (this.$refs["lili-component"]?.[0]) {
|
||||
this.$refs["lili-component"][0].type = "single";
|
||||
}
|
||||
});
|
||||
|
||||
this.wap.forEach((item) => {
|
||||
item.selected = false;
|
||||
if (item) {
|
||||
item.selected = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@@ -63,14 +74,8 @@ export default {
|
||||
.tabs {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep .ivu-modal {
|
||||
overflow: hidden;
|
||||
height: 650px !important;
|
||||
}
|
||||
::v-deep .ivu-modal-body {
|
||||
width: 100%;
|
||||
:deep(.el-tabs__content) {
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,101 +1,101 @@
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
.wap-list {
|
||||
flex: 2;
|
||||
text-align: center;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
}
|
||||
> .wap-list,
|
||||
.wap-content {
|
||||
padding: 8px;
|
||||
}
|
||||
.wap-content {
|
||||
flex: 8;
|
||||
}
|
||||
}
|
||||
.wap-sku {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
||||
.query-wrapper {
|
||||
display: flex;
|
||||
margin: 8px 0;
|
||||
> .query-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> * {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep .ivu-scroll-container {
|
||||
width: 100% !important;
|
||||
height: 400px !important;
|
||||
}
|
||||
::v-deep .ivu-scroll-content {
|
||||
/* */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.wap-content-list {
|
||||
.wap-list {
|
||||
flex: 2;
|
||||
text-align: center;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.wap-item {
|
||||
padding: 10px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.wap-item:hover {
|
||||
background: #ededed;
|
||||
}
|
||||
.active{
|
||||
background: #ededed;
|
||||
}
|
||||
.active {
|
||||
border: 1px solid #ededed;
|
||||
}
|
||||
.wap-content-item {
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
> .wap-list,
|
||||
.wap-content {
|
||||
flex: 8;
|
||||
}
|
||||
}
|
||||
|
||||
.wap-sku {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.query-wrapper {
|
||||
display: flex;
|
||||
margin: 8px 0;
|
||||
|
||||
> .query-item {
|
||||
display: flex;
|
||||
height: 100px;
|
||||
padding: 2px;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
margin: 10px;
|
||||
::v-deep img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
.wap-content-desc {
|
||||
width: 180px;
|
||||
padding: 8px;
|
||||
> .wap-content-desc-title {
|
||||
display: -webkit-box;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
> .wap-content-desc-bottom {
|
||||
font-size: 12px;
|
||||
padding: 4px 0;
|
||||
color: #999;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
> div:nth-of-type(1) {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
> * {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wap-content-list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.wap-item {
|
||||
padding: 10px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wap-item:hover {
|
||||
background: #ededed;
|
||||
}
|
||||
|
||||
.pageration {
|
||||
text-align: right;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.wap-content-item {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
height: 90px;
|
||||
padding: 2px;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
margin: 10px;
|
||||
|
||||
:deep(img) {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wap-content-desc {
|
||||
width: 180px;
|
||||
padding: 8px;
|
||||
|
||||
> .wap-content-desc-title {
|
||||
display: -webkit-box;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
> .wap-content-desc-bottom {
|
||||
font-size: 12px;
|
||||
padding: 4px 0;
|
||||
color: #999;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,5 +117,6 @@ export default {
|
||||
}
|
||||
.wrapper {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { markRaw } from "vue";
|
||||
import category from "./category.vue";
|
||||
import pages from "./pages.vue";
|
||||
import goods from "../goods-dialog.vue";
|
||||
import other from "./other.vue";
|
||||
|
||||
import category from './category.vue'
|
||||
import shops from './shops.vue'
|
||||
|
||||
import pages from './pages.vue'
|
||||
import goods from '../goods-dialog.vue'
|
||||
import other from './other.vue'
|
||||
export default {
|
||||
// pages,
|
||||
|
||||
// shops,
|
||||
category,
|
||||
goods,
|
||||
other,
|
||||
}
|
||||
category: markRaw(category),
|
||||
goods: markRaw(goods),
|
||||
other: markRaw(other),
|
||||
pages: markRaw(pages),
|
||||
};
|
||||
|
||||
@@ -1,116 +1,108 @@
|
||||
<template>
|
||||
<div>
|
||||
<Row :gutter="30">
|
||||
<Col span="6" v-for="(item,index) in linkList" :key="index" v-if="(item.title !== '拼团频道' && item.title !== '签到') || $route.name !== 'renovation'">
|
||||
<div class="card" :class="{'active':selectedIndex == index}" @click="handleLink(item,index)">
|
||||
<Icon size="24" :type="item.icon" />
|
||||
<p>{{item.title}}</p>
|
||||
</div>
|
||||
</Col>
|
||||
<!-- 外部链接,只有pc端跳转 -->
|
||||
<Col span="6" v-if="$route.name === 'renovation'">
|
||||
<div class="card" :class="{'active':selectedIndex == linkList.length}" @click="handleLink(linkItem,linkList.length)">
|
||||
<Poptip v-model="linkVisible">
|
||||
<Icon size="24" :type="linkItem.icon" />
|
||||
<p>{{linkItem.title}}</p>
|
||||
<div slot="title">链接地址</div>
|
||||
<div slot="content">
|
||||
<Input type="text" @keyup="handleLink(linkItem,linkList.length)" v-model="linkItem.url" placeholder="https://"></Input>
|
||||
<el-row :gutter="30">
|
||||
<template v-for="(item, index) in linkList" :key="index">
|
||||
<el-col v-if="showLinkItem(item)" :span="6">
|
||||
<div
|
||||
class="card"
|
||||
:class="{ active: selectedIndex == index }"
|
||||
@click="handleLink(item, index)"
|
||||
>
|
||||
<el-icon :size="24">
|
||||
<component :is="item.icon" />
|
||||
</el-icon>
|
||||
<p>{{ item.title }}</p>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
<el-col v-if="linkVisible" :span="6">
|
||||
<div
|
||||
class="card"
|
||||
:class="{ active: selectedIndex == linkList.length }"
|
||||
@click="handleLink(linkItem, linkList.length)"
|
||||
>
|
||||
<el-popover v-model:visible="linkPopoverVisible" trigger="click" placement="top" :width="280">
|
||||
<template #reference>
|
||||
<div class="link-card-inner">
|
||||
<el-icon :size="24">
|
||||
<component :is="linkItem.icon" />
|
||||
</el-icon>
|
||||
<p>{{ linkItem.title }}</p>
|
||||
</div>
|
||||
</Poptip>
|
||||
|
||||
</template>
|
||||
<div>
|
||||
<div style="margin-bottom: 8px">链接地址</div>
|
||||
<el-input
|
||||
v-model="linkItem.url"
|
||||
placeholder="https://"
|
||||
@keyup.enter="handleLink(linkItem, linkList.length)"
|
||||
/>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { markRaw } from "vue";
|
||||
import {
|
||||
House,
|
||||
ShoppingCart,
|
||||
Star,
|
||||
Document,
|
||||
User,
|
||||
Promotion,
|
||||
PriceTag,
|
||||
Sunny,
|
||||
Share,
|
||||
ShoppingBag,
|
||||
Link,
|
||||
} from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
linkList: [ // 链接列表
|
||||
{
|
||||
title: "首页",
|
||||
icon: "md-home",
|
||||
___type: "home",
|
||||
},
|
||||
{
|
||||
title: "购物车",
|
||||
icon: "md-cart",
|
||||
___type: "cart",
|
||||
},
|
||||
{
|
||||
title: "收藏商品",
|
||||
icon: "md-heart",
|
||||
___type: "collection",
|
||||
},
|
||||
{
|
||||
title: "我的订单",
|
||||
icon: "md-document",
|
||||
___type: "order",
|
||||
},
|
||||
{
|
||||
title: "个人中心",
|
||||
icon: "md-person",
|
||||
___type: "user",
|
||||
},
|
||||
{
|
||||
title: "拼团频道",
|
||||
icon: "md-flame",
|
||||
___type: "group",
|
||||
},
|
||||
{
|
||||
title: "秒杀频道",
|
||||
icon: "md-flame",
|
||||
___type: "seckill",
|
||||
},
|
||||
{
|
||||
title: "领券中心",
|
||||
icon: "md-pricetag",
|
||||
___type: "coupon",
|
||||
},
|
||||
{
|
||||
title: "签到",
|
||||
icon: "md-happy",
|
||||
___type: "sign",
|
||||
},
|
||||
// {
|
||||
// title: "小程序直播",
|
||||
// icon: "ios-videocam",
|
||||
// ___type: "live",
|
||||
// },
|
||||
{
|
||||
title: "砍价",
|
||||
icon: "md-share-alt",
|
||||
___type: "kanjia",
|
||||
},
|
||||
{
|
||||
title: "积分商城",
|
||||
icon: "ios-basket",
|
||||
___type: "point",
|
||||
},
|
||||
|
||||
linkList: [
|
||||
{ title: "首页", icon: markRaw(House), ___type: "home" },
|
||||
{ title: "购物车", icon: markRaw(ShoppingCart), ___type: "cart" },
|
||||
{ title: "收藏商品", icon: markRaw(Star), ___type: "collection" },
|
||||
{ title: "我的订单", icon: markRaw(Document), ___type: "order" },
|
||||
{ title: "个人中心", icon: markRaw(User), ___type: "user" },
|
||||
{ title: "拼团频道", icon: markRaw(Promotion), ___type: "group" },
|
||||
{ title: "秒杀频道", icon: markRaw(Promotion), ___type: "seckill" },
|
||||
{ title: "领券中心", icon: markRaw(PriceTag), ___type: "coupon" },
|
||||
{ title: "签到", icon: markRaw(Sunny), ___type: "sign" },
|
||||
{ title: "砍价", icon: markRaw(Share), ___type: "kanjia" },
|
||||
{ title: "积分商城", icon: markRaw(ShoppingBag), ___type: "point" },
|
||||
],
|
||||
linkItem: {
|
||||
title: "外部链接",
|
||||
icon: "ios-link",
|
||||
icon: markRaw(Link),
|
||||
___type: "link",
|
||||
url: ''
|
||||
url: "",
|
||||
},
|
||||
linkVisible: false, // 是否显示外部链接
|
||||
selectedIndex: 9999999, // 已选index
|
||||
linkVisible: false,
|
||||
linkPopoverVisible: false,
|
||||
selectedIndex: 9999999,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showLinkItem(item) {
|
||||
return (
|
||||
(item.title !== "拼团频道" && item.title !== "签到") ||
|
||||
this.$route.name !== "renovation"
|
||||
);
|
||||
},
|
||||
handleLink(val, index) {
|
||||
val = {...val,___type:'other'}
|
||||
val = { ...val, ___type: "other" };
|
||||
this.selectedIndex = index;
|
||||
if (index === this.linkList.length) {
|
||||
this.linkVisible = true
|
||||
this.linkPopoverVisible = true;
|
||||
} else {
|
||||
this.linkVisible = false
|
||||
this.linkPopoverVisible = false;
|
||||
}
|
||||
this.$emit("selected",[val])
|
||||
this.$emit("selected", [val]);
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -127,13 +119,19 @@ export default {
|
||||
text-align: center;
|
||||
transition: 0.35s;
|
||||
cursor: pointer;
|
||||
::v-deep p {
|
||||
border: 1px solid #ededed;
|
||||
:deep(p) {
|
||||
margin: 10px 0;
|
||||
}
|
||||
border: 1px solid #ededed;
|
||||
}
|
||||
.card:hover{
|
||||
background: #ededed;
|
||||
.link-card-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.card:hover {
|
||||
background: #ededed;
|
||||
}
|
||||
.active {
|
||||
background: #ededed;
|
||||
|
||||
@@ -33,13 +33,10 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .ivu-card-body {
|
||||
:deep(.el-card__body) {
|
||||
height: 414px;
|
||||
overflow: auto;
|
||||
}
|
||||
.ivu-table-wrapper ivu-table-wrapper-with-border {
|
||||
height: 300px !important;
|
||||
}
|
||||
.list {
|
||||
margin: 0 1.5%;
|
||||
height: 400px;
|
||||
@@ -69,11 +66,11 @@ export default {
|
||||
height: 416px;
|
||||
overflow: hidden;
|
||||
}
|
||||
::v-deep .ivu-table {
|
||||
:deep(.el-table) {
|
||||
height: 300px !important;
|
||||
overflow: auto;
|
||||
}
|
||||
::v-deep .ivu-card-body {
|
||||
:deep(.el-card__body) {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -4,29 +4,54 @@
|
||||
<div class="query-wrapper">
|
||||
<div class="query-item">
|
||||
<div>店铺名称</div>
|
||||
<Input placeholder="请输入店铺名称" @on-clear="shopsData=[]; params.storeName=''; params.pageNumber =1; init()" @on-enter="()=>{shopsData=[]; params.pageNumber =1; init();}" icon="ios-search" clearable style="width: 150px"
|
||||
v-model="params.storeName" />
|
||||
<el-input
|
||||
v-model="params.storeName"
|
||||
placeholder="请输入店铺名称"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
@clear="resetSearch"
|
||||
@keyup.enter="resetSearch"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="query-item">
|
||||
<Button type="primary" @click="shopsData=[];params.pageNumber =1; init();" icon="ios-search">搜索</Button>
|
||||
<el-button type="primary" @click="resetSearch">搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Scroll class="wap-content-list" :on-reach-bottom="handleReachBottom" :distance-to-edge="23">
|
||||
<div class="wap-content-item" @click="clickShop(item,index)" :class="{ active:selected == index }" v-for="(item, index) in shopsData" :key="index">
|
||||
<div v-loading="loading" class="wap-content-list">
|
||||
<div
|
||||
v-for="(item, index) in shopsData"
|
||||
:key="index"
|
||||
class="wap-content-item"
|
||||
:class="{ active: selected == index }"
|
||||
@click="clickShop(item, index)"
|
||||
>
|
||||
<div>
|
||||
<img class="shop-logo" :src="item.storeLogo" alt="" />
|
||||
</div>
|
||||
<div class="wap-content-desc">
|
||||
<div class="wap-content-desc-title">{{ item.storeName }}</div>
|
||||
|
||||
<div class="self-operated" :class="{'theme_color':item.selfOperated }">{{ item.selfOperated ? '自营' : '非自营' }}</div>
|
||||
<div class="wap-sku" :class="{'theme_color':(item.storeDisable === 'OPEN' ? true : false) }">{{ item.storeDisable === 'OPEN' ? '开启中' : '未开启' }}</div>
|
||||
<div class="self-operated" :class="{ theme_color: item.selfOperated }">
|
||||
{{ item.selfOperated ? "自营" : "非自营" }}
|
||||
</div>
|
||||
<div
|
||||
class="wap-sku"
|
||||
:class="{ theme_color: item.storeDisable === 'OPEN' }"
|
||||
>
|
||||
{{ item.storeDisable === "OPEN" ? "开启中" : "未开启" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Spin size="large" fix v-if="loading"></Spin>
|
||||
</Scroll>
|
||||
</div>
|
||||
<el-pagination
|
||||
class="pageration"
|
||||
size="small"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="params.pageSize"
|
||||
:current-page="params.pageNumber"
|
||||
@current-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,45 +61,39 @@ import { getShopListData } from "@/api/shops.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false, // 加载状态
|
||||
total: "", // 总数
|
||||
params: { // 请求参数
|
||||
loading: false,
|
||||
total: 0,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 12,
|
||||
storeDisable: "OPEN",
|
||||
storeName: "",
|
||||
},
|
||||
shopsData: [], // 店铺数据
|
||||
selected: 9999999999, //设置一个不可能选中的index
|
||||
shopsData: [],
|
||||
selected: 9999999999,
|
||||
};
|
||||
},
|
||||
watch: {},
|
||||
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
handleReachBottom() {
|
||||
setTimeout(() => {
|
||||
if (this.params.pageNumber * this.params.pageSize <= this.total) {
|
||||
this.params.pageNumber++;
|
||||
this.init();
|
||||
}
|
||||
}, 1500);
|
||||
resetSearch() {
|
||||
this.shopsData = [];
|
||||
this.params.pageNumber = 1;
|
||||
this.init();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.params.pageNumber = v;
|
||||
this.init();
|
||||
},
|
||||
init() {
|
||||
this.loading = true;
|
||||
getShopListData(this.params).then((res) => {
|
||||
if (res.success) {
|
||||
/**
|
||||
* 解决数据请求中,滚动栏会一直上下跳动
|
||||
*/
|
||||
this.total = res.result.total;
|
||||
|
||||
this.shopsData.push(...res.result.records);
|
||||
|
||||
this.loading = false;
|
||||
this.shopsData = res.result.records;
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
clickShop(val, i) {
|
||||
@@ -95,16 +114,21 @@ export default {
|
||||
color: #999;
|
||||
}
|
||||
.wap-content-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 340px;
|
||||
min-height: 120px;
|
||||
}
|
||||
.shop-logo {
|
||||
object-fit: cover;
|
||||
}
|
||||
.wap-content-item {
|
||||
}
|
||||
.active {
|
||||
background: url("../../../assets/selected.png") no-repeat;
|
||||
background-position: right;
|
||||
background-size: 10%;
|
||||
}
|
||||
.pageration {
|
||||
margin-top: 12px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,36 +5,34 @@ export default [
|
||||
openGoods: true,
|
||||
name: "goods"
|
||||
},
|
||||
// {
|
||||
// title: "分类",
|
||||
// url: "1",
|
||||
// name: "category"
|
||||
// },
|
||||
|
||||
// {
|
||||
// title: "活动",
|
||||
// url: "3",
|
||||
// name: "marketing"
|
||||
// },
|
||||
// {
|
||||
// title: "页面",
|
||||
// url: "3",
|
||||
// name: "pages"
|
||||
// },
|
||||
|
||||
// {
|
||||
// title: "活动",
|
||||
// url: "3",
|
||||
// name: "marketing"
|
||||
// },
|
||||
// {
|
||||
// title: "页面",
|
||||
// url: "3",
|
||||
// name: "pages"
|
||||
// },
|
||||
{
|
||||
title: "分类",
|
||||
url: "1",
|
||||
name: "category"
|
||||
},
|
||||
{
|
||||
title: "店铺",
|
||||
url: "2",
|
||||
name: "shops"
|
||||
},
|
||||
{
|
||||
title: "活动",
|
||||
url: "3",
|
||||
name: "marketing"
|
||||
},
|
||||
{
|
||||
title: "文章",
|
||||
url: "3",
|
||||
name: "pages"
|
||||
},
|
||||
{
|
||||
title: "专题",
|
||||
url: "4",
|
||||
name: "special"
|
||||
},
|
||||
{
|
||||
title: "其他",
|
||||
url: "3",
|
||||
name: "other"
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,65 +1,112 @@
|
||||
<template>
|
||||
<div class="login" @click="$refs.verify.show = false">
|
||||
<Row type="flex" @keydown.enter.native="submitLogin">
|
||||
<Col style="width: 368px">
|
||||
<Header />
|
||||
<Row style="flex-direction: column">
|
||||
<Tabs v-model="loginType">
|
||||
<Tab-pane label="账号密码登录" name="passwordLogin">
|
||||
<!--账号密码登录-->
|
||||
<Form ref="usernameLoginForm" :model="form" :rules="rules" class="form">
|
||||
<FormItem prop="username">
|
||||
<Input v-model="form.username" prefix="ios-contact" clearable placeholder="请输入用户名"
|
||||
autocomplete="off" />
|
||||
</FormItem>
|
||||
<FormItem prop="password">
|
||||
<Input type="password" v-model="form.password" prefix="ios-lock" password
|
||||
placeholder="请输入密码" autocomplete="off" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div class="register">
|
||||
<a @click="$router.push('forgetPassword')">忘记密码</a>
|
||||
</div>
|
||||
</Tab-pane>
|
||||
<Tab-pane label="验证码登录" name="mobileLogin">
|
||||
<!-- 验证码登录 -->
|
||||
<Form ref="formSms" :model="formSms" :rules="ruleInline" @click.self='$refs.verify.show = false'>
|
||||
<FormItem prop="mobile">
|
||||
<i-input type="text" maxlength="11" v-model="formSms.mobile" clearable placeholder="手机号">
|
||||
<Icon type="md-lock" slot="prepend"></Icon>
|
||||
</i-input>
|
||||
</FormItem>
|
||||
<FormItem prop="code">
|
||||
<i-input type="text" v-model="formSms.code" placeholder="手机验证码">
|
||||
<Icon type="ios-text-outline" style="font-weight: bold" slot="prepend" />
|
||||
<Button slot="append" @click="sendCode" :loading="sendCodeLoading">{{ codeMsg }}</Button>
|
||||
</i-input>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<!-- <Button @click.stop="verifyBtnClick" long :type="verifyStatus ? 'success' : 'default'">{{ verifyStatus ?
|
||||
'验证通过' :
|
||||
'点击完成安全验证' }}
|
||||
</Button> -->
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Tab-pane>
|
||||
</Tabs>
|
||||
<Row>
|
||||
<div class="login-btn" type="primary" size="large" :loading="loading" @click="submitLogin" long>
|
||||
<span v-if="!loading">登录</span>
|
||||
<span v-else>登录中</span>
|
||||
</div>
|
||||
</Row>
|
||||
</Row>
|
||||
<Footer />
|
||||
<!-- 拼图验证码 -->
|
||||
<verify ref="verify" class="verify-con" verifyType="LOGIN" @change="verifyChange"></verify>
|
||||
</Col>
|
||||
</Row>
|
||||
<el-row class="flex" @keyup.enter="submitLogin">
|
||||
<el-col style="width: 368px">
|
||||
<Header />
|
||||
<el-row style="flex-direction: column">
|
||||
<el-tabs v-model="loginType">
|
||||
<el-tab-pane label="账号密码登录" name="passwordLogin">
|
||||
<el-form
|
||||
ref="usernameLoginForm"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
class="form"
|
||||
>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
size="large"
|
||||
clearable
|
||||
placeholder="请输入用户名"
|
||||
autocomplete="off"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><User /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="form.password"
|
||||
type="password"
|
||||
size="large"
|
||||
show-password
|
||||
placeholder="请输入密码"
|
||||
autocomplete="off"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Lock /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="register">
|
||||
<a @click="$router.push('forgetPassword')">忘记密码</a>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="验证码登录" name="mobileLogin">
|
||||
<el-form
|
||||
ref="formSms"
|
||||
:model="formSms"
|
||||
:rules="ruleInline"
|
||||
@click.self="$refs.verify.show = false"
|
||||
>
|
||||
<el-form-item prop="mobile">
|
||||
<el-input
|
||||
v-model="formSms.mobile"
|
||||
maxlength="11"
|
||||
clearable
|
||||
placeholder="手机号"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-icon><Iphone /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<el-input v-model="formSms.code" placeholder="手机验证码">
|
||||
<template #prepend>
|
||||
<el-icon><Message /></el-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button @click="sendCode" :loading="sendCodeLoading">
|
||||
{{ codeMsg }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-row>
|
||||
<el-button
|
||||
class="login-btn"
|
||||
type="primary"
|
||||
size="large"
|
||||
:loading="loading"
|
||||
style="width: 100%"
|
||||
@click="submitLogin"
|
||||
>
|
||||
<span v-if="!loading">登录</span>
|
||||
<span v-else>登录中</span>
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-row>
|
||||
<verify
|
||||
ref="verify"
|
||||
class="verify-con"
|
||||
verifyType="LOGIN"
|
||||
@change="verifyChange"
|
||||
/>
|
||||
<Footer />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { User, Lock, Iphone, Message } from "@element-plus/icons-vue";
|
||||
import * as RegExp from "@/utils/regular.js";
|
||||
import { sendSms } from "@/api/common.js";
|
||||
import { login, storeSmsLogin, userMsg } from "@/api/index";
|
||||
import util from "@/libs/util.js";
|
||||
@@ -67,55 +114,40 @@ import Footer from "@/views/main-components/footer";
|
||||
import Header from "@/views/main-components/header";
|
||||
import verify from "@/views/my-components/verify";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Header,
|
||||
Footer,
|
||||
verify,
|
||||
User,
|
||||
Lock,
|
||||
Iphone,
|
||||
Message,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
saveLogin: true, // 保存登录状态
|
||||
sendCodeLoading:false,
|
||||
loading: false, // 加载状态
|
||||
verifyStatus: false, // 是否图片验证通过
|
||||
time: 60, // 倒计时
|
||||
loginType: 'passwordLogin', //登陆类型
|
||||
saveLogin: true,
|
||||
sendCodeLoading: false,
|
||||
loading: false,
|
||||
verifyStatus: false,
|
||||
time: 60,
|
||||
loginType: "passwordLogin",
|
||||
form: {
|
||||
// 表单数据
|
||||
username: "",
|
||||
password: "",
|
||||
mobile: "",
|
||||
code: "",
|
||||
},
|
||||
formSms: {
|
||||
mobile: '',
|
||||
code: '',
|
||||
mobile: "",
|
||||
code: "",
|
||||
},
|
||||
rules: {
|
||||
// 验证规则
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "账号不能为空",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "密码不能为空",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
username: [{ required: true, message: "账号不能为空", trigger: "blur" }],
|
||||
password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
|
||||
},
|
||||
ruleInline: {
|
||||
// 验证规则
|
||||
username: [{ required: true, message: "请输入用户名" }],
|
||||
password: [
|
||||
{ required: true, message: "请输入密码" },
|
||||
{ type: "string", min: 6, message: "密码不能少于6位" },
|
||||
],
|
||||
mobile: [
|
||||
{ required: true, message: "请输入手机号码" },
|
||||
{
|
||||
@@ -125,28 +157,22 @@ export default {
|
||||
],
|
||||
code: [{ required: true, message: "请输入手机验证码" }],
|
||||
},
|
||||
codeMsg: "发送验证码", // 验证码文字
|
||||
codeMsg: "发送验证码",
|
||||
};
|
||||
},
|
||||
created() {
|
||||
window.localStorage.setItem("menuData", "");
|
||||
},
|
||||
|
||||
methods: {
|
||||
afterLogin(res) {
|
||||
let accessToken = res.result.accessToken;
|
||||
const accessToken = res.result.accessToken;
|
||||
this.setStore("accessToken", accessToken);
|
||||
this.setStore("refreshToken", res.result.refreshToken);
|
||||
|
||||
// 获取用户信息
|
||||
userMsg().then((res) => {
|
||||
if (res.success) {
|
||||
// location.reload();
|
||||
// this.$router.go(0);
|
||||
|
||||
this.setStore("saveLogin", this.saveLogin);
|
||||
if (this.saveLogin) {
|
||||
// 保存7天
|
||||
Cookies.set("userInfoSeller", JSON.stringify(res.result), {
|
||||
expires: 7,
|
||||
});
|
||||
@@ -158,18 +184,14 @@ export default {
|
||||
this.$store.commit("setAvatarPath", res.result.storeLogo);
|
||||
|
||||
const redirectRouter = this.$route.query.redirect;
|
||||
// 加载菜单
|
||||
const push = {
|
||||
this.$router.push({
|
||||
path: redirectRouter || "/home",
|
||||
}
|
||||
|
||||
this.$router.push(push);
|
||||
});
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 发送手机验证码
|
||||
sendCode() {
|
||||
if (this.formSms.mobile === "") {
|
||||
this.$Message.warning("请先填写手机号");
|
||||
@@ -177,73 +199,71 @@ export default {
|
||||
}
|
||||
if (!this.verifyStatus) {
|
||||
this.$refs.verify.init();
|
||||
return
|
||||
return;
|
||||
}
|
||||
if (this.time === 60) {
|
||||
this.sendCodeLoading = true
|
||||
let params = {
|
||||
this.sendCodeLoading = true;
|
||||
const params = {
|
||||
mobile: this.formSms.mobile,
|
||||
verificationEnums: "LOGIN",
|
||||
};
|
||||
sendSms(params).then((res) => {
|
||||
|
||||
if (res.success) {
|
||||
this.$Message.success("验证码发送成功");
|
||||
let that = this;
|
||||
this.interval = setInterval(() => {
|
||||
// this.sendCodeLoading = false
|
||||
that.time--;
|
||||
if (that.time === 0) {
|
||||
this.sendCodeLoading = false
|
||||
that.time = 60;
|
||||
that.codeMsg = "重新发送";
|
||||
that.verifyStatus = false;
|
||||
clearInterval(that.interval);
|
||||
} else {
|
||||
that.codeMsg = that.time;
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
this.$Message.warning(res.message);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.sendCodeLoading = false
|
||||
});
|
||||
sendSms(params)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("验证码发送成功");
|
||||
const that = this;
|
||||
this.interval = setInterval(() => {
|
||||
that.time--;
|
||||
if (that.time === 0) {
|
||||
this.sendCodeLoading = false;
|
||||
that.time = 60;
|
||||
that.codeMsg = "重新发送";
|
||||
that.verifyStatus = false;
|
||||
clearInterval(that.interval);
|
||||
} else {
|
||||
that.codeMsg = that.time;
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
this.$Message.warning(res.message);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.sendCodeLoading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
submitLogin() {
|
||||
// 登录提交
|
||||
if (this.loginType == 'passwordLogin') {
|
||||
if (this.loginType === "passwordLogin") {
|
||||
this.$refs.usernameLoginForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$refs.verify.init();
|
||||
}
|
||||
});
|
||||
} else if (this.loginType == 'mobileLogin') {
|
||||
this.$refs['formSms'].validate((valid) => {
|
||||
} else if (this.loginType === "mobileLogin") {
|
||||
this.$refs.formSms.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
|
||||
storeSmsLogin(this.formSms).then(res => {
|
||||
this.loading = false;
|
||||
|
||||
if (res.success) {
|
||||
this.afterLogin(res)
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
})
|
||||
storeSmsLogin(this.formSms)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.afterLogin(res);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
verifyChange(con) {
|
||||
// 拼图验证码回显
|
||||
if (!con.status) return;
|
||||
|
||||
if (this.loginType == 'passwordLogin') {
|
||||
if (this.loginType === "passwordLogin") {
|
||||
this.loading = true;
|
||||
let fd = new FormData();
|
||||
const fd = new FormData();
|
||||
fd.append("username", this.form.username);
|
||||
fd.append("password", this.md5(this.form.password));
|
||||
login(fd)
|
||||
@@ -258,22 +278,15 @@ export default {
|
||||
});
|
||||
} else {
|
||||
this.verifyStatus = true;
|
||||
|
||||
this.sendCode()
|
||||
this.sendCode();
|
||||
}
|
||||
|
||||
this.$refs.verify.show = false;
|
||||
},
|
||||
|
||||
// 开启滑块验证
|
||||
verifyBtnClick() {
|
||||
if (!this.verifyStatus) {
|
||||
this.$refs.verify.init();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login {
|
||||
height: 100%;
|
||||
@@ -299,22 +312,24 @@ export default {
|
||||
.login-btn {
|
||||
background: linear-gradient(135deg, $theme_color 0%, $warning_color 100%);
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
transition: 0.35s;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.login-btn:hover {
|
||||
opacity: 0.9;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.register {
|
||||
text-align: right;
|
||||
margin-bottom: 12px;
|
||||
a {
|
||||
color: $theme_color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex {
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,64 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<Drawer width="300px" title="页面配置" v-model="drawer">
|
||||
<!-- 内容 -->
|
||||
<h3>
|
||||
内容设置
|
||||
</h3>
|
||||
<el-drawer v-model="drawer" title="页面配置" size="300px">
|
||||
<h3>内容设置</h3>
|
||||
<div class="config-item flex flex-a-c flex-j-sb">
|
||||
<div>
|
||||
<Tooltip theme="light" placement="bottom-end" max-width="100" content="关闭之后部分页面点击'查看''详情'等按钮将跳到新页面展示" >
|
||||
<div>
|
||||
多标签Tab页内嵌模式
|
||||
</div>
|
||||
</Tooltip>
|
||||
<el-tooltip
|
||||
placement="bottom-end"
|
||||
content="关闭之后部分页面点击'查看''详情'等按钮将跳到新页面展示"
|
||||
>
|
||||
<div>多标签Tab页内嵌模式</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<i-switch v-model="setting.isUseTabsRouter"></i-switch>
|
||||
<el-switch v-model="setting.isUseTabsRouter" />
|
||||
</div>
|
||||
</Drawer>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "configDrawer",
|
||||
data() {
|
||||
return {
|
||||
drawer: false,
|
||||
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
setting: state => {
|
||||
return state.setting.setting
|
||||
}
|
||||
})
|
||||
setting: (state) => state.setting.setting,
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
setting: {
|
||||
handler(val) {
|
||||
this.setStore('setting', val)
|
||||
this.$store.commit('updateSetting', val);
|
||||
this.setStore("setting", val);
|
||||
this.$store.commit("updateSetting", val);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.drawer = true
|
||||
this.drawer = true;
|
||||
},
|
||||
close() {
|
||||
this.drawer = false
|
||||
this.drawer = false;
|
||||
},
|
||||
toggle() {
|
||||
this.drawer != this.drawer
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="foot">
|
||||
<Row type="flex" justify="space-around" class="help">
|
||||
<el-row justify="space-around" class="help">
|
||||
<a class="item" :href="config.website" target="_blank">帮助</a>
|
||||
<a class="item" :href="config.website" target="_blank">隐私</a>
|
||||
<a class="item" :href="config.website" target="_blank">条款</a>
|
||||
</Row>
|
||||
<Row type="flex" justify="center" class="copyright">
|
||||
</el-row>
|
||||
<el-row justify="center" class="copyright">
|
||||
Copyright © {{ year }} - Present
|
||||
<a
|
||||
:href="config.website"
|
||||
@@ -14,18 +14,17 @@
|
||||
style="margin: 0 5px"
|
||||
>{{ config.title }}</a
|
||||
>
|
||||
</Row>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const config = require("@/config/index");
|
||||
export default {
|
||||
// name: "footer",
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
year: new Date().getFullYear(), // 年
|
||||
year: new Date().getFullYear(),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
<template>
|
||||
<div @click="handleChange" v-if="showFullScreenBtn" class="full-screen-btn-con">
|
||||
<Tooltip :content="value ? '退出全屏' : '全屏'" placement="bottom">
|
||||
<Icon :type="value ? 'ios-contract' : 'ios-expand'" :size="24"></Icon>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div v-if="showFullScreenBtn" @click="handleChange" class="full-screen-btn-con">
|
||||
<el-tooltip :content="modelValue ? '退出全屏' : '全屏'" placement="bottom">
|
||||
<el-icon :size="24">
|
||||
<ScaleToOriginal v-if="modelValue" />
|
||||
<FullScreen v-else />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { FullScreen, ScaleToOriginal } from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
name: "fullScreen",
|
||||
components: { FullScreen, ScaleToOriginal },
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue", "input", "on-change"],
|
||||
computed: {
|
||||
showFullScreenBtn() {
|
||||
return window.navigator.userAgent.indexOf("MSIE") < 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleFullscreen() {
|
||||
let main = document.body;
|
||||
if (this.value) {
|
||||
const main = document.body;
|
||||
if (this.modelValue) {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
@@ -47,34 +58,44 @@ export default {
|
||||
},
|
||||
handleChange() {
|
||||
this.handleFullscreen();
|
||||
}
|
||||
},
|
||||
emitFullscreenState(isFullscreen) {
|
||||
this.$emit("update:modelValue", isFullscreen);
|
||||
this.$emit("input", isFullscreen);
|
||||
this.$emit("on-change", isFullscreen);
|
||||
},
|
||||
onFullscreenChange() {
|
||||
const isFullscreen = !!(
|
||||
document.fullscreenElement ||
|
||||
document.mozFullScreenElement ||
|
||||
document.webkitFullscreenElement ||
|
||||
document.fullScreen ||
|
||||
document.mozFullScreen ||
|
||||
document.webkitIsFullScreen
|
||||
);
|
||||
this.emitFullscreenState(isFullscreen);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
let isFullscreen =
|
||||
const isFullscreen = !!(
|
||||
document.fullscreenElement ||
|
||||
document.mozFullScreenElement ||
|
||||
document.webkitFullscreenElement ||
|
||||
document.fullScreen ||
|
||||
document.mozFullScreen ||
|
||||
document.webkitIsFullScreen;
|
||||
isFullscreen = !!isFullscreen;
|
||||
document.addEventListener("fullscreenchange", () => {
|
||||
this.$emit("input", !this.value);
|
||||
this.$emit("on-change", !this.value);
|
||||
});
|
||||
document.addEventListener("mozfullscreenchange", () => {
|
||||
this.$emit("input", !this.value);
|
||||
this.$emit("on-change", !this.value);
|
||||
});
|
||||
document.addEventListener("webkitfullscreenchange", () => {
|
||||
this.$emit("input", !this.value);
|
||||
this.$emit("on-change", !this.value);
|
||||
});
|
||||
document.addEventListener("msfullscreenchange", () => {
|
||||
this.$emit("input", !this.value);
|
||||
this.$emit("on-change", !this.value);
|
||||
});
|
||||
this.$emit("input", isFullscreen);
|
||||
}
|
||||
document.webkitIsFullScreen
|
||||
);
|
||||
this.emitFullscreenState(isFullscreen);
|
||||
document.addEventListener("fullscreenchange", this.onFullscreenChange);
|
||||
document.addEventListener("mozfullscreenchange", this.onFullscreenChange);
|
||||
document.addEventListener("webkitfullscreenchange", this.onFullscreenChange);
|
||||
document.addEventListener("msfullscreenchange", this.onFullscreenChange);
|
||||
},
|
||||
beforeUnmount() {
|
||||
document.removeEventListener("fullscreenchange", this.onFullscreenChange);
|
||||
document.removeEventListener("mozfullscreenchange", this.onFullscreenChange);
|
||||
document.removeEventListener("webkitfullscreenchange", this.onFullscreenChange);
|
||||
document.removeEventListener("msfullscreenchange", this.onFullscreenChange);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<Row class="header">
|
||||
<el-row class="header">
|
||||
<img class="logo" :src="storeSideLogo" />
|
||||
</Row>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getBaseSite } from "@/api/common.js";
|
||||
|
||||
export default {
|
||||
// name: "header",
|
||||
data() {
|
||||
return {
|
||||
storeSideLogo: require("@/assets/logo.png"),
|
||||
@@ -24,53 +24,39 @@ export default {
|
||||
!localStorage.getItem("seller_expiration_time")
|
||||
) {
|
||||
this.getSite();
|
||||
} else if (new Date() > localStorage.getItem("seller_expiration_time")) {
|
||||
this.getSite();
|
||||
} else {
|
||||
// 如果缓存过期,则获取最新的信息
|
||||
if (new Date() > localStorage.getItem("seller_expiration_time")) {
|
||||
this.getSite();
|
||||
return;
|
||||
} else {
|
||||
this.storeSideLogo = localStorage.getItem("sellerlogoImg");
|
||||
window.document.title = localStorage.getItem("sellersiteName");
|
||||
//动态获取icon
|
||||
let link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = localStorage.getItem("sellerIconImg");
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
}
|
||||
this.storeSideLogo = localStorage.getItem("sellerlogoImg");
|
||||
window.document.title = localStorage.getItem("sellersiteName");
|
||||
this.applyFavicon(localStorage.getItem("sellerIconImg"));
|
||||
}
|
||||
},
|
||||
applyFavicon(href) {
|
||||
const link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = href;
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
},
|
||||
getSite() {
|
||||
//获取基本站点信息
|
||||
getBaseSite().then((res) => {
|
||||
if (res.success && res.result.settingValue) {
|
||||
let data = JSON.parse(res.result.settingValue);
|
||||
// 过期时间
|
||||
var expirationTime = new Date().setHours(new Date().getHours() + 1);
|
||||
// 存放过期时间
|
||||
const data = JSON.parse(res.result.settingValue);
|
||||
const expirationTime = new Date().setHours(new Date().getHours() + 1);
|
||||
localStorage.setItem("seller_expiration_time", expirationTime);
|
||||
// 存放信息
|
||||
localStorage.setItem("sellersiteName", data.siteName);
|
||||
localStorage.setItem("sellerlogoImg", data.storeSideLogo);
|
||||
localStorage.setItem("sellerIconImg", data.storeSideIcon);
|
||||
console.log(data, "datadadada");
|
||||
this.storeSideLogo = data.storeSideLogo;
|
||||
window.document.title = data.siteName;
|
||||
//动态获取icon
|
||||
let link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = data.storeSideIcon;
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
this.applyFavicon(data.storeSideIcon);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
|
||||
@@ -1,34 +1,41 @@
|
||||
<template>
|
||||
<div @click="showMessage" class="message-con">
|
||||
<Tooltip :always="value>0" :content="value > 0 ? '有' + value + message : '无未读消息'" placement="bottom">
|
||||
<Badge :count="value" dot>
|
||||
<Icon type="md-notifications" :size="22" />
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
<el-tooltip
|
||||
:visible="value > 0 ? undefined : false"
|
||||
:content="value > 0 ? '有' + value + message : '无未读消息'"
|
||||
placement="bottom"
|
||||
>
|
||||
<el-badge :value="value" :hidden="value <= 0" is-dot>
|
||||
<el-icon :size="22"><Bell /></el-icon>
|
||||
</el-badge>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Bell } from "@element-plus/icons-vue";
|
||||
import util from "@/libs/util.js";
|
||||
|
||||
export default {
|
||||
name: "messageTip",
|
||||
components: { Bell },
|
||||
props: {
|
||||
value: { // 未读消息数量
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
default: 0,
|
||||
},
|
||||
message:{ // 消息展示内容
|
||||
message: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
showMessage() {
|
||||
util.openNewPage(this, "message_index");
|
||||
this.$router.push({
|
||||
name: "message_index"
|
||||
name: "message_index",
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,79 +1,117 @@
|
||||
<style lang="scss" scoped>
|
||||
@import "./styles/menu.scss";
|
||||
</style>
|
||||
<template>
|
||||
<div class="ivu-shrinkable-menu">
|
||||
<!-- 一级菜单 -->
|
||||
<Menu ref="sideMenu" width="80px" theme="dark" :active-name="currNav" @on-select="selectNav">
|
||||
<MenuItem v-for="(item, i) in navList" :key="i" :name="item.name">
|
||||
{{item.title}}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<!-- 二级菜单 -->
|
||||
<Menu
|
||||
ref="childrenMenu"
|
||||
:active-name="$route.name"
|
||||
width="100px"
|
||||
@on-select="changeMenu"
|
||||
<div class="shrinkable-menu">
|
||||
<el-menu
|
||||
ref="sideMenu"
|
||||
class="nav-menu-dark"
|
||||
:default-active="currNav"
|
||||
@select="selectNav"
|
||||
>
|
||||
<template v-for="item in menuList">
|
||||
<MenuGroup :title="item.title" :key="item.id" style="padding-left:0;">
|
||||
<MenuItem :name="menu.name" v-for="menu in item.children" :key="menu.name">
|
||||
{{menu.title}}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
|
||||
<el-menu-item v-for="(item, i) in navList" :key="i" :index="item.name">
|
||||
{{ item.title }}
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<el-menu
|
||||
ref="childrenMenu"
|
||||
:key="currNav"
|
||||
class="sub-menu"
|
||||
:default-active="$route.name"
|
||||
@select="changeMenu"
|
||||
>
|
||||
<template v-for="item in menuList" :key="item.id">
|
||||
<el-menu-item-group :title="item.title">
|
||||
<el-menu-item
|
||||
v-for="menu in item.children"
|
||||
:key="menu.name"
|
||||
:index="menu.name"
|
||||
>
|
||||
{{ menu.title }}
|
||||
</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</template>
|
||||
</Menu>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from "@/libs/util.js";
|
||||
|
||||
export default {
|
||||
name: "shrinkableMenu",
|
||||
computed: {
|
||||
|
||||
// 二级菜单列表
|
||||
menuList() {
|
||||
return this.$store.state.app.menuList;
|
||||
},
|
||||
// 一级菜单
|
||||
navList() {
|
||||
return this.$store.state.app.navList;
|
||||
},
|
||||
// 当前一级菜单
|
||||
currNav() {
|
||||
return this.$store.state.app.currNav;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
// 监听路由变化
|
||||
$route: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val.meta.firstRouterName && val.meta.firstRouterName !== this.currNav) {
|
||||
this.selectNav(val.meta.firstRouterName)
|
||||
}
|
||||
$route(val) {
|
||||
if (
|
||||
val.meta.firstRouterName &&
|
||||
val.meta.firstRouterName !== this.currNav
|
||||
) {
|
||||
this.selectNav(val.meta.firstRouterName);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
changeMenu(name) { //二级路由点击
|
||||
this.$router.push({
|
||||
name: name
|
||||
});
|
||||
changeMenu(name) {
|
||||
if (!name) return;
|
||||
this.$router.push({ name });
|
||||
},
|
||||
selectNav(name) { // 一级路由点击
|
||||
this.$store.commit("childrenMenu",this.$refs.childrenMenu)
|
||||
selectNav(name) {
|
||||
this.$store.commit("childrenMenu", this.$refs.childrenMenu);
|
||||
this.$store.commit("setCurrNav", name);
|
||||
this.setStore("currNav", name);
|
||||
util.initRouter(this);
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
|
||||
color: $theme_color;
|
||||
.shrinkable-menu {
|
||||
height: calc(100% - 60px);
|
||||
width: 180px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.nav-menu-dark {
|
||||
width: 80px;
|
||||
background-color: #191a23;
|
||||
border-right: none;
|
||||
overflow-y: auto;
|
||||
|
||||
:deep(.el-menu-item) {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
justify-content: center;
|
||||
padding: 0 8px !important;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
height: auto;
|
||||
min-height: 56px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
:deep(.el-menu-item.is-active) {
|
||||
background-color: #fff !important;
|
||||
color: $theme_color !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-menu {
|
||||
width: 100px;
|
||||
overflow-y: auto;
|
||||
border-right: none;
|
||||
|
||||
:deep(.el-menu-item-group__title) {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,25 +1,10 @@
|
||||
.ivu-shrinkable-menu{
|
||||
.shrinkable-menu {
|
||||
height: calc(100% - 60px);
|
||||
width: 180px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ivu-btn-text:hover {
|
||||
background-color: rgba(255,255,255,.2) !important;
|
||||
}
|
||||
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
|
||||
background-color: #fff;
|
||||
&:hover{
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
.ivu-menu-vertical{
|
||||
overflow-y: auto;
|
||||
}
|
||||
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
|
||||
color: #ed3f14;
|
||||
}
|
||||
::v-deep .ivu-menu-vertical .ivu-menu-item-group-title{
|
||||
:deep(.el-menu-item-group__title) {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-left: 20px;
|
||||
|
||||
@@ -1,33 +1,42 @@
|
||||
<style lang="scss" scoped>
|
||||
@import "../main.scss";
|
||||
</style>
|
||||
|
||||
<template>
|
||||
|
||||
<div
|
||||
ref="scrollCon"
|
||||
@DOMMouseScroll="handlescroll"
|
||||
@mousewheel="handlescroll"
|
||||
class="tags-outer-scroll-con"
|
||||
>
|
||||
<ul v-show="visible" :style="{left: contextMenuLeft + 'px', top: contextMenuTop + 'px'}" class="contextmenu">
|
||||
<li v-for="(item, key) of actionList" @click="handleTagsOption(key)" :key="key">{{item}}</li>
|
||||
<ul
|
||||
v-show="visible"
|
||||
:style="{ left: contextMenuLeft + 'px', top: contextMenuTop + 'px' }"
|
||||
class="contextmenu"
|
||||
>
|
||||
<li
|
||||
v-for="(item, key) of actionList"
|
||||
:key="key"
|
||||
@click="handleTagsOption(key)"
|
||||
>
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
<div ref="scrollBody" class="tags-inner-scroll-body" :style="{left: tagBodyLeft + 'px'}">
|
||||
<transition-group name="taglist-moving-animation">
|
||||
<Tag
|
||||
type="dot"
|
||||
v-for="item in pageTagsList"
|
||||
ref="tagsPageOpened"
|
||||
:key="item.name"
|
||||
:name="item.name"
|
||||
@on-close="closePage"
|
||||
@click.native="linkTo(item)"
|
||||
:closable="item.name=='home_index'?false:true"
|
||||
:color="item.children?(item.children[0].name==currentPageName?'primary':'default'):(item.name==currentPageName?'primary':'default')"
|
||||
@contextmenu.prevent.native="contextMenu(item, $event)"
|
||||
>{{ itemTitle(item) }}</Tag>
|
||||
</transition-group>
|
||||
<div
|
||||
ref="scrollBody"
|
||||
class="tags-inner-scroll-body"
|
||||
:style="{ left: tagBodyLeft + 'px' }"
|
||||
>
|
||||
<el-tag
|
||||
v-for="item in pageTagsList"
|
||||
:key="item.name"
|
||||
:closable="item.name !== 'home_index'"
|
||||
:type="tagType(item)"
|
||||
:effect="isActive(item) ? 'dark' : 'plain'"
|
||||
class="page-tag"
|
||||
size="large"
|
||||
@close="closePage($event, item.name)"
|
||||
@click="linkTo(item)"
|
||||
@contextmenu.prevent="contextMenu(item, $event)"
|
||||
>
|
||||
{{ itemTitle(item) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -35,218 +44,149 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "tagsPageOpened",
|
||||
data() {
|
||||
return {
|
||||
currentPageName: this.$route.name, // 当前路由名称
|
||||
tagBodyLeft: 0, // 标签左偏移量
|
||||
visible: false, // 显示操作按钮
|
||||
contextMenuLeft: 0, // 内容左偏移量
|
||||
contextMenuTop: 0, // 内容上偏移量
|
||||
actionList: { // 右键菜单
|
||||
others: '关闭其他',
|
||||
clearAll: '关闭所有'
|
||||
},
|
||||
refsTag: [], // 所有已打开标签
|
||||
tagsCount: 1 // 标签数量
|
||||
};
|
||||
},
|
||||
props: {
|
||||
pageTagsList: Array,
|
||||
beforePush: {
|
||||
type: Function,
|
||||
default: item => {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
default: () => true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentPageName: this.$route.name,
|
||||
tagBodyLeft: 0,
|
||||
visible: false,
|
||||
contextMenuLeft: 0,
|
||||
contextMenuTop: 0,
|
||||
actionList: {
|
||||
others: "关闭其他",
|
||||
clearAll: "关闭所有",
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return this.$store.state.app.currentTitle;
|
||||
},
|
||||
tagsList() {
|
||||
return this.$store.state.app.storeOpenedList;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 格式化标签名
|
||||
isActive(item) {
|
||||
return item.children
|
||||
? item.children[0].name === this.currentPageName
|
||||
: item.name === this.currentPageName;
|
||||
},
|
||||
tagType(item) {
|
||||
return this.isActive(item) ? "primary" : "info";
|
||||
},
|
||||
itemTitle(item) {
|
||||
if (typeof item.title == "object") {
|
||||
return item.title;
|
||||
} else {
|
||||
if (typeof item.title === "object") {
|
||||
return item.title;
|
||||
}
|
||||
return item.title;
|
||||
},
|
||||
// 关闭页面
|
||||
closePage(event, name) {
|
||||
let storeOpenedList = this.$store.state.app.storeOpenedList;
|
||||
let lastPageObj = storeOpenedList[0];
|
||||
if (this.currentPageName == name) {
|
||||
let len = storeOpenedList.length;
|
||||
if (this.currentPageName === name) {
|
||||
const len = storeOpenedList.length;
|
||||
for (let i = 1; i < len; i++) {
|
||||
if (storeOpenedList[i].name == name) {
|
||||
if (i < len - 1) {
|
||||
lastPageObj = storeOpenedList[i + 1];
|
||||
} else {
|
||||
lastPageObj = storeOpenedList[i - 1];
|
||||
}
|
||||
if (storeOpenedList[i].name === name) {
|
||||
lastPageObj =
|
||||
i < len - 1 ? storeOpenedList[i + 1] : storeOpenedList[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let tagWidth = event.target.parentNode.offsetWidth;
|
||||
} else if (event && event.target) {
|
||||
const tagWidth = event.target.parentNode?.offsetWidth || 0;
|
||||
this.tagBodyLeft = Math.min(this.tagBodyLeft + tagWidth, 0);
|
||||
}
|
||||
this.$store.commit("removeTag", name);
|
||||
this.$store.commit("closePage", name);
|
||||
storeOpenedList = this.$store.state.app.storeOpenedList;
|
||||
localStorage.storeOpenedList = JSON.stringify(storeOpenedList);
|
||||
if (this.currentPageName == name) {
|
||||
if (this.currentPageName === name) {
|
||||
this.linkTo(lastPageObj);
|
||||
}
|
||||
},
|
||||
// 跳转
|
||||
linkTo(item) {
|
||||
if (this.$route.name == item.name) {
|
||||
return;
|
||||
}
|
||||
let routerObj = {};
|
||||
routerObj.name = item.name;
|
||||
if (item.argu) {
|
||||
routerObj.params = item.argu;
|
||||
}
|
||||
if (item.query) {
|
||||
routerObj.query = item.query;
|
||||
}
|
||||
if (this.$route.name === item.name) return;
|
||||
const routerObj = { name: item.name };
|
||||
if (item.argu) routerObj.params = item.argu;
|
||||
if (item.query) routerObj.query = item.query;
|
||||
if (this.beforePush(item)) {
|
||||
this.$router.push(routerObj);
|
||||
}
|
||||
},
|
||||
// 页签栏滚动
|
||||
handlescroll(e) {
|
||||
var type = e.type;
|
||||
const type = e.type;
|
||||
let delta = 0;
|
||||
if (type == "DOMMouseScroll" || type == "mousewheel") {
|
||||
if (type === "DOMMouseScroll" || type === "mousewheel") {
|
||||
delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0) * 40;
|
||||
}
|
||||
let left = 0;
|
||||
if (delta > 0) {
|
||||
left = Math.min(0, this.tagBodyLeft + delta);
|
||||
} else {
|
||||
} else if (
|
||||
this.$refs.scrollCon.offsetWidth - 100 <
|
||||
this.$refs.scrollBody.offsetWidth
|
||||
) {
|
||||
if (
|
||||
this.$refs.scrollCon.offsetWidth - 100 <
|
||||
this.$refs.scrollBody.offsetWidth
|
||||
this.tagBodyLeft <
|
||||
-(this.$refs.scrollBody.offsetWidth - this.$refs.scrollCon.offsetWidth + 100)
|
||||
) {
|
||||
if (
|
||||
this.tagBodyLeft <
|
||||
-(
|
||||
this.$refs.scrollBody.offsetWidth -
|
||||
this.$refs.scrollCon.offsetWidth +
|
||||
100
|
||||
)
|
||||
) {
|
||||
left = this.tagBodyLeft;
|
||||
} else {
|
||||
left = Math.max(
|
||||
this.tagBodyLeft + delta,
|
||||
this.$refs.scrollCon.offsetWidth -
|
||||
this.$refs.scrollBody.offsetWidth -
|
||||
100
|
||||
);
|
||||
}
|
||||
left = this.tagBodyLeft;
|
||||
} else {
|
||||
this.tagBodyLeft = 0;
|
||||
left = Math.max(
|
||||
this.tagBodyLeft + delta,
|
||||
this.$refs.scrollCon.offsetWidth -
|
||||
this.$refs.scrollBody.offsetWidth -
|
||||
100
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.tagBodyLeft = 0;
|
||||
}
|
||||
this.tagBodyLeft = left;
|
||||
},
|
||||
// 标签右键操作
|
||||
handleTagsOption(type) {
|
||||
if (type == "clearAll") {
|
||||
if (type === "clearAll") {
|
||||
this.$store.commit("clearAllTags");
|
||||
this.$router.push({
|
||||
name: "home_index"
|
||||
});
|
||||
this.$router.push({ name: "home_index" });
|
||||
} else {
|
||||
this.$store.commit("clearOtherTags", this);
|
||||
}
|
||||
this.tagBodyLeft = 0;
|
||||
},
|
||||
// 标签栏滚动
|
||||
moveToView(tag) {
|
||||
if (tag.offsetLeft < -this.tagBodyLeft) {
|
||||
// 标签在可视区域左侧
|
||||
this.tagBodyLeft = -tag.offsetLeft + 10;
|
||||
} else if (
|
||||
tag.offsetLeft + 10 > -this.tagBodyLeft &&
|
||||
tag.offsetLeft + tag.offsetWidth <
|
||||
-this.tagBodyLeft + this.$refs.scrollCon.offsetWidth - 100
|
||||
) {
|
||||
// 标签在可视区域
|
||||
this.tagBodyLeft = Math.min(
|
||||
0,
|
||||
this.$refs.scrollCon.offsetWidth -
|
||||
100 -
|
||||
tag.offsetWidth -
|
||||
tag.offsetLeft -
|
||||
20
|
||||
);
|
||||
} else {
|
||||
// 标签在可视区域右侧
|
||||
this.tagBodyLeft = -(
|
||||
tag.offsetLeft -
|
||||
(this.$refs.scrollCon.offsetWidth - 100 - tag.offsetWidth) +
|
||||
20
|
||||
);
|
||||
}
|
||||
contextMenu(item, e) {
|
||||
this.visible = true;
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left;
|
||||
this.contextMenuLeft = e.clientX - offsetLeft + 10;
|
||||
this.contextMenuTop = e.clientY - 64;
|
||||
},
|
||||
// 显示操作按钮
|
||||
contextMenu (item, e) {
|
||||
this.visible = true
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left
|
||||
this.contextMenuLeft = e.clientX - offsetLeft + 10
|
||||
this.contextMenuTop = e.clientY - 64
|
||||
closeMenu() {
|
||||
this.visible = false;
|
||||
},
|
||||
// 关闭右侧菜单
|
||||
closeMenu () {
|
||||
this.visible = false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.refsTag = this.$refs.tagsPageOpened;
|
||||
setTimeout(() => {
|
||||
this.refsTag.forEach((item, index) => {
|
||||
if (this.$route.name == item.name) {
|
||||
let tag = this.refsTag[index].$el;
|
||||
this.moveToView(tag);
|
||||
}
|
||||
});
|
||||
}, 1); // 这里不设定时器就会有偏移bug
|
||||
this.tagsCount = this.tagsList.length;
|
||||
},
|
||||
watch: {
|
||||
$route(to) {
|
||||
this.currentPageName = to.name;
|
||||
this.$nextTick(() => {
|
||||
this.refsTag.forEach((item, index) => {
|
||||
if (to.name == item.name) {
|
||||
let tag = this.refsTag[index].$el;
|
||||
this.moveToView(tag);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.tagsCount = this.tagsList.length;
|
||||
},
|
||||
visible (value) {
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener('click', this.closeMenu)
|
||||
document.body.addEventListener("click", this.closeMenu);
|
||||
} else {
|
||||
document.body.removeEventListener('click', this.closeMenu)
|
||||
document.body.removeEventListener("click", this.closeMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
document.body.removeEventListener("click", this.closeMenu);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/views/main.scss";
|
||||
.contextmenu {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
@@ -255,21 +195,35 @@ export default {
|
||||
z-index: 11000;
|
||||
list-style-type: none;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 5px 15px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: rgba($color: $theme_color, $alpha: .1);
|
||||
background: rgba($color: $theme_color, $alpha: 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.page-tag {
|
||||
margin-right: 8px;
|
||||
cursor: pointer;
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
.ivu-tag-primary{
|
||||
::v-deep .ivu-tag-dot-inner{
|
||||
background: $theme_color !important;
|
||||
& + .page-tag {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.el-tag__close {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,64 +1,128 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" @keydown.enter.native="handleSearch" inline :label-width="70" class="search-form">
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input type="text" v-model="searchForm.memberName" clearable placeholder="请输入会员名称" style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input type="text" v-model="searchForm.goodsName" clearable placeholder="请输入商品名" style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="评价" prop="orderStatus">
|
||||
<Select v-model="searchForm.grade" placeholder="请选择" clearable style="width: 240px">
|
||||
<Option value="GOOD">好评</Option>
|
||||
<Option value="MODERATE">中评</Option>
|
||||
<Option value="WORSE">差评</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="评论日期">
|
||||
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd HH:mm:ss" clearable @on-change="selectDateRange" placeholder="选择起始时间" style="width: 240px"></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small"
|
||||
show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal :title="modalTitle" v-model="modalVisible" :mask-closable="false" :width="500">
|
||||
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
|
||||
<FormItem label="评价内容">
|
||||
<span v-if="!content">暂无评价</span>
|
||||
<span v-else>
|
||||
<div>
|
||||
<Input v-model="content" type="textarea" maxlength="200" disabled :rows="4" clearable style="width:90%" />
|
||||
</div>
|
||||
</span>
|
||||
</FormItem>
|
||||
<FormItem label="评价图片" style="padding-top: 10px" v-if="detailInfo.haveImage == 1">
|
||||
<upload-pic-thumb v-model="image" :disable="true" :remove="false" :isView="true"></upload-pic-thumb>
|
||||
</FormItem>
|
||||
<FormItem label="回复内容" prop="reply">
|
||||
<Input v-if="replyStatus == false" v-model="form.reply" type="textarea" maxlength="200" :rows="4" clearable style="width:90%" />
|
||||
<span v-else>
|
||||
<Input v-model="form.reply" type="textarea" maxlength="200" disabled :rows="4" clearable style="width:90%" />
|
||||
</span>
|
||||
</FormItem>
|
||||
<FormItem label="回复图片" prop="replyImage" style="padding-top: 18px" v-if="detailInfo.haveReplyImage == 1 || replyStatus == false">
|
||||
<upload-pic-thumb v-if="replyStatus == false" v-model="form.replyImage" :limit="5"></upload-pic-thumb>
|
||||
<upload-pic-thumb v-else v-model="form.replyImage" :disable="true" :remove="false"></upload-pic-thumb>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button v-if="replyStatus == false" type="primary" :loading="submitLoading" @click="handleSubmit">回复
|
||||
</Button>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input v-model="searchForm.memberName" clearable placeholder="请输入会员名称" style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input v-model="searchForm.goodsName" clearable placeholder="请输入商品名" style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="评价" prop="grade">
|
||||
<el-select v-model="searchForm.grade" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="好评" value="GOOD" />
|
||||
<el-option label="中评" value="MODERATE" />
|
||||
<el-option label="差评" value="WORSE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="评论日期">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
style="width: 360px"
|
||||
@change="selectDateRange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
<el-button class="search-btn" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table v-loading="loading" border :data="data" ref="table" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="content" label="评价内容" min-width="300" show-overflow-tooltip />
|
||||
<el-table-column label="评价" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.grade === 'GOOD'" type="success">好评</el-tag>
|
||||
<el-tag v-else-if="row.grade === 'MODERATE'" type="warning">中评</el-tag>
|
||||
<el-tag v-else type="danger">差评</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.status === 'OPEN'" type="success">展示</el-tag>
|
||||
<el-tag v-else type="danger">隐藏</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="回复状态" width="110">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.replyStatus" type="success">已回复</el-tag>
|
||||
<el-tag v-else type="primary">未回复</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" width="170" />
|
||||
<el-table-column label="操作" align="center" fixed="right" width="100">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="detail(row)">详细</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="评价内容">
|
||||
<span v-if="!content">暂无评价</span>
|
||||
<el-input v-else v-model="content" type="textarea" maxlength="200" disabled :rows="4" style="width: 90%" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="detailInfo.haveImage == 1" label="评价图片" style="padding-top: 10px">
|
||||
<upload-pic-thumb v-model="image" :disable="true" :remove="false" :isView="true" />
|
||||
</el-form-item>
|
||||
<el-form-item label="回复内容" prop="reply">
|
||||
<el-input
|
||||
v-if="!replyStatus"
|
||||
v-model="form.reply"
|
||||
type="textarea"
|
||||
maxlength="200"
|
||||
:rows="4"
|
||||
clearable
|
||||
style="width: 90%"
|
||||
/>
|
||||
<el-input v-else v-model="form.reply" type="textarea" maxlength="200" disabled :rows="4" style="width: 90%" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="detailInfo.haveReplyImage == 1 || !replyStatus"
|
||||
label="回复图片"
|
||||
prop="replyImage"
|
||||
style="padding-top: 18px"
|
||||
>
|
||||
<upload-pic-thumb v-if="!replyStatus" v-model="form.replyImage" :limit="5" />
|
||||
<upload-pic-thumb v-else v-model="form.replyImage" :disable="true" :remove="false" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button v-if="!replyStatus" type="primary" :loading="submitLoading" @click="handleSubmit">回复</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -68,175 +132,74 @@ import uploadPicThumb from "@/views/my-components/lili/upload-pic-thumb";
|
||||
|
||||
export default {
|
||||
name: "memberComment",
|
||||
components: {
|
||||
uploadPicThumb,
|
||||
},
|
||||
components: { uploadPicThumb },
|
||||
data() {
|
||||
return {
|
||||
detailInfo: {}, // 详情信息
|
||||
image: [], //评价图片
|
||||
replyStatus: false, //回复状态
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
loading: true, // 表单加载状态
|
||||
content: "", //评价内容
|
||||
detailInfo: {},
|
||||
image: [],
|
||||
replyStatus: false,
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
loading: true,
|
||||
content: "",
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startTime: "", // 起始时间
|
||||
endTime: "", // 终止时间
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startTime: "",
|
||||
endTime: "",
|
||||
},
|
||||
selectDate: null,
|
||||
form: {
|
||||
replyImage: [],
|
||||
reply: "",
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
reply: [{ required: true, message: "请输入回复内容", trigger: "blur" }],
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 150,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 150,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "评价内容",
|
||||
key: "content",
|
||||
minWidth: 300,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "评价",
|
||||
key: "grade",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.grade == "GOOD") {
|
||||
return h("Tag", { props: { color: "green" } }, "好评");
|
||||
} else if (params.row.grade == "MODERATE") {
|
||||
return h("Tag", { props: { color: "orange" } }, "中评");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "red" } }, "差评");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "status",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.status === "OPEN") {
|
||||
return h("Tag", { props: { color: "green" } }, "展示");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "red" } }, "隐藏");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "回复状态",
|
||||
key: "replyStatus",
|
||||
width: 110,
|
||||
render: (h, params) => {
|
||||
if (params.row.replyStatus) {
|
||||
return h("Tag", { props: { color: "green" } }, "已回复");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "blue" } }, "未回复");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "创建日期",
|
||||
key: "createTime",
|
||||
width: 170,
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: 'right',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"详细"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
submitLoading: false,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// 初始化数据
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 改变页码
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {};
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startTime: "",
|
||||
endTime: "",
|
||||
};
|
||||
this.selectDate = null;
|
||||
this.getDataList();
|
||||
},
|
||||
// 清除选中状态
|
||||
clearSelectAll() {
|
||||
this.$refs.table.selectAll(false);
|
||||
},
|
||||
// 选择日期回调
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startTime = v[0];
|
||||
this.searchForm.endTime = v[1];
|
||||
} else {
|
||||
this.searchForm.startTime = "";
|
||||
this.searchForm.endTime = "";
|
||||
}
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberReview(this.searchForm).then((res) => {
|
||||
@@ -247,7 +210,6 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//回复
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
@@ -262,26 +224,19 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取详情
|
||||
detail(v) {
|
||||
this.form.replyImage = [];
|
||||
this.loading = true;
|
||||
API_Member.getMemberInfoReview(v.id).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
//赋值
|
||||
this.form.id = res.result.id;
|
||||
this.content = res.result.content;
|
||||
this.form.reply = res.result.reply;
|
||||
this.replyStatus = res.result.replyStatus;
|
||||
if (res.result.images) {
|
||||
this.image = (res.result.images || "").split(",");
|
||||
}
|
||||
if (res.result.replyImage) {
|
||||
this.form.replyImage = (res.result.replyImage || "").split(",");
|
||||
}
|
||||
this.image = res.result.images ? (res.result.images || "").split(",") : [];
|
||||
this.form.replyImage = res.result.replyImage ? (res.result.replyImage || "").split(",") : [];
|
||||
this.detailInfo = res.result;
|
||||
//弹出框
|
||||
this.modalVisible = true;
|
||||
this.modalTitle = "详细";
|
||||
}
|
||||
@@ -293,7 +248,12 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,81 +1,102 @@
|
||||
|
||||
<template>
|
||||
<div class="message-main-con">
|
||||
<div class="message-mainlist-con">
|
||||
<div>
|
||||
<Button @click="setCurrentMesType('unread')" size="large" long type="text">
|
||||
<el-button size="large" text style="width: 100%" @click="setCurrentMesType('unread')">
|
||||
<div class="mes-wrap">
|
||||
<transition name="mes-current-type-btn">
|
||||
<Icon v-show="currentMessageType == 'unread'" type="md-checkmark"></Icon>
|
||||
<el-icon v-show="currentMessageType == 'unread'"><Check /></el-icon>
|
||||
</transition>
|
||||
<span class="mes-type-btn-text">未读消息</span>
|
||||
<Badge
|
||||
class="message-count-badge-outer"
|
||||
class-name="message-count-badge-red"
|
||||
:count="unReadCount"
|
||||
></Badge>
|
||||
<el-badge :value="unReadCount" class="message-count-badge-outer" />
|
||||
</div>
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<Button @click="setCurrentMesType('read')" size="large" long type="text">
|
||||
<el-button size="large" text style="width: 100%" @click="setCurrentMesType('read')">
|
||||
<div class="mes-wrap">
|
||||
<transition name="mes-current-type-btn">
|
||||
<Icon v-show="currentMessageType == 'read'" type="md-checkmark"></Icon>
|
||||
<el-icon v-show="currentMessageType == 'read'"><Check /></el-icon>
|
||||
</transition>
|
||||
<span class="mes-type-btn-text">已读消息</span>
|
||||
</div>
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<Button @click="setCurrentMesType('recycleBin')" size="large" long type="text">
|
||||
<el-button size="large" text style="width: 100%" @click="setCurrentMesType('recycleBin')">
|
||||
<div class="mes-wrap">
|
||||
<transition name="mes-current-type-btn">
|
||||
<Icon v-show="currentMessageType == 'recycleBin'" type="md-checkmark"></Icon>
|
||||
<el-icon v-show="currentMessageType == 'recycleBin'"><Check /></el-icon>
|
||||
</transition>
|
||||
<span class="mes-type-btn-text">回收站</span>
|
||||
</div>
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-content-con">
|
||||
<transition name="view-message">
|
||||
<div v-if="showMesTitleList" class="message-title-list-con">
|
||||
<Table
|
||||
class="mt_10"
|
||||
<el-table
|
||||
ref="messageList"
|
||||
:loading="loading"
|
||||
:columns="mesTitleColumns"
|
||||
v-loading="loading"
|
||||
class="mt_10"
|
||||
:data="currentMesList"
|
||||
:no-data-text="noDataText"
|
||||
></Table>
|
||||
<Page
|
||||
:current="params.pageNumber"
|
||||
:total="total"
|
||||
:page-size="params.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[5,10]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
class="page-fix"
|
||||
></Page>
|
||||
:empty-text="noDataText"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label=" " min-width="300">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text mes-title-link" @click="openMessage(row)">{{ row.title }}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label=" " width="190" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-icon style="margin-right: 5px; vertical-align: middle"><Clock /></el-icon>
|
||||
<span>{{ row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label=" " width="210" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="currentMessageType == 'unread'">
|
||||
<a class="link-text" @click="markAsRead(row)">标为已读</a>
|
||||
</template>
|
||||
<template v-else-if="currentMessageType == 'read'">
|
||||
<a class="link-text" @click="deleteMes(row)">删除</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a class="link-text" @click="restoreMes(row)">还原</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="deleteReal(row)">彻底删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="page-fix mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="params.pageNumber"
|
||||
v-model:page-size="params.pageSize"
|
||||
:page-sizes="[5, 10]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="back-message-list">
|
||||
<div v-if="!showMesTitleList" class="message-view-content-con">
|
||||
<div class="message-content-top-bar">
|
||||
<span class="mes-back-btn-con">
|
||||
<Button type="text" @click="backMesTitleList">
|
||||
<Icon type="ios-arrow-back"></Icon> 返回
|
||||
</Button>
|
||||
<el-button type="primary" link @click="backMesTitleList">
|
||||
<el-icon><ArrowLeft /></el-icon> 返回
|
||||
</el-button>
|
||||
</span>
|
||||
<h3 class="mes-title">{{ mes.title }}</h3>
|
||||
</div>
|
||||
<p class="mes-time-con">
|
||||
<Icon type="android-time"></Icon>
|
||||
<el-icon><Clock /></el-icon>
|
||||
{{ mes.time }}
|
||||
</p>
|
||||
<div class="message-content-body">
|
||||
@@ -88,308 +109,145 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Index from "@/api/index";
|
||||
import { Check, Clock, ArrowLeft } from "@element-plus/icons-vue";
|
||||
import * as API_Index from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "message_index",
|
||||
data() {
|
||||
const markAsReadBtn = (h, params) => {
|
||||
return h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
let v = params.row;
|
||||
this.loading = true;
|
||||
API_Index.read(v.id).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.getAll();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
"标为已读"
|
||||
);
|
||||
};
|
||||
const deleteMesBtn = (h, params) => {
|
||||
return h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
let v = params.row;
|
||||
this.loading = true;
|
||||
API_Index.deleteMessage(v.id).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.refreshMessage();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
);
|
||||
};
|
||||
const restoreBtn = (h, params) => {
|
||||
return h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
let v = params.row;
|
||||
API_Index.reductionMessage(v.id).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.refreshMessage();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
"还原"
|
||||
);
|
||||
};
|
||||
const deleteRealBtn = (h, params) => {
|
||||
return h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
let v = params.row;
|
||||
this.loading = true;
|
||||
API_Index.clearMessage(v.id).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.refreshMessage();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
"彻底删除"
|
||||
);
|
||||
};
|
||||
return {
|
||||
loading: true, // 列表加载的loading
|
||||
params: { // 请求消息列表参数
|
||||
status: "UN_READY",
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc" // 默认排序方式
|
||||
},
|
||||
total: 0, // 消息列表总数
|
||||
totalUnread: 0, // 未读总数
|
||||
totalRead: 0, // 已读总数
|
||||
totalRemove: 0, // 回收站消息数
|
||||
currentMesList: [], // 当前状态消息
|
||||
unreadMesList: [], // 未读消息
|
||||
hasReadMesList: [], // 已读消息
|
||||
recyclebinList: [], // 回收站消息
|
||||
currentMessageType: "unread", // 当前列表消息状态
|
||||
showMesTitleList: true, // 是否展示消息状态列表
|
||||
unReadCount: 0, // 未读消息数量
|
||||
hasReadCount: 0, // 已读消息数量
|
||||
recycleBinCount: 0, // 回收站消息数量
|
||||
noDataText: "暂无未读消息",
|
||||
mes: { // 展示消息详情
|
||||
title: "",
|
||||
time: "",
|
||||
content: ""
|
||||
},
|
||||
mesTitleColumns: [ // 表格表头
|
||||
|
||||
{
|
||||
title: " ",
|
||||
key: "title",
|
||||
align: "left",
|
||||
ellipsis: true,
|
||||
render: (h, params) => {
|
||||
return h("span", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
margin: "0 30px 0 0"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showMesTitleList = false;
|
||||
this.mes.title = params.row.title;
|
||||
this.mes.time = params.row.createTime;
|
||||
this.getContent(params.row);
|
||||
}
|
||||
}
|
||||
},
|
||||
params.row.title
|
||||
)
|
||||
]);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: " ",
|
||||
key: "time",
|
||||
align: "center",
|
||||
width: 190,
|
||||
render: (h, params) => {
|
||||
return h("span", [
|
||||
h("Icon", {
|
||||
props: {
|
||||
type: "md-time",
|
||||
size: 16
|
||||
},
|
||||
style: {
|
||||
margin: "0 5px 3px 0"
|
||||
}
|
||||
}),
|
||||
h("span", params.row.createTime)
|
||||
]);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: " ",
|
||||
key: "asread",
|
||||
align: "center",
|
||||
width: 210,
|
||||
render: (h, params) => {
|
||||
if (this.currentMessageType == "unread") {
|
||||
return h("div", [markAsReadBtn(h, params)]);
|
||||
} else if (this.currentMessageType == "read") {
|
||||
return h("div", [deleteMesBtn(h, params)]);
|
||||
} else {
|
||||
return h("div", [
|
||||
restoreBtn(h, params),
|
||||
h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"),
|
||||
deleteRealBtn(h, params)
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
export default {
|
||||
name: "message_index",
|
||||
components: { Check, Clock, ArrowLeft },
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
params: {
|
||||
status: "UN_READY",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
total: 0,
|
||||
currentMesList: [],
|
||||
currentMessageType: "unread",
|
||||
showMesTitleList: true,
|
||||
unReadCount: 0,
|
||||
noDataText: "暂无未读消息",
|
||||
mes: {
|
||||
title: "",
|
||||
time: "",
|
||||
content: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changePage() {
|
||||
this.refreshMessage();
|
||||
},
|
||||
methods: {
|
||||
// 改变页数
|
||||
changePage(v) {
|
||||
this.params.pageNumber = v;
|
||||
this.refreshMessage();
|
||||
},
|
||||
// 改变页码
|
||||
changePageSize(v) {
|
||||
this.params.pageSize = v;
|
||||
this.refreshMessage();
|
||||
},
|
||||
// 刷新消息
|
||||
refreshMessage() {
|
||||
let status = "UN_READY";
|
||||
let type = this.currentMessageType;
|
||||
if (type == "unread") {
|
||||
status = "UN_READY";
|
||||
} else if (type == "read") {
|
||||
status = "ALREADY_READY";
|
||||
} else {
|
||||
status = "ALREADY_REMOVE";
|
||||
changePageSize() {
|
||||
this.refreshMessage();
|
||||
},
|
||||
refreshMessage() {
|
||||
let status = "UN_READY";
|
||||
const type = this.currentMessageType;
|
||||
if (type == "unread") status = "UN_READY";
|
||||
else if (type == "read") status = "ALREADY_READY";
|
||||
else status = "ALREADY_REMOVE";
|
||||
this.params.status = status;
|
||||
this.loading = true;
|
||||
API_Index.getMessageSendData(this.params).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.currentMesList = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
this.params.status = status;
|
||||
this.loading = true;
|
||||
API_Index.getMessageSendData(this.params).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.currentMesList = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
//获取全部数据
|
||||
getAll() {
|
||||
API_Index.getAllMessage(this.params).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
//未读消息
|
||||
this.unReadCount = res.result.UN_READY.total;
|
||||
this.currentMesList = res.result.UN_READY.records;
|
||||
//已读消息
|
||||
this.hasReadCount = res.result.ALREADY_READY.total;
|
||||
//回收站
|
||||
this.recycleBinCount = res.result.ALREADY_REMOVE.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除消息
|
||||
deleteMessage(id) {
|
||||
API_Index.deleteMessage(id).then(res => {
|
||||
if (res.success) {
|
||||
this.$Message.success("删除成功");
|
||||
}
|
||||
});
|
||||
},
|
||||
backMesTitleList() {
|
||||
});
|
||||
},
|
||||
getAll() {
|
||||
API_Index.getAllMessage(this.params).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.unReadCount = res.result.UN_READY.total;
|
||||
this.currentMesList = res.result.UN_READY.records;
|
||||
}
|
||||
});
|
||||
},
|
||||
backMesTitleList() {
|
||||
this.showMesTitleList = true;
|
||||
},
|
||||
setCurrentMesType(type) {
|
||||
if (this.currentMessageType !== type) {
|
||||
this.showMesTitleList = true;
|
||||
},
|
||||
// 设置当前消息分类
|
||||
setCurrentMesType(type) {
|
||||
if (this.currentMessageType !== type) {
|
||||
this.showMesTitleList = true;
|
||||
}
|
||||
this.currentMessageType = type;
|
||||
if (type == "unread") {
|
||||
this.noDataText = "暂无未读消息";
|
||||
} else if (type == "read") {
|
||||
this.noDataText = "暂无已读消息";
|
||||
} else {
|
||||
this.noDataText = "回收站无消息";
|
||||
}
|
||||
this.params.pageNumber = 1;
|
||||
this.refreshMessage();
|
||||
},
|
||||
getContent(v) {
|
||||
this.mes.content = v.content;
|
||||
|
||||
API_Index.read(v.id).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.getAll()();
|
||||
}
|
||||
});
|
||||
}
|
||||
this.currentMessageType = type;
|
||||
if (type == "unread") this.noDataText = "暂无未读消息";
|
||||
else if (type == "read") this.noDataText = "暂无已读消息";
|
||||
else this.noDataText = "回收站无消息";
|
||||
this.params.pageNumber = 1;
|
||||
this.refreshMessage();
|
||||
},
|
||||
mounted() {
|
||||
this.getAll();
|
||||
openMessage(row) {
|
||||
this.showMesTitleList = false;
|
||||
this.mes.title = row.title;
|
||||
this.mes.time = row.createTime;
|
||||
this.getContent(row);
|
||||
},
|
||||
watch: {
|
||||
// 监听路由变化通过id获取数据
|
||||
$route(to, from) {
|
||||
if (to.name == "message_index") {
|
||||
this.getAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
markAsRead(v) {
|
||||
this.loading = true;
|
||||
API_Index.read(v.id).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) this.getAll();
|
||||
});
|
||||
},
|
||||
deleteMes(v) {
|
||||
this.loading = true;
|
||||
API_Index.deleteMessage(v.id).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) this.refreshMessage();
|
||||
});
|
||||
},
|
||||
restoreMes(v) {
|
||||
API_Index.reductionMessage(v.id).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) this.refreshMessage();
|
||||
});
|
||||
},
|
||||
deleteReal(v) {
|
||||
this.loading = true;
|
||||
API_Index.clearMessage(v.id).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) this.refreshMessage();
|
||||
});
|
||||
},
|
||||
getContent(v) {
|
||||
this.mes.content = v.content;
|
||||
API_Index.read(v.id).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) this.getAll();
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getAll();
|
||||
},
|
||||
watch: {
|
||||
$route(to) {
|
||||
if (to.name == "message_index") this.getAll();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "./message.scss";
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
.mes-title-link {
|
||||
margin-right: 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
<template>
|
||||
<div style="display: inline-block;">
|
||||
<Icon type="ios-loading" size="18" color="#2d8cf0" class="spin-icon-load"></Icon>
|
||||
<div style="display: inline-block">
|
||||
<el-icon class="spin-icon-load" :size="18" color="#ff5c58">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Loading } from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
name: "circleLoading"
|
||||
name: "circleLoading",
|
||||
components: { Loading },
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -14,5 +19,12 @@ export default {
|
||||
.spin-icon-load {
|
||||
animation: ani-demo-spin 1s linear infinite;
|
||||
}
|
||||
@keyframes ani-demo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,72 +1,68 @@
|
||||
<template>
|
||||
<div>
|
||||
<Cascader
|
||||
<el-cascader
|
||||
v-model="selectDep"
|
||||
:data="department"
|
||||
@on-change="handleChangeDep"
|
||||
change-on-select
|
||||
:options="department"
|
||||
:props="cascaderProps"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择"
|
||||
></Cascader>
|
||||
style="width: 100%"
|
||||
@change="handleChangeDep"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { initDepartment } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "departmentChoose",
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectDep: [], // 已选数据
|
||||
department: [] // 列表
|
||||
selectDep: [],
|
||||
department: [],
|
||||
cascaderProps: {
|
||||
value: "value",
|
||||
label: "label",
|
||||
children: "children",
|
||||
checkStrictly: true,
|
||||
emitPath: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取部门数据
|
||||
initDepartmentData() {
|
||||
initDepartment().then(res => {
|
||||
initDepartment().then((res) => {
|
||||
if (res.success) {
|
||||
const arr = res.result;
|
||||
this.filterData(arr)
|
||||
this.department = arr
|
||||
this.filterData(arr);
|
||||
this.department = arr;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleChangeDep(value, selectedData) {
|
||||
handleChangeDep(value) {
|
||||
let departmentId = "";
|
||||
// 获取最后一个值
|
||||
if (value && value.length > 0) {
|
||||
departmentId = value[value.length - 1];
|
||||
}
|
||||
this.$emit("on-change", departmentId);
|
||||
},
|
||||
// 清空已选列表
|
||||
clearSelect() {
|
||||
this.selectDep = [];
|
||||
},
|
||||
// 处理部门数据
|
||||
filterData (data) {
|
||||
data.forEach(e => {
|
||||
filterData(data) {
|
||||
data.forEach((e) => {
|
||||
e.value = e.id;
|
||||
e.label = e.title;
|
||||
if (e.children) {
|
||||
this.filterData(e.children)
|
||||
} else {
|
||||
return
|
||||
this.filterData(e.children);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initDepartmentData();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,112 +1,123 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="display:flex;">
|
||||
<Input
|
||||
<div style="display: flex">
|
||||
<el-input
|
||||
v-model="departmentTitle"
|
||||
readonly
|
||||
style="margin-right:10px;"
|
||||
style="margin-right: 10px; flex: 1"
|
||||
:placeholder="placeholder"
|
||||
:clearable="clearable"
|
||||
@on-clear="clearSelect"
|
||||
@clear="clearSelect"
|
||||
/>
|
||||
<Poptip transfer trigger="click" placement="right" title="选择部门" width="250">
|
||||
<Button icon="md-list">选择部门</Button>
|
||||
<div slot="content">
|
||||
<Input
|
||||
v-model="searchKey"
|
||||
suffix="ios-search"
|
||||
@on-change="searchDep"
|
||||
placeholder="输入部门名搜索"
|
||||
clearable
|
||||
<el-popover trigger="click" placement="right" title="选择部门" :width="280">
|
||||
<template #reference>
|
||||
<el-button>选择部门</el-button>
|
||||
</template>
|
||||
<el-input
|
||||
v-model="searchKey"
|
||||
placeholder="输入部门名搜索"
|
||||
clearable
|
||||
style="margin-bottom: 8px"
|
||||
@input="searchDep"
|
||||
/>
|
||||
<div v-loading="depLoading" class="dep-tree-bar">
|
||||
<el-tree
|
||||
:data="dataDep"
|
||||
:props="treeProps"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
default-expand-all
|
||||
@node-click="selectTree"
|
||||
/>
|
||||
<div class="dep-tree-bar">
|
||||
<Tree
|
||||
:data="dataDep"
|
||||
@on-select-change="selectTree"
|
||||
></Tree>
|
||||
<Spin size="large" fix v-if="depLoading"></Spin>
|
||||
</div>
|
||||
</div>
|
||||
</Poptip>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {initDepartment, searchDepartment} from "@/api/index";
|
||||
import { initDepartment, searchDepartment } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "departmentTreeChoose",
|
||||
props: {
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "点击选择部门"
|
||||
}
|
||||
default: "点击选择部门",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
depLoading: false, // 加载状态
|
||||
departmentTitle: "", // modal标题
|
||||
searchKey: "", // 搜索关键词
|
||||
dataDep: [], // 部门列表
|
||||
selectDep: [], // 已选部门
|
||||
departmentId: [] // 部门id
|
||||
depLoading: false,
|
||||
departmentTitle: "",
|
||||
searchKey: "",
|
||||
dataDep: [],
|
||||
cloneDep: [],
|
||||
departmentId: [],
|
||||
treeProps: {
|
||||
label: "title",
|
||||
children: "children",
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取部门数据
|
||||
initDepartmentData() {
|
||||
initDepartment().then(res => {
|
||||
if (res.success) {
|
||||
this.dataDep = res.result;
|
||||
}
|
||||
});
|
||||
this.depLoading = true;
|
||||
initDepartment()
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.dataDep = res.result;
|
||||
this.cloneDep = JSON.parse(JSON.stringify(this.dataDep));
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.depLoading = false;
|
||||
});
|
||||
},
|
||||
searchDep() {
|
||||
// 搜索部门
|
||||
if (this.searchKey) {
|
||||
this.depLoading = true;
|
||||
searchDepartment({title: this.searchKey}).then(res => {
|
||||
this.depLoading = false;
|
||||
if (res.success) {
|
||||
res.result.forEach(function (e) {
|
||||
if (e.status == -1) {
|
||||
e.title = "[已禁用] " + e.title;
|
||||
e.disabled = true;
|
||||
}
|
||||
});
|
||||
this.dataDep = res.result;
|
||||
}
|
||||
});
|
||||
searchDepartment({ title: this.searchKey })
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
res.result.forEach((e) => {
|
||||
if (e.status == -1) {
|
||||
e.title = "[已禁用] " + e.title;
|
||||
e.disabled = true;
|
||||
}
|
||||
});
|
||||
this.dataDep = res.result;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.depLoading = false;
|
||||
});
|
||||
} else {
|
||||
this.initDepartmentData();
|
||||
this.dataDep = JSON.parse(JSON.stringify(this.cloneDep));
|
||||
}
|
||||
},
|
||||
// 选择回调
|
||||
selectTree(v) {
|
||||
if (v.length === 0) {
|
||||
selectTree(node) {
|
||||
if (!node) {
|
||||
this.$emit("on-change", null);
|
||||
this.departmentId = "";
|
||||
this.departmentTitle = "";
|
||||
return
|
||||
return;
|
||||
}
|
||||
this.departmentId = v[0].id;
|
||||
this.departmentTitle = v[0].title;
|
||||
let department = {
|
||||
this.departmentId = node.id;
|
||||
this.departmentTitle = node.title;
|
||||
this.$emit("on-change", {
|
||||
departmentId: this.departmentId,
|
||||
departmentTitle: this.departmentTitle
|
||||
}
|
||||
this.$emit("on-change", department);
|
||||
departmentTitle: this.departmentTitle,
|
||||
});
|
||||
},
|
||||
// 清除选中方法
|
||||
clearSelect() {
|
||||
this.departmentId = [];
|
||||
this.departmentTitle = "";
|
||||
@@ -118,7 +129,6 @@ export default {
|
||||
}
|
||||
this.$emit("on-clear");
|
||||
},
|
||||
// 设置数据 回显用
|
||||
setData(ids, title) {
|
||||
this.departmentTitle = title;
|
||||
if (this.multiple) {
|
||||
@@ -127,11 +137,11 @@ export default {
|
||||
this.departmentId = [];
|
||||
this.departmentId.push(ids);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initDepartmentData();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -151,9 +161,6 @@ export default {
|
||||
|
||||
.dep-tree-bar::-webkit-scrollbar-thumb {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 0 2px #d1d1d1;
|
||||
background: #e4e4e4;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
<template>
|
||||
<div class="set-password">
|
||||
<Poptip transfer trigger="focus" placement="right" width="250">
|
||||
<Input
|
||||
type="password"
|
||||
password
|
||||
style="width:350px;"
|
||||
:maxlength="maxlength"
|
||||
v-model="currentValue"
|
||||
@on-change="handleChange"
|
||||
:size="size"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
/>
|
||||
<div :class="tipStyle" slot="content">
|
||||
<div class="words">强度 : {{strength}}</div>
|
||||
<Progress
|
||||
:percent="strengthValue"
|
||||
:status="progressStatus"
|
||||
hide-info
|
||||
style="margin: 13px 0;"
|
||||
<el-popover trigger="focus" placement="right" :width="250">
|
||||
<template #reference>
|
||||
<el-input
|
||||
v-model="currentValue"
|
||||
type="password"
|
||||
show-password
|
||||
style="width: 350px"
|
||||
:maxlength="maxlength"
|
||||
:size="size"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
@input="handleChange"
|
||||
/>
|
||||
<br />请至少输入 6 个字符。请不要使
|
||||
<br />用容易被猜到的密码。
|
||||
</template>
|
||||
<div :class="tipStyle">
|
||||
<div class="words">强度 : {{ strength }}</div>
|
||||
<el-progress
|
||||
:percentage="strengthValue"
|
||||
:status="progressStatus"
|
||||
:show-text="false"
|
||||
style="margin: 13px 0"
|
||||
/>
|
||||
<br />请至少输入 6 个字符。请不要使用容易被猜到的密码。
|
||||
</div>
|
||||
</Poptip>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -32,58 +33,56 @@
|
||||
export default {
|
||||
name: "setPassword",
|
||||
props: {
|
||||
modelValue: String,
|
||||
value: String,
|
||||
size: String,
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "请输入密码,长度为6-20个字符"
|
||||
default: "请输入密码,长度为6-20个字符",
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
default: 20
|
||||
}
|
||||
default: 20,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue", "input", "on-change"],
|
||||
data() {
|
||||
return {
|
||||
currentValue: this.value, // 当前密码
|
||||
tipStyle: "password-tip-none", // 提示样式
|
||||
strengthValue: 0, // 密码强度
|
||||
progressStatus: "normal", // 进度条状态
|
||||
strength: "无", // 密码长度
|
||||
grade: 0 // 强度等级
|
||||
currentValue: this.modelValue ?? this.value ?? "",
|
||||
tipStyle: "password-tip-none",
|
||||
strengthValue: 0,
|
||||
progressStatus: "",
|
||||
strength: "无",
|
||||
grade: 0,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
this.setCurrentValue(val);
|
||||
},
|
||||
value(val) {
|
||||
this.setCurrentValue(val);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
checkStrengthValue(v) {
|
||||
// 评级制判断密码强度 最高5
|
||||
let grade = 0;
|
||||
if (/\d/.test(v)) {
|
||||
grade++; //数字
|
||||
}
|
||||
if (/[a-z]/.test(v)) {
|
||||
grade++; //小写
|
||||
}
|
||||
if (/[A-Z]/.test(v)) {
|
||||
grade++; //大写
|
||||
}
|
||||
if (/\W/.test(v)) {
|
||||
grade++; //特殊字符
|
||||
}
|
||||
if (v.length >= 10) {
|
||||
grade++;
|
||||
}
|
||||
if (/\d/.test(v)) grade++;
|
||||
if (/[a-z]/.test(v)) grade++;
|
||||
if (/[A-Z]/.test(v)) grade++;
|
||||
if (/\W/.test(v)) grade++;
|
||||
if (v.length >= 10) grade++;
|
||||
this.grade = grade;
|
||||
return grade;
|
||||
},
|
||||
// 强度验证方法
|
||||
strengthChange() {
|
||||
if (!this.currentValue) {
|
||||
this.tipStyle = "password-tip-none";
|
||||
@@ -91,14 +90,14 @@ export default {
|
||||
this.strengthValue = 0;
|
||||
return;
|
||||
}
|
||||
let grade = this.checkStrengthValue(this.currentValue);
|
||||
const grade = this.checkStrengthValue(this.currentValue);
|
||||
if (grade <= 1) {
|
||||
this.progressStatus = "wrong";
|
||||
this.progressStatus = "exception";
|
||||
this.tipStyle = "password-tip-weak";
|
||||
this.strength = "弱";
|
||||
this.strengthValue = 33;
|
||||
} else if (grade >= 2 && grade <= 4) {
|
||||
this.progressStatus = "normal";
|
||||
this.progressStatus = "";
|
||||
this.tipStyle = "password-tip-middle";
|
||||
this.strength = "中";
|
||||
this.strengthValue = 66;
|
||||
@@ -109,61 +108,33 @@ export default {
|
||||
this.strengthValue = 100;
|
||||
}
|
||||
},
|
||||
// 输入框change事件
|
||||
handleChange(v) {
|
||||
handleChange() {
|
||||
this.strengthChange();
|
||||
this.$emit("update:modelValue", this.currentValue);
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue, this.grade, this.strength);
|
||||
},
|
||||
// 回显当前密码
|
||||
setCurrentValue(value) {
|
||||
if (value === this.currentValue) {
|
||||
return;
|
||||
}
|
||||
this.currentValue = value;
|
||||
if (value === this.currentValue) return;
|
||||
this.currentValue = value ?? "";
|
||||
this.strengthChange();
|
||||
this.$emit("on-change", this.currentValue, this.grade, this.strength);
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.setCurrentValue(val);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.set-password .ivu-poptip,
|
||||
.set-password .ivu-poptip-rel {
|
||||
display: block;
|
||||
}
|
||||
.password-tip-none {
|
||||
padding: 1vh 0;
|
||||
}
|
||||
|
||||
.password-tip-weak {
|
||||
padding: 1vh 0;
|
||||
|
||||
.words {
|
||||
color: #ed3f14;
|
||||
}
|
||||
.password-tip-weak .words {
|
||||
color: #ed3f14;
|
||||
}
|
||||
|
||||
.password-tip-middle {
|
||||
padding: 1vh 0;
|
||||
|
||||
.words {
|
||||
color: #2d8cf0;
|
||||
}
|
||||
.password-tip-middle .words {
|
||||
color: #2d8cf0;
|
||||
}
|
||||
|
||||
.password-tip-strong {
|
||||
padding: 1vh 0;
|
||||
|
||||
.words {
|
||||
color: #52c41a;
|
||||
}
|
||||
.password-tip-strong .words {
|
||||
color: #52c41a;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,173 +1,166 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="display:flex;">
|
||||
<Input
|
||||
<div style="display: flex; gap: 10px; align-items: center; width: 100%">
|
||||
<el-input
|
||||
v-if="showInput"
|
||||
v-model="currentValue"
|
||||
@on-change="handleChange"
|
||||
v-show="showInput"
|
||||
:placeholder="placeholder"
|
||||
:size="size"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:maxlength="maxlength"
|
||||
style="flex: 1"
|
||||
@input="handleChange"
|
||||
>
|
||||
<Poptip slot="append" transfer trigger="hover" title="图片预览" placement="right">
|
||||
<Icon type="md-eye" class="see-icon" />
|
||||
<div slot="content">
|
||||
<img :src="currentValue" alt="该资源不存在" style="width: 100%;margin: 0 auto;display: block;" />
|
||||
<a @click="viewImage=true" style="margin-top:5px;text-align:right;display:block">查看大图</a>
|
||||
</div>
|
||||
</Poptip>
|
||||
</Input>
|
||||
|
||||
<Upload
|
||||
:action="uploadFileUrl"
|
||||
:headers="accessToken"
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleError"
|
||||
:format="['jpg','jpeg','png','gif','bmp']"
|
||||
accept=".jpg, .jpeg, .png, .gif, .bmp"
|
||||
:max-size="1024"
|
||||
:on-format-error="handleFormatError"
|
||||
:on-exceeded-size="handleMaxSize"
|
||||
:before-upload="beforeUpload"
|
||||
:show-upload-list="false"
|
||||
ref="up"
|
||||
class="upload"
|
||||
>
|
||||
<Button :loading="loading" :size="size" :disabled="disabled">上传图片</Button>
|
||||
</Upload>
|
||||
<template #append>
|
||||
<el-popover trigger="hover" placement="right" :width="320" title="图片预览">
|
||||
<template #reference>
|
||||
<el-button class="see-icon">
|
||||
<el-icon><View /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
<img
|
||||
v-if="currentValue"
|
||||
:src="currentValue"
|
||||
alt="该资源不存在"
|
||||
style="max-width: 280px; display: block; margin: 0 auto"
|
||||
/>
|
||||
<el-button
|
||||
v-if="currentValue"
|
||||
type="primary"
|
||||
link
|
||||
style="margin-top: 8px; display: block; text-align: right"
|
||||
@click="viewImage = true"
|
||||
>
|
||||
查看大图
|
||||
</el-button>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button @click="handleCLickImg('storeLogo')">选择图片</el-button>
|
||||
</div>
|
||||
|
||||
<Modal title="图片预览" v-model="viewImage" :styles="{top: '30px'}" draggable>
|
||||
<img :src="currentValue" alt="该资源不存在" style="width: 100%;margin: 0 auto;display: block;" />
|
||||
<div slot="footer">
|
||||
<Button @click="viewImage=false">关闭</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<el-dialog v-model="viewImage" title="图片预览" width="480px" append-to-body :z-index="3500">
|
||||
<img
|
||||
:src="currentValue"
|
||||
alt="该资源不存在"
|
||||
style="max-width: 100%; margin: 0 auto; display: block"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="viewImage = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="picModalFlag" width="1200px" append-to-body :z-index="3500" destroy-on-close>
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
:is-component="true"
|
||||
:initialize="picModalFlag"
|
||||
@callback="callbackSelected"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { View } from "@element-plus/icons-vue";
|
||||
import { uploadFile } from "@/libs/axios";
|
||||
import ossManage from "@/views/shop/ossManages";
|
||||
|
||||
export default {
|
||||
name: "uploadPicInput",
|
||||
props: {
|
||||
value: String,
|
||||
size: String,
|
||||
placeholder: { // input提示信息
|
||||
type: String,
|
||||
default: "图片链接"
|
||||
},
|
||||
showInput: { // 显示图片链接
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
disabled: { // 是否不可选中
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: { // 是否只读
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
maxlength: Number, // 最大长度
|
||||
icon: { // 上传按钮图标
|
||||
type: String,
|
||||
default: "ios-cloud-upload-outline"
|
||||
}
|
||||
components: {
|
||||
ossManage,
|
||||
View,
|
||||
},
|
||||
props: {
|
||||
modelValue: String,
|
||||
value: String,
|
||||
size: {
|
||||
default: "default",
|
||||
type: String,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "图片链接",
|
||||
},
|
||||
showInput: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
maxlength: Number,
|
||||
},
|
||||
emits: ["update:modelValue", "input", "on-change"],
|
||||
data() {
|
||||
return {
|
||||
accessToken: {}, // 验证token
|
||||
currentValue: this.value, // 当前值
|
||||
loading: false, // 加载状态
|
||||
viewImage: false, // 是否预览图片
|
||||
uploadFileUrl: uploadFile // 上传路径
|
||||
accessToken: {},
|
||||
currentValue: this.modelValue ?? this.value ?? "",
|
||||
viewImage: false,
|
||||
uploadFileUrl: uploadFile,
|
||||
picModalFlag: false,
|
||||
selectedFormBtnName: "",
|
||||
picIndex: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
handleCLickImg(val, index) {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModalFlag = true;
|
||||
this.selectedFormBtnName = val;
|
||||
this.picIndex = index;
|
||||
},
|
||||
callbackSelected(val) {
|
||||
this.picModalFlag = false;
|
||||
this.currentValue = val.url;
|
||||
this.picIndex = "";
|
||||
this.emitValue(this.currentValue);
|
||||
},
|
||||
init() {
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken")
|
||||
accessToken: this.getStore("accessToken"),
|
||||
};
|
||||
},
|
||||
// 格式校验
|
||||
handleFormatError(file) {
|
||||
this.loading = false;
|
||||
this.$Notice.warning({
|
||||
title: "不支持的文件格式",
|
||||
desc:
|
||||
"所选文件‘ " +
|
||||
file.name +
|
||||
" ’格式不正确, 请选择 .jpg .jpeg .png .gif .bmp格式文件"
|
||||
});
|
||||
emitValue(val) {
|
||||
this.$emit("update:modelValue", val);
|
||||
this.$emit("input", val);
|
||||
this.$emit("on-change", val);
|
||||
},
|
||||
// 大小校验
|
||||
handleMaxSize(file) {
|
||||
this.loading = false;
|
||||
this.$Notice.warning({
|
||||
title: "文件大小过大",
|
||||
desc: "所选文件大小过大, 不得超过1M."
|
||||
});
|
||||
handleChange() {
|
||||
this.emitValue(this.currentValue);
|
||||
this.$attrs.rollback && this.$attrs.rollback();
|
||||
},
|
||||
// 上传前
|
||||
beforeUpload() {
|
||||
this.loading = true;
|
||||
return true;
|
||||
},
|
||||
// 上传成功
|
||||
handleSuccess(res, file) {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.currentValue = res.result;
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue);
|
||||
} else {
|
||||
this.$Message.error(res.message);
|
||||
}
|
||||
},
|
||||
// 上传失败
|
||||
handleError(error, file, fileList) {
|
||||
this.loading = false;
|
||||
this.$Message.error(error.toString());
|
||||
},
|
||||
// 上传成功回显
|
||||
handleChange(v) {
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue);
|
||||
this.$attrs.rollback && this.$attrs.rollback()
|
||||
},
|
||||
// 初始值
|
||||
setCurrentValue(value) {
|
||||
if (value === this.currentValue) {
|
||||
return;
|
||||
}
|
||||
this.currentValue = value;
|
||||
this.$emit("on-change", this.currentValue);
|
||||
}
|
||||
this.currentValue = value ?? "";
|
||||
this.emitValue(this.currentValue);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
this.setCurrentValue(val);
|
||||
},
|
||||
value(val) {
|
||||
this.setCurrentValue(val);
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.see-icon {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.upload {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -3,144 +3,152 @@
|
||||
<div class="upload-pic-thumb">
|
||||
<vuedraggable
|
||||
:list="uploadList"
|
||||
:disabled="!draggable||!multiple"
|
||||
:disabled="!draggable || !multiple"
|
||||
:animation="200"
|
||||
class="list-group"
|
||||
ghost-class="thumb-ghost"
|
||||
@end="onEnd"
|
||||
>
|
||||
<div class="upload-list" v-for="(item, index) in uploadList" :key="index">
|
||||
<div v-if="item.status == 'finished'">
|
||||
<img :src="item.url" />
|
||||
<div v-for="(item, index) in uploadList" :key="index" class="upload-list">
|
||||
<div v-if="item.status == 'finished'" style="height: 60px">
|
||||
<img :src="item.url" alt="" />
|
||||
<div class="upload-list-cover">
|
||||
<Icon type="ios-eye-outline" @click="handleView(item.url)"></Icon>
|
||||
<Icon v-if="remove" type="ios-trash-outline" @click="handleRemove(item)"></Icon>
|
||||
<el-icon class="action-icon" @click="handleView(item.url)"><View /></el-icon>
|
||||
<el-icon v-if="remove" class="action-icon" @click="handleRemove(item)"><Delete /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
|
||||
<el-progress
|
||||
v-if="item.showProgress"
|
||||
:percentage="item.percentage"
|
||||
:show-text="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
<div style="display: inline-block; width: 60px; height: 60px;border: 1px dashed #dcdee2;border-radius: 4px;line-height: 60px;text-align: center;"
|
||||
@click="handleCLickImg('uploadList')">
|
||||
<Icon size="20" type="md-camera"></Icon>
|
||||
<div
|
||||
v-if="!isView"
|
||||
class="upload-trigger-box"
|
||||
@click="handleCLickImg('uploadList')"
|
||||
>
|
||||
<el-icon :size="20"><Camera /></el-icon>
|
||||
</div>
|
||||
<!--<Upload-->
|
||||
<!--:disabled="disable"-->
|
||||
<!--ref="upload"-->
|
||||
<!--:multiple="multiple"-->
|
||||
<!--:show-upload-list="false"-->
|
||||
<!--:on-success="handleSuccess"-->
|
||||
<!--:on-error="handleError"-->
|
||||
<!--:format="['jpg','jpeg','png','gif']"-->
|
||||
<!--:max-size="1024"-->
|
||||
<!--:on-format-error="handleFormatError"-->
|
||||
<!--:on-exceeded-size="handleMaxSize"-->
|
||||
<!--:before-upload="handleBeforeUpload"-->
|
||||
<!--type="drag"-->
|
||||
<!--:action="uploadFileUrl"-->
|
||||
<!--:headers="accessToken"-->
|
||||
<!--style="display: inline-block;width:58px;"-->
|
||||
<!--v-if="!isView"-->
|
||||
<!-->-->
|
||||
<!--<div style="width: 58px;height:58px;line-height: 58px;">-->
|
||||
<!--<Icon type="md-camera" size="20"></Icon>-->
|
||||
<!--</div>-->
|
||||
<!--</Upload>-->
|
||||
</div>
|
||||
<Modal title="图片预览" v-model="viewImage" :styles="{top: '30px'}" draggable>
|
||||
<img :src="imgUrl" alt="无效的图片链接" style="width: 100%;margin: 0 auto;display: block;" />
|
||||
<div slot="footer">
|
||||
<Button @click="viewImage=false">关闭</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Modal width="1200px" v-model="picModelFlag" @on-ok="confirmUrls">
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" @selected="(list)=>{ selectedImage = list}" ref="ossManage" />
|
||||
</Modal>
|
||||
<el-dialog v-model="viewImage" title="图片预览" width="520px" append-to-body>
|
||||
<img :src="imgUrl" alt="无效的图片链接" style="width: 100%; display: block; margin: 0 auto" />
|
||||
<template #footer>
|
||||
<el-button @click="viewImage = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
@callback="callbackSelected"
|
||||
@selected="(list) => { selectedImage = list }"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="picModelFlag = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmUrls">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Camera, Delete, View } from "@element-plus/icons-vue";
|
||||
import { uploadFile } from "@/libs/axios";
|
||||
import vuedraggable from "vuedraggable";
|
||||
import ossManage from "@/views/shop/ossManages";
|
||||
|
||||
export default {
|
||||
name: "uploadPicThumb",
|
||||
components: {
|
||||
vuedraggable,
|
||||
ossManage
|
||||
ossManage,
|
||||
Camera,
|
||||
Delete,
|
||||
View,
|
||||
},
|
||||
props: {
|
||||
value: { // 默认值
|
||||
type:null
|
||||
},
|
||||
draggable: { // 是否可拖拽改变位置
|
||||
modelValue: { type: null },
|
||||
value: { type: null },
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
multiple: { // 多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
disable:{ // 禁止上传
|
||||
disable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
remove:{ // 移除图片
|
||||
remove: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
limit: { // 上传总数限制
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 10
|
||||
default: 10,
|
||||
},
|
||||
isView: { // 显示上传按钮
|
||||
isView: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue", "input", "on-change", "uploadchange"],
|
||||
data() {
|
||||
return {
|
||||
accessToken: {}, // 验证token
|
||||
uploadFileUrl: uploadFile, // 上传文件
|
||||
uploadList: [], // 上传文件列表
|
||||
viewImage: false, // 是否预览图片
|
||||
imgUrl: "", // 图片地址
|
||||
picModelFlag: false, // 图片选择器
|
||||
selectedFormBtnName: "", // 点击图片绑定form
|
||||
accessToken: {},
|
||||
uploadFileUrl: uploadFile,
|
||||
uploadList: [],
|
||||
viewImage: false,
|
||||
imgUrl: "",
|
||||
picModelFlag: false,
|
||||
selectedFormBtnName: "",
|
||||
selectedImage: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
bindValue() {
|
||||
return this.modelValue !== undefined ? this.modelValue : this.value;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 选择图片modal
|
||||
handleCLickImg(val, index) {
|
||||
handleCLickImg(val) {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
this.selectedFormBtnName = val;
|
||||
},
|
||||
// 图片选择后回调
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
if (!this.multiple && this.uploadList && this.uploadList.length > 0) {
|
||||
// 删除第一张
|
||||
if (!this.multiple && this.uploadList.length > 0) {
|
||||
this.uploadList.splice(0, 1);
|
||||
}
|
||||
this.uploadList.push(val);
|
||||
// 返回组件值
|
||||
this.uploadList.push({ ...val, status: "finished" });
|
||||
this.returnValue();
|
||||
},
|
||||
confirmUrls(){
|
||||
|
||||
confirmUrls() {
|
||||
if (this.selectedImage.length) {
|
||||
this.selectedImage.forEach((element) => {
|
||||
this.uploadList.push({ url: element.url, status: "finished" });
|
||||
});
|
||||
}
|
||||
this.picModelFlag = false;
|
||||
this.returnValue();
|
||||
},
|
||||
onEnd() {
|
||||
this.returnValue();
|
||||
},
|
||||
init() {
|
||||
this.setData(this.value, true);
|
||||
this.setData(this.bindValue, true);
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken")
|
||||
accessToken: this.getStore("accessToken"),
|
||||
};
|
||||
},
|
||||
handleView(imgUrl) {
|
||||
@@ -148,79 +156,28 @@ export default {
|
||||
this.viewImage = true;
|
||||
},
|
||||
handleRemove(file) {
|
||||
const uploadList = this.uploadList;
|
||||
this.uploadList.splice(uploadList.indexOf(file), 1);
|
||||
this.uploadList = this.uploadList.filter((i) => i.url !== file.url);
|
||||
this.returnValue();
|
||||
},
|
||||
handleSuccess(res, file) {
|
||||
if (res.success) {
|
||||
file.url = res.result;
|
||||
// 单张图片处理
|
||||
if (!this.multiple && this.uploadList.length > 0) {
|
||||
// 删除第一张
|
||||
this.uploadList.splice(0, 1);
|
||||
}
|
||||
this.uploadList.push(file);
|
||||
// 返回组件值
|
||||
this.returnValue();
|
||||
} else {
|
||||
this.$Message.error(res.message);
|
||||
}
|
||||
},
|
||||
handleError(error, file, fileList) {
|
||||
this.$Message.error(error.toString());
|
||||
},
|
||||
handleFormatError(file) {
|
||||
this.$Notice.warning({
|
||||
title: "不支持的文件格式",
|
||||
desc:
|
||||
"所选文件‘ " +
|
||||
file.name +
|
||||
" ’格式不正确, 请选择 .jpg .jpeg .png .gif图片格式文件"
|
||||
});
|
||||
},
|
||||
handleMaxSize(file) {
|
||||
this.$Notice.warning({
|
||||
title: "文件大小过大",
|
||||
desc:
|
||||
"所选文件大小过大, 不得超过1M."
|
||||
});
|
||||
},
|
||||
handleBeforeUpload() {
|
||||
if (this.multiple && this.uploadList.length >= this.limit) {
|
||||
this.$Message.warning("最多只能上传" + this.limit + "张图片");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
emitValue(val) {
|
||||
this.$emit("update:modelValue", val);
|
||||
this.$emit("input", val);
|
||||
this.$emit("on-change", val);
|
||||
},
|
||||
returnValue() {
|
||||
if (!this.uploadList || this.uploadList.length < 1) {
|
||||
if (!this.multiple) {
|
||||
this.$emit("input", "");
|
||||
this.$emit("on-change", "");
|
||||
} else {
|
||||
this.$emit("input", []);
|
||||
this.$emit("on-change", []);
|
||||
}
|
||||
const empty = this.multiple ? [] : "";
|
||||
this.emitValue(empty);
|
||||
return;
|
||||
}
|
||||
if (!this.multiple) {
|
||||
// 单张
|
||||
let v = this.uploadList[0].url;
|
||||
this.$emit("input", v);
|
||||
this.$emit("on-change", v);
|
||||
this.emitValue(this.uploadList[0].url);
|
||||
} else {
|
||||
let v = [];
|
||||
this.uploadList.forEach(e => {
|
||||
v.push(e.url);
|
||||
});
|
||||
this.$emit("input", v);
|
||||
this.$emit("on-change", v);
|
||||
this.emitValue(this.uploadList.map((e) => e.url));
|
||||
}
|
||||
},
|
||||
setData(v, init) {
|
||||
if (typeof v == "string") {
|
||||
// 单张
|
||||
if (this.multiple) {
|
||||
this.$Message.warning("多张上传仅支持数组数据类型");
|
||||
return;
|
||||
@@ -228,62 +185,53 @@ export default {
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
this.uploadList = [];
|
||||
let item = {
|
||||
url: v,
|
||||
status: "finished"
|
||||
};
|
||||
this.uploadList.push(item);
|
||||
this.$emit("on-change", v);
|
||||
} else if (typeof v == "object") {
|
||||
// 多张
|
||||
this.uploadList = [{ url: v, status: "finished" }];
|
||||
this.$emit("uploadchange", v);
|
||||
this.emitValue(v);
|
||||
} else if (typeof v == "object" && v) {
|
||||
if (!this.multiple) {
|
||||
this.$Message.warning("单张上传仅支持字符串数据类型");
|
||||
return;
|
||||
}
|
||||
this.uploadList = [];
|
||||
const list = v.length > this.limit ? v.slice(0, this.limit) : v;
|
||||
if (v.length > this.limit) {
|
||||
for (let i = 0; i < this.limit; i++) {
|
||||
let item = {
|
||||
url: v[i],
|
||||
status: "finished"
|
||||
};
|
||||
this.uploadList.push(item);
|
||||
}
|
||||
this.$emit("on-change", v.slice(0, this.limit));
|
||||
if (init) {
|
||||
this.$emit("input", v.slice(0, this.limit));
|
||||
}
|
||||
this.$Message.warning("最多只能上传" + this.limit + "张图片");
|
||||
} else {
|
||||
v.forEach(e => {
|
||||
let item = {
|
||||
url: e,
|
||||
status: "finished"
|
||||
};
|
||||
this.uploadList.push(item);
|
||||
}
|
||||
list.forEach((e) => {
|
||||
this.uploadList.push({
|
||||
status: "finished",
|
||||
...(typeof e === "string" ? { url: e } : e),
|
||||
});
|
||||
this.$emit("on-change", v);
|
||||
});
|
||||
if (init) {
|
||||
this.emitValue(list);
|
||||
} else {
|
||||
this.$emit("on-change", list);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
this.setData(val);
|
||||
},
|
||||
value(val) {
|
||||
this.setData(val);
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-pic-thumb{
|
||||
.upload-pic-thumb {
|
||||
display: flex;
|
||||
}
|
||||
.upload-list {
|
||||
display: inline-flex;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
@@ -300,6 +248,7 @@ export default {
|
||||
.upload-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.upload-list-cover {
|
||||
display: none;
|
||||
@@ -309,15 +258,17 @@ export default {
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.upload-list:hover .upload-list-cover {
|
||||
display: block;
|
||||
display: flex;
|
||||
}
|
||||
.upload-list-cover i {
|
||||
.action-icon {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.list-group {
|
||||
display: inline-block;
|
||||
@@ -326,5 +277,14 @@ export default {
|
||||
opacity: 0.5;
|
||||
background: #c8ebfb;
|
||||
}
|
||||
.upload-trigger-box {
|
||||
display: inline-block;
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
border: 1px dashed #dcdfe6;
|
||||
border-radius: 4px;
|
||||
line-height: 58px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<template>
|
||||
<div class="map">
|
||||
|
||||
<div class="address">{{ addrContent.address }}</div>
|
||||
<div id="map-container"></div>
|
||||
|
||||
<div class="search-con">
|
||||
<Input placeholder="输入关键字搜索" id="input-map" v-model="mapSearch" />
|
||||
<el-input id="input-map" v-model="mapSearch" placeholder="输入关键字搜索" clearable />
|
||||
<ul>
|
||||
<li v-for="(tip, index) in tips" :key="index" @click="selectAddr(tip.location)">
|
||||
<p>{{ tip.name }}</p>
|
||||
@@ -13,42 +12,39 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer" class="footer">
|
||||
|
||||
<Button type="primary" :loading="loading" @click="ok">确定</Button>
|
||||
<div class="footer">
|
||||
<el-button type="primary" :loading="loading" @click="ok">确定</el-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
import { getRegion } from "@/api/common.js";
|
||||
|
||||
const config = require('@/config/index')
|
||||
const config = require("@/config/index");
|
||||
export default {
|
||||
name: "map",
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
showMap: false, // 地图显隐
|
||||
mapSearch: "", // 地图搜索
|
||||
map: null, // 初始化地图
|
||||
autoComplete: null, // 初始化搜索方法
|
||||
geocoder: null, // 初始化地理、坐标转化
|
||||
positionPicker: null, // 地图拖拽选点
|
||||
tips: [], //搜索关键字列表
|
||||
addrContent: {}, // 回显地址信息
|
||||
loading: false, // 加载状态
|
||||
showMap: false,
|
||||
mapSearch: "",
|
||||
map: null,
|
||||
autoComplete: null,
|
||||
geocoder: null,
|
||||
positionPicker: null,
|
||||
tips: [],
|
||||
addrContent: {},
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
mapSearch: function (val) {
|
||||
mapSearch(val) {
|
||||
this.searchOfMap(val);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
ok() {
|
||||
|
||||
if (this.addrContent && this.addrContent.regeocode) {
|
||||
const params = {
|
||||
cityCode: this.addrContent.regeocode.addressComponent.citycode,
|
||||
@@ -59,30 +55,27 @@ export default {
|
||||
this.addrContent.addr = res.result.name.replace(/,/g, " ");
|
||||
this.addrContent.addrId = res.result.id;
|
||||
this.loading = false;
|
||||
|
||||
this.$emit("getAddress", this.addrContent);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$Message.error('未获取到坐标信息!请查看高德API配置是否正确')
|
||||
this.$Message.error("未获取到坐标信息!请查看高德API配置是否正确");
|
||||
}
|
||||
|
||||
},
|
||||
init() {
|
||||
AMapLoader.load({
|
||||
key: this.config.aMapKey, // 申请好的Web端开发者Key,首次调用 load 时必填
|
||||
version: "", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
||||
key: this.config.aMapKey,
|
||||
version: "",
|
||||
plugins: [
|
||||
"AMap.ToolBar",
|
||||
"AMap.Autocomplete",
|
||||
"AMap.PlaceSearch",
|
||||
"AMap.Geolocation",
|
||||
"AMap.Geocoder",
|
||||
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
||||
],
|
||||
AMapUI: {
|
||||
// 是否加载 AMapUI,缺省不加载
|
||||
version: "1.1", // AMapUI 缺省 1.1
|
||||
plugins: ["misc/PositionPicker"], // 需要加载的 AMapUI ui插件
|
||||
version: "1.1",
|
||||
plugins: ["misc/PositionPicker"],
|
||||
},
|
||||
})
|
||||
.then((AMap) => {
|
||||
@@ -95,36 +88,26 @@ export default {
|
||||
that.map.addControl(new AMap.PlaceSearch());
|
||||
that.map.addControl(new AMap.Geocoder());
|
||||
|
||||
// 实例化Autocomplete
|
||||
let autoOptions = {
|
||||
city: "全国",
|
||||
};
|
||||
that.autoComplete = new AMap.Autocomplete(autoOptions); // 搜索
|
||||
that.autoComplete = new AMap.Autocomplete(autoOptions);
|
||||
that.geocoder = new AMap.Geocoder(autoOptions);
|
||||
|
||||
that.positionPicker = new AMapUI.PositionPicker({
|
||||
// 拖拽选点
|
||||
mode: "dragMap",
|
||||
map: that.map,
|
||||
});
|
||||
that.positionPicker.start();
|
||||
/**
|
||||
*
|
||||
* 所有回显数据,都在positionResult里面
|
||||
* 需要字段可以查找
|
||||
*
|
||||
*/
|
||||
that.positionPicker.on("success", function (positionResult) {
|
||||
that.addrContent = positionResult;
|
||||
});
|
||||
})
|
||||
.catch((e) => { });
|
||||
.catch(() => {});
|
||||
},
|
||||
searchOfMap(val) {
|
||||
// 地图搜索
|
||||
let that = this;
|
||||
this.autoComplete.search(val, function (status, result) {
|
||||
// 搜索成功时,result即是对应的匹配数据
|
||||
if (status == "complete" && result.info == "OK") {
|
||||
that.tips = result.tips;
|
||||
} else {
|
||||
@@ -133,7 +116,6 @@ export default {
|
||||
});
|
||||
},
|
||||
selectAddr(location) {
|
||||
// 选择坐标
|
||||
if (!location) {
|
||||
this.$Message.warning("请选择正确点位");
|
||||
return false;
|
||||
@@ -182,7 +164,6 @@ export default {
|
||||
|
||||
.address {
|
||||
margin-bottom: 10px;
|
||||
// color: $theme_color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,50 @@
|
||||
<template>
|
||||
<Modal width="800" footer-hide v-model="enableMap">
|
||||
<RadioGroup @on-change="changeMap" v-model="mapDefault" type="button">
|
||||
<Radio label="select">级联选择</Radio>
|
||||
<Radio label="map" v-if="aMapSwitch">高德地图</Radio>
|
||||
</RadioGroup>
|
||||
<el-dialog v-model="enableMap" width="800px" :show-close="true" destroy-on-close>
|
||||
<el-radio-group v-model="mapDefault" @change="changeMap">
|
||||
<el-radio-button value="select">级联选择</el-radio-button>
|
||||
<el-radio-button v-if="aMapSwitch" value="map">高德地图</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div>
|
||||
<div v-if="mapDefault === 'select'">
|
||||
<div class="selector">
|
||||
<div class="selector-item" v-for="(plant, plantIndex) in Object.keys(data)" :key="plantIndex">
|
||||
<div :class="{ 'active': chiosend[plantIndex].id == item.id }" v-for="(item, index) in data[plant]"
|
||||
<div
|
||||
v-for="(plant, plantIndex) in Object.keys(data)"
|
||||
:key="plantIndex"
|
||||
class="selector-item"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in data[plant]"
|
||||
:key="index"
|
||||
@click="init(item, plantIndex != Object.keys(data).length - 1 ? Object.keys(data)[plantIndex + 1] : 0, plantIndex)"
|
||||
class="map-item">
|
||||
:class="{ active: chiosend[plantIndex]?.id == item.id }"
|
||||
class="map-item"
|
||||
@click="
|
||||
init(
|
||||
item,
|
||||
plantIndex != Object.keys(data).length - 1
|
||||
? Object.keys(data)[plantIndex + 1]
|
||||
: 0,
|
||||
plantIndex
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="footer">
|
||||
<Button type="primary" @click="finished">确定</Button>
|
||||
<el-button type="primary" @click="finished">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<mapping v-if="mapDefault === 'map'" ref="map" @getAddress="getAddress" />
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { aMapSwitch } from '@/config/index'
|
||||
import { aMapSwitch } from "@/config/index";
|
||||
import mapping from "@/views/my-components/map/index.vue";
|
||||
import * as API_Setup from "@/api/common.js";
|
||||
|
||||
export default {
|
||||
components: { mapping },
|
||||
data() {
|
||||
@@ -41,87 +53,76 @@ export default {
|
||||
enableMap: false,
|
||||
mapDefault: "select",
|
||||
data: {
|
||||
province: [], //省
|
||||
city: [], //市
|
||||
area: [], //区
|
||||
street: [], //街道
|
||||
province: [],
|
||||
city: [],
|
||||
area: [],
|
||||
street: [],
|
||||
},
|
||||
chiosend: [],
|
||||
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.chiosend = new Array(4).fill("");
|
||||
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.enableMap = true
|
||||
this.init({ id: 0 }, 'province');
|
||||
this.enableMap = true;
|
||||
this.init({ id: 0 }, "province");
|
||||
},
|
||||
changeMap(val) {
|
||||
this.mapDefault = val
|
||||
|
||||
|
||||
this.mapDefault = val;
|
||||
},
|
||||
init(val, level = 'province', index) {
|
||||
init(val, level = "province", index) {
|
||||
if (level == 0) {
|
||||
// 说明选择到了街道,将街道id存入数组
|
||||
this.chiosend.splice(3, 1, val);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
API_Setup.getChildRegion(val.id).then((res) => {
|
||||
if (res.result.length && val.id !== 0) {
|
||||
this.chiosend[index] = val
|
||||
}
|
||||
else if(!res.result.length){
|
||||
this.chiosend[index] = val
|
||||
this.chiosend[index] = val;
|
||||
} else if (!res.result.length) {
|
||||
this.chiosend[index] = val;
|
||||
}
|
||||
this.data[level] = res.result;
|
||||
if (level == 'city') {
|
||||
this.data.area = []
|
||||
this.data.street = []
|
||||
this.chiosend.splice(1, 3, "","","");
|
||||
if (level == "city") {
|
||||
this.data.area = [];
|
||||
this.data.street = [];
|
||||
this.chiosend.splice(1, 3, "", "", "");
|
||||
}
|
||||
if (level == 'area') {
|
||||
this.data.street = []
|
||||
this.chiosend.splice(2, 2, "","");
|
||||
if (level == "area") {
|
||||
this.data.street = [];
|
||||
this.chiosend.splice(2, 2, "", "");
|
||||
}
|
||||
if (level == 'street') {
|
||||
if (level == "street") {
|
||||
this.chiosend.splice(3, 1, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
getAddress(center) {
|
||||
this.$emit('callback', {
|
||||
this.$emit("callback", {
|
||||
type: this.mapDefault,
|
||||
data: center
|
||||
})
|
||||
data: center,
|
||||
});
|
||||
this.enableMap = false;
|
||||
},
|
||||
// 选择完成
|
||||
finished() {
|
||||
if(!this.chiosend[0]){
|
||||
this.$Message.error("请选择地址")
|
||||
return
|
||||
if (!this.chiosend[0]) {
|
||||
this.$Message.error("请选择地址");
|
||||
return;
|
||||
}
|
||||
const params = this.chiosend.filter((item) => item!=="" && item.value !== "");
|
||||
const params = this.chiosend.filter((item) => item !== "" && item.value !== "");
|
||||
this.enableMap = false;
|
||||
this.$emit('callback', {
|
||||
this.$emit("callback", {
|
||||
type: this.mapDefault,
|
||||
data: params
|
||||
})
|
||||
data: params,
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.selector {
|
||||
|
||||
|
||||
height: 400px;
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
|
||||
@@ -55,4 +55,4 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" src="./Checkbox.less"></style>
|
||||
<style lang="less" scoped src="./Checkbox.less"></style>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<div
|
||||
v-if="columns.length > 0"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:class="[prefixCls, `${prefixCls}-${size}`, tableClass]">
|
||||
<Spin fix v-if="loading"></Spin>
|
||||
<div
|
||||
v-show="showHeader"
|
||||
ref="header-wrapper"
|
||||
@@ -297,6 +297,11 @@ export default {
|
||||
cellStyle: [Object, Function],
|
||||
expandKey: String
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
treeTableRoot: this,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
computedWidth: "",
|
||||
@@ -387,7 +392,7 @@ export default {
|
||||
this.measure();
|
||||
window.addEventListener("resize", this.measure);
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("resize", this.measure);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Checkbox from '../Checkbox/Checkbox'; // eslint-disable-line
|
||||
// import Radio from '../Radio/Radio'; // eslint-disable-line
|
||||
import { mixins } from './utils';
|
||||
import { Radio } from 'view-design'; // eslint-disable-line
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
export default {
|
||||
name: 'TreeTable__body',
|
||||
mixins: [mixins],
|
||||
components: { Radio },
|
||||
inject: {
|
||||
treeTableRoot: { default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
radioSelectedIndex: -1,
|
||||
@@ -15,6 +15,12 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
table() {
|
||||
if (this.treeTableRoot) return this.treeTableRoot;
|
||||
let parent = this.$parent;
|
||||
while (parent) {
|
||||
if (parent.$options && parent.$options.name === 'TreeTable') return parent;
|
||||
parent = parent.$parent;
|
||||
}
|
||||
return this.$parent;
|
||||
},
|
||||
},
|
||||
@@ -110,15 +116,6 @@ export default {
|
||||
},
|
||||
},
|
||||
render() {
|
||||
// key
|
||||
// function getKey(row, rowIndex) {
|
||||
// const rowKey = this.table.rowKey;
|
||||
// if (rowKey) {
|
||||
// return rowKey.call(null, row, rowIndex);
|
||||
// }
|
||||
// return rowIndex;
|
||||
// }
|
||||
|
||||
// style
|
||||
function getStyle(type, row, rowIndex, column, columnIndex) {
|
||||
const certainType = this.validateType(type, ['cell', 'row'], 'getStyle');
|
||||
@@ -185,8 +182,21 @@ export default {
|
||||
return classList.join(' ');
|
||||
}
|
||||
|
||||
// Vue 3:scoped slot 合并到 $slots
|
||||
function renderTemplateSlot(table, slotName, scope) {
|
||||
if (!table || !slotName) return '';
|
||||
const slots = table.$slots || {};
|
||||
let slot = slots[slotName];
|
||||
if (!slot && table.$scopedSlots && table.$scopedSlots[slotName]) {
|
||||
slot = table.$scopedSlots[slotName];
|
||||
}
|
||||
if (!slot) return '';
|
||||
return slot(scope);
|
||||
}
|
||||
|
||||
// 根据type渲染单元格Cell
|
||||
function renderCell(row, rowIndex, column, columnIndex) {
|
||||
if (!row || !column) return '';
|
||||
// ExpandType
|
||||
if (this.isExpandCell(this.table, columnIndex)) {
|
||||
return <i class='zk-icon zk-icon-angle-right'></i>;
|
||||
@@ -219,13 +229,16 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
// res = <Checkbox
|
||||
// indeterminate={indeterminate}
|
||||
// value={allCheck}
|
||||
// onOn-change={isChecked => this.handleEvent(null, 'checkbox', { row, rowIndex, column, columnIndex }, { isChecked })}>
|
||||
// </Checkbox>;
|
||||
} else {
|
||||
res = <Radio value={this.radioSelectedIndex === rowIndex} on-on-change={() => this.handleEvent(null, 'radio', { row, rowIndex, column, columnIndex })}></Radio>;
|
||||
res = (
|
||||
<input
|
||||
type="radio"
|
||||
checked={this.radioSelectedIndex === rowIndex}
|
||||
onChange={() =>
|
||||
this.handleEvent(null, 'radio', { row, rowIndex, column, columnIndex })
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -253,9 +266,12 @@ export default {
|
||||
if (column.type === undefined || column.type === 'custom') {
|
||||
return row[column.key];
|
||||
} else if (column.type === 'template') {
|
||||
return this.table.$scopedSlots[column.template]
|
||||
? this.table.$scopedSlots[column.template]({ row, rowIndex, column, columnIndex })
|
||||
: '';
|
||||
return renderTemplateSlot.call(this, this.table, column.template, {
|
||||
row,
|
||||
rowIndex,
|
||||
column,
|
||||
columnIndex,
|
||||
});
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -263,11 +279,6 @@ export default {
|
||||
// Template
|
||||
return (
|
||||
<table cellspacing="0" cellpadding="0" border="0" class={`${this.prefixCls}__body`}>
|
||||
{/* <colgroup>
|
||||
{this.table.tableColumns.map(column =>
|
||||
<col width={column.computedWidth || column.minWidth || column.width}></col>)
|
||||
}
|
||||
</colgroup> */}
|
||||
<tbody>
|
||||
{ this.table.bodyData.length > 0
|
||||
? this.table.bodyData.map((row, rowIndex) =>
|
||||
@@ -304,10 +315,7 @@ export default {
|
||||
<td
|
||||
class={`${this.prefixCls}--expand-content`}
|
||||
colspan={this.table.tableColumns.length}>
|
||||
{this.table.$scopedSlots.expand
|
||||
? this.table.$scopedSlots.expand({ row, rowIndex })
|
||||
: ''
|
||||
}
|
||||
{renderTemplateSlot.call(this, this.table, 'expand', { row, rowIndex })}
|
||||
</td>
|
||||
</tr>,
|
||||
])
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
let scrollBarWidth;
|
||||
|
||||
export default function () {
|
||||
if (Vue.prototype.$isServer) return 0;
|
||||
export default function getScrollBarWidth() {
|
||||
if (typeof document === "undefined") return 0;
|
||||
if (scrollBarWidth !== undefined) return scrollBarWidth;
|
||||
|
||||
const outer = document.createElement('div');
|
||||
outer.style.visibility = 'hidden';
|
||||
outer.style.width = '100px';
|
||||
outer.style.position = 'absolute';
|
||||
outer.style.top = '-9999px';
|
||||
const outer = document.createElement("div");
|
||||
outer.style.visibility = "hidden";
|
||||
outer.style.width = "100px";
|
||||
outer.style.position = "absolute";
|
||||
outer.style.top = "-9999px";
|
||||
document.body.appendChild(outer);
|
||||
|
||||
const widthNoScroll = outer.offsetWidth;
|
||||
outer.style.overflow = 'scroll';
|
||||
outer.style.overflow = "scroll";
|
||||
|
||||
const inner = document.createElement('div');
|
||||
inner.style.width = '100%';
|
||||
const inner = document.createElement("div");
|
||||
inner.style.width = "100%";
|
||||
outer.appendChild(inner);
|
||||
|
||||
const widthWithScroll = inner.offsetWidth;
|
||||
|
||||
@@ -1,59 +1,81 @@
|
||||
<template>
|
||||
<div class="verify-content" v-if="show" @mousemove="mouseMove" @mouseup="mouseUp" @click.stop>
|
||||
<div class="imgBox" :style="{width:data.originalWidth+'px',height:data.originalHeight + 'px'}">
|
||||
<img :src="data.backImage" style="width:100%;height:100%" alt="">
|
||||
<img class="slider" :src="data.slidingImage" :style="{left:distance+'px',top:data.randomY+'px'}" :width="data.sliderWidth" :height="data.sliderHeight" alt="">
|
||||
<Icon type="md-refresh" class="refresh" @click="init" />
|
||||
<div
|
||||
class="verify-content"
|
||||
v-if="show"
|
||||
@mousemove="mouseMove"
|
||||
@mouseup="mouseUp"
|
||||
@click.stop
|
||||
>
|
||||
<div
|
||||
class="imgBox"
|
||||
:style="{
|
||||
width: data.originalWidth + 'px',
|
||||
height: data.originalHeight + 'px',
|
||||
}"
|
||||
>
|
||||
<img :src="data.backImage" style="width: 100%; height: 100%" alt="" />
|
||||
<img
|
||||
class="slider"
|
||||
:src="data.slidingImage"
|
||||
:style="{ left: distance + 'px', top: data.randomY + 'px' }"
|
||||
:width="data.sliderWidth"
|
||||
:height="data.sliderHeight"
|
||||
alt=""
|
||||
/>
|
||||
<el-icon class="refresh" @click="init"><Refresh /></el-icon>
|
||||
</div>
|
||||
<div class="handle" :style="{width:data.originalWidth+'px'}">
|
||||
<span class="bgcolor" :style="{width:distance + 'px',background:bgColor}"></span>
|
||||
<span class="swiper" :style="{left:distance + 'px'}" @mousedown="mouseDown">
|
||||
<Icon type="md-arrow-round-forward" />
|
||||
<div class="handle" :style="{ width: data.originalWidth + 'px' }">
|
||||
<span
|
||||
class="bgcolor"
|
||||
:style="{ width: distance + 'px', background: bgColor }"
|
||||
></span>
|
||||
<span class="swiper" :style="{ left: distance + 'px' }" @mousedown="mouseDown">
|
||||
<el-icon><DArrowRight /></el-icon>
|
||||
</span>
|
||||
<span class="text">{{verifyText}}</span>
|
||||
<span class="text">{{ verifyText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getVerifyImg, postVerifyImg } from './verify.js';
|
||||
import { Refresh, DArrowRight } from "@element-plus/icons-vue";
|
||||
import { getVerifyImg, postVerifyImg } from "./verify.js";
|
||||
|
||||
export default {
|
||||
components: { Refresh, DArrowRight },
|
||||
props: {
|
||||
// 传入数据,判断是登录、注册、修改密码
|
||||
verifyType: {
|
||||
defalut: 'LOGIN',
|
||||
type: String
|
||||
}
|
||||
default: "LOGIN",
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
show: false, // 验证码显隐
|
||||
type: 'LOGIN', // 请求类型
|
||||
data: { // 验证码数据
|
||||
backImage: '',
|
||||
slidingImage: '',
|
||||
show: false,
|
||||
type: "LOGIN",
|
||||
data: {
|
||||
backImage: "",
|
||||
slidingImage: "",
|
||||
originalHeight: 150,
|
||||
originalWidth: 300,
|
||||
sliderWidth: 60,
|
||||
sliderHeight: 60
|
||||
sliderHeight: 60,
|
||||
},
|
||||
distance: 0, // 拼图移动距离
|
||||
flag: false, // 判断滑块是否按下
|
||||
downX: 0, // 鼠标按下位置
|
||||
bgColor: '#04ad11', // 滑动背景颜色
|
||||
verifyText: '拖动滑块解锁' // 文字提示
|
||||
distance: 0,
|
||||
flag: false,
|
||||
downX: 0,
|
||||
bgColor: "#04ad11",
|
||||
verifyText: "拖动滑块解锁",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 鼠标按下事件,开始拖动滑块
|
||||
mouseDown (e) {
|
||||
mouseDown(e) {
|
||||
this.downX = e.clientX;
|
||||
this.flag = true;
|
||||
},
|
||||
// 鼠标移动事件,计算距离
|
||||
mouseMove (e) {
|
||||
mouseMove(e) {
|
||||
if (this.flag) {
|
||||
let offset = e.clientX - this.downX;
|
||||
|
||||
const offset = e.clientX - this.downX;
|
||||
if (offset > this.data.originalWidth - 43) {
|
||||
this.distance = this.data.originalWidth - 43;
|
||||
} else if (offset < 0) {
|
||||
@@ -63,65 +85,63 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
// 鼠标抬起事件,验证是否正确
|
||||
mouseUp () {
|
||||
mouseUp() {
|
||||
if (!this.flag) return false;
|
||||
this.flag = false;
|
||||
let params = {
|
||||
const params = {
|
||||
verificationEnums: this.type,
|
||||
xPos: this.distance
|
||||
xPos: this.distance,
|
||||
};
|
||||
postVerifyImg(params).then(res => {
|
||||
if (res.success) {
|
||||
if (res.result) {
|
||||
this.bgColor = 'green';
|
||||
this.verifyText = '解锁成功';
|
||||
this.$emit('change', { status: true, distance: this.distance });
|
||||
postVerifyImg(params)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
if (res.result) {
|
||||
this.bgColor = "green";
|
||||
this.verifyText = "解锁成功";
|
||||
this.$emit("change", { status: true, distance: this.distance });
|
||||
} else {
|
||||
this.bgColor = "red";
|
||||
this.verifyText = "解锁失败";
|
||||
setTimeout(() => this.init(), 1000);
|
||||
this.$emit("change", { status: false, distance: this.distance });
|
||||
}
|
||||
} else {
|
||||
this.bgColor = 'red';
|
||||
this.verifyText = '解锁失败';
|
||||
let that = this;
|
||||
setTimeout(() => {
|
||||
that.init();
|
||||
}, 1000);
|
||||
this.$emit('change', { status: false, distance: this.distance });
|
||||
this.init();
|
||||
}
|
||||
} else {
|
||||
this.init()
|
||||
}
|
||||
|
||||
}).catch(()=>{
|
||||
this.init()
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
init () { // 初始化数据
|
||||
init() {
|
||||
this.flag = false;
|
||||
this.downX = 0;
|
||||
this.distance = 0;
|
||||
this.bgColor = '#04ad11';
|
||||
this.verifyText = '拖动滑块解锁';
|
||||
getVerifyImg(this.type).then(res => {
|
||||
this.bgColor = "#04ad11";
|
||||
this.verifyText = "拖动滑块解锁";
|
||||
getVerifyImg(this.type).then((res) => {
|
||||
if (res.result) {
|
||||
this.data = res.result;
|
||||
this.show = true;
|
||||
} else {
|
||||
this.$Message.warning('请求失败请重试!')
|
||||
this.$Message.warning("请求失败请重试!");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
verifyType: {
|
||||
immediate: true,
|
||||
handler: function (v) {
|
||||
handler(v) {
|
||||
this.type = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.verify-content{
|
||||
.verify-content {
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #eee;
|
||||
@@ -174,9 +194,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.ivu-icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.text {
|
||||
|
||||
@@ -1,258 +1,212 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.memberName"
|
||||
clearable
|
||||
placeholder="请输入会员名称"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="订单号" prop="orderSn">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.orderSn"
|
||||
clearable
|
||||
placeholder="请输入订单号"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="状态" prop="status">
|
||||
<Select v-model="searchForm.status" placeholder="请选择订单状态" clearable style="width: 240px">
|
||||
<Option value="NEW">新投诉</Option>
|
||||
<Option value="CANCEL">已撤销</Option>
|
||||
<Option value="WAIT_APPEAL">待申诉</Option>
|
||||
<Option value="COMMUNICATION">对话中</Option>
|
||||
<Option value="WAIT_ARBITRATION">等待仲裁</Option>
|
||||
<Option value="COMPLETE">已完成</Option>
|
||||
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
ref="table"
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<template slot-scope="{row}" slot="goodsName">
|
||||
<a class="mr_10" @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
|
||||
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
|
||||
<div slot="content">
|
||||
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
|
||||
</div>
|
||||
<img src="../../../assets/qrcode.svg" style="vertical-align:bottom;" class="hover-pointer" width="20" height="20" alt="">
|
||||
</Poptip>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-form-item label="订单编号" prop="orderSn">
|
||||
<el-input
|
||||
v-model="searchForm.orderSn"
|
||||
placeholder="请输入订单编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="新投诉" value="NEW" />
|
||||
<el-option label="已撤销" value="CANCEL" />
|
||||
<el-option label="待申诉" value="WAIT_APPEAL" />
|
||||
<el-option label="对话中" value="COMMUNICATION" />
|
||||
<el-option label="等待仲裁" value="WAIT_ARBITRATION" />
|
||||
<el-option label="已完成" value="COMPLETE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table v-loading="loading" border :data="data" ref="table" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="memberName" label="会员名称" width="200" />
|
||||
<el-table-column prop="orderSn" label="订单编号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="商品名称" min-width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text mr_10" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../../assets/qrcode.svg"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="qrcode"
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="complainTopic" label="投诉主题" width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="投诉时间" width="180" />
|
||||
<el-table-column label="投诉状态" width="110">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="complainStatusTagType(row.complainStatus)">
|
||||
{{ complainStatusText(row.complainStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a v-if="row" class="link-text" @click="detail(row)">
|
||||
{{ row.complainStatus === "COMPLETE" ? "详情" : "处理" }}
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Member from "@/api/member";
|
||||
import * as API_Order from "@/api/order";
|
||||
import uploadPicThumb from "@/views/my-components/lili/upload-pic-thumb";
|
||||
import * as API_Order from "@/api/order";
|
||||
import vueQr from "vue-qr";
|
||||
|
||||
export default {
|
||||
name: "orderComplaint",
|
||||
components: {
|
||||
uploadPicThumb
|
||||
export default {
|
||||
name: "orderComplaint",
|
||||
components: { vueQr },
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getDataList();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
},
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "订单编号",
|
||||
key: "orderSn",
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
slot: "goodsName",
|
||||
},
|
||||
{
|
||||
title: "投诉主题",
|
||||
key: "complainTopic",
|
||||
},
|
||||
{
|
||||
title: "投诉时间",
|
||||
key: "createTime",
|
||||
},
|
||||
{
|
||||
title: "投诉状态",
|
||||
key: "complainStatus",
|
||||
render: (h, params) => {
|
||||
if (params.row.complainStatus == "NEW") {
|
||||
return h('div', [h('tag',{props: {color: "purple"}}, '新投诉'),]);
|
||||
} else if (params.row.complainStatus == "CANCEL") {
|
||||
return h('div', [h('tag', {props: {color: "cyan"}}, '已撤销'),]);
|
||||
} else if (params.row.complainStatus == "WAIT_APPEAL") {
|
||||
return h('div', [h('tag', {props: {color: "volcano"}}, '待申诉'),]);
|
||||
} else if (params.row.complainStatus == "COMMUNICATION") {
|
||||
return h('div', [h('tag', {props: {color: "orange"}}, '对话中'),]);
|
||||
}else if (params.row.complainStatus == "WAIT_ARBITRATION") {
|
||||
return h('div', [h('tag', {props: {color: "blue"}}, '等待仲裁'),]);
|
||||
}else if (params.row.complainStatus == "COMPLETE") {
|
||||
return h('div', [h('tag', {props: {color: "green"}}, '已完成'),]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: 'right',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
if (params.row.complainStatus === "COMPLETE") {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"详情"
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"处理"
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
],
|
||||
data: [], // 表格数据
|
||||
total: 0, // 表单数据总数
|
||||
},
|
||||
methods: {
|
||||
complainStatusText(v) {
|
||||
const map = {
|
||||
NEW: "新投诉",
|
||||
CANCEL: "已撤销",
|
||||
WAIT_APPEAL: "待申诉",
|
||||
COMMUNICATION: "对话中",
|
||||
WAIT_ARBITRATION: "等待仲裁",
|
||||
COMPLETE: "已完成",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {}
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getComplainPage(this.searchForm).then((res) => {
|
||||
complainStatusTagType(v) {
|
||||
const map = {
|
||||
NEW: "primary",
|
||||
CANCEL: "info",
|
||||
WAIT_APPEAL: "warning",
|
||||
COMMUNICATION: "warning",
|
||||
WAIT_ARBITRATION: "",
|
||||
COMPLETE: "success",
|
||||
};
|
||||
return map[v] || "info";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getOrderComplain(this.searchForm)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
//投诉详情
|
||||
detail(v) {
|
||||
let id = v.id;
|
||||
this.$options.filters.customRouterPush({
|
||||
name: "order-complaint-detail",
|
||||
query: { id: id },
|
||||
})
|
||||
},
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
detail(v) {
|
||||
this.$filters.customRouterPush({
|
||||
name: "order-complaint-detail",
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false
|
||||
next()
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.mr_10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.hover-pointer {
|
||||
cursor: pointer;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<div class="main-content">
|
||||
<div class="search" v-loading="loading">
|
||||
<el-card>
|
||||
<div class="main-content" v-if="complaintInfo.id">
|
||||
<div class="div-flow-left">
|
||||
<div class="div-form-default">
|
||||
<h3>投诉信息</h3>
|
||||
@@ -9,20 +9,15 @@
|
||||
<dt>投诉商品</dt>
|
||||
<dd>
|
||||
<div>
|
||||
<img :src="complaintInfo.goodsImage" style="height: 60px">
|
||||
<img :src="complaintInfo.goodsImage" style="height: 60px" alt="" />
|
||||
</div>
|
||||
<a>{{ complaintInfo.goodsName }}</a><br>
|
||||
<span>¥{{ complaintInfo.goodsPrice | unitPrice }} * {{ complaintInfo.num }}(数量)</span>
|
||||
<a class="link-text">{{ complaintInfo.goodsName }}</a><br />
|
||||
<span>{{ complaintInfo.num }}(数量)</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>投诉状态</dt>
|
||||
<dd v-if="complaintInfo.complainStatus =='NEW'">新投诉</dd>
|
||||
<dd v-if="complaintInfo.complainStatus =='CANCEL'">已撤销</dd>
|
||||
<dd v-if="complaintInfo.complainStatus =='WAIT_APPEAL'">待申诉</dd>
|
||||
<dd v-if="complaintInfo.complainStatus =='COMMUNICATION'">对话中</dd>
|
||||
<dd v-if="complaintInfo.complainStatus =='WAIT_ARBITRATION'">等待仲裁</dd>
|
||||
<dd v-if="complaintInfo.complainStatus =='COMPLETE'">已完成</dd>
|
||||
<dd>{{ complainStatusText(complaintInfo.complainStatus) }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>投诉时间</dt>
|
||||
@@ -38,17 +33,16 @@
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>投诉凭证</dt>
|
||||
<dd v-if="images === ''">
|
||||
暂无投诉凭证
|
||||
</dd>
|
||||
<dd v-if="!images.length">暂无投诉凭证</dd>
|
||||
<dd v-else>
|
||||
<div class="div-img" v-for="(item, index) in images" :key="index">
|
||||
<img class="complain-img" :src=item>
|
||||
<img class="complain-img" :src="item" alt="" />
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="div-form-default" v-if="complaintInfo.complainStatus !== 'WAIT_APPEAL'">
|
||||
|
||||
<div class="div-form-default" v-if="complaintInfo.appealContent">
|
||||
<h3>商家申诉信息</h3>
|
||||
<dl>
|
||||
<dt>申诉时间</dt>
|
||||
@@ -60,368 +54,288 @@
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>申诉凭证</dt>
|
||||
<dd v-if="appealImages == ''">
|
||||
暂无申诉凭证
|
||||
</dd>
|
||||
<dd v-if="!appealImages.length">暂无申诉凭证</dd>
|
||||
<dd v-else>
|
||||
<div class="div-img" v-for="(item, index) in appealImages" :key="index">
|
||||
<img class="complain-img" :src=item>
|
||||
<img class="complain-img" :src="item" alt="" />
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="div-form-default" v-if="complaintInfo.complainStatus === 'WAIT_APPEAL'">
|
||||
<h3>商家申诉</h3>
|
||||
<dl>
|
||||
<dt>申诉内容</dt>
|
||||
<dd>
|
||||
<Input v-model="appeal.appealContent" type="textarea" maxlength="200" :rows="4" clearable style="width:260px" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>申诉凭证</dt>
|
||||
<dd>
|
||||
<div class="complain-upload-list" :key="index" v-for="(item,index) in appeal.appealImages">
|
||||
<template v-if="item.status === 'finished'">
|
||||
<img class="complain-img" :src="item.url">
|
||||
<div class="complain-upload-list-cover">
|
||||
<Icon type="ios-eye-outline" @click.native="handleView(item.url)"></Icon>
|
||||
<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
|
||||
</template>
|
||||
</div>
|
||||
<Upload ref="upload" :show-upload-list="false" :on-format-error="handleFormatError" :action="uploadFileUrl" :headers="accessToken" :on-success="handleSuccessGoodsPicture"
|
||||
:format="['jpg','jpeg','png']" :max-size="1024" :on-exceeded-size="handleMaxSize" :before-upload="handleBeforeUpload" multiple type="drag"
|
||||
style="display: inline-block;width:58px;">
|
||||
<div style="width: 58px;height:58px;line-height: 58px;">
|
||||
<Icon type="ios-camera" size="20"></Icon>
|
||||
</div>
|
||||
</Upload>
|
||||
<Modal title="View Image" v-model="visible">
|
||||
<img :src="imgName" v-if="visible" style="width: 100%">
|
||||
</Modal>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<Button type="primary" :loading="submitLoading" @click="appealSubmit()" style="margin-left: 5px">
|
||||
提交申诉
|
||||
</Button>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="div-form-default">
|
||||
<h3>对话详情</h3>
|
||||
<dl>
|
||||
<dt>对话记录</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
<p v-for="(item, index) in complaintInfo.orderComplaintCommunications" :key="index">
|
||||
<span v-if="item.owner === 'STORE'">商家[{{ item.createTime }}]</span>
|
||||
<span v-if="item.owner === 'BUYER'">买家[{{ item.createTime }}]</span>
|
||||
<span v-if="item.owner === 'PLATFORM'">平台[{{ item.createTime }}]</span>
|
||||
<p
|
||||
v-for="(item, index) in complaintInfo.orderComplaintCommunications || []"
|
||||
:key="index"
|
||||
>
|
||||
<span v-if="item.owner == 'STORE'">商家[{{ item.createTime }}]</span>
|
||||
<span v-else-if="item.owner == 'BUYER'">买家[{{ item.createTime }}]</span>
|
||||
<span v-else-if="item.owner == 'PLATFORM'">平台[{{ item.createTime }}]</span>
|
||||
{{ item.content }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="complaintInfo.complainStatus!='COMPLETE'">
|
||||
<dl v-if="complaintInfo.complainStatus != 'COMPLETE'">
|
||||
<dt>发送对话</dt>
|
||||
<dd>
|
||||
<Input v-model="params.content" type="textarea" maxlength="200" :rows="4" clearable style="width:260px" />
|
||||
<el-input
|
||||
v-model="params.content"
|
||||
type="textarea"
|
||||
maxlength="200"
|
||||
:rows="4"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="complaintInfo.complainStatus != 'COMPLETE'">
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<div style="text-align: right; width: 45%; margin-top: 10px">
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
|
||||
回复
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="returnDataList" style="margin-left: 5px">
|
||||
返回列表
|
||||
</el-button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="div-form-default" v-if="complaintInfo.complainStatus == 'COMPLETE'">
|
||||
<h3>仲裁结果</h3>
|
||||
<dl>
|
||||
<dt>仲裁意见</dt>
|
||||
<dd>{{ complaintInfo.arbitrationResult }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="div-form-default" v-if="complaintInfo.complainStatus != 'COMPLETE'">
|
||||
<h3>平台仲裁</h3>
|
||||
<dl v-if="arbitrationResultShow">
|
||||
<dt>仲裁</dt>
|
||||
<dd>
|
||||
<el-input
|
||||
v-model="arbitrationParams.arbitrationResult"
|
||||
type="textarea"
|
||||
maxlength="200"
|
||||
:rows="4"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt></dt>
|
||||
<dd v-if="complaintInfo.complainStatus != 'COMPLETE'">
|
||||
<div style="text-align: right;width: 45%;margin-top: 10px">
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit" style="margin-left: 5px">
|
||||
回复
|
||||
</Button>
|
||||
<Button type="default" :loading="submitLoading" @click="returnDataList" style="margin-left: 5px">
|
||||
返回列表
|
||||
</Button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="div-form-default" v-if="complaintInfo.complainStatus === 'COMPLETE'">
|
||||
<h3>仲裁结果</h3>
|
||||
<dl>
|
||||
<dt>仲裁意见</dt>
|
||||
<dd>
|
||||
{{ complaintInfo.arbitrationResult }}
|
||||
<dd style="text-align: right; display: flex; justify-content: space-between">
|
||||
<el-button
|
||||
v-if="!arbitrationResultShow"
|
||||
:loading="submitLoading"
|
||||
@click="arbitrationHandle"
|
||||
>
|
||||
直接仲裁结束投诉流程
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="complaintInfo.complainStatus == 'NEW'"
|
||||
:loading="submitLoading"
|
||||
@click="handleStoreComplaint"
|
||||
>
|
||||
交由商家申诉
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="arbitrationResultShow"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="arbitrationHandleSubmit"
|
||||
>
|
||||
提交仲裁
|
||||
</el-button>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-flow-center">
|
||||
|
||||
</div>
|
||||
<div class="div-flow-center"></div>
|
||||
|
||||
<div class="div-flow-right">
|
||||
<div class="div-form-default">
|
||||
<h3>订单相关信息</h3>
|
||||
<dl>
|
||||
<dt>
|
||||
订单编号
|
||||
</dt>
|
||||
<dd>
|
||||
{{ complaintInfo.orderSn }}
|
||||
</dd>
|
||||
<dt>订单编号</dt>
|
||||
<dd>{{ complaintInfo.orderSn }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
下单时间
|
||||
</dt>
|
||||
<dd>
|
||||
{{ complaintInfo.orderTime }}
|
||||
</dd>
|
||||
<dt>下单时间</dt>
|
||||
<dd>{{ complaintInfo.createTime }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
订单金额
|
||||
</dt>
|
||||
<dt>订单金额</dt>
|
||||
<dd>
|
||||
<priceColorScheme :value="complaintInfo.orderPrice" :color="$mainColor"></priceColorScheme>
|
||||
<span class="price-text">{{ $filters.unitPrice(complaintInfo.orderPrice, "¥") }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
<div class="div-form-default">
|
||||
<h3>收件人信息</h3>
|
||||
<dl>
|
||||
<dt>
|
||||
收货人
|
||||
</dt>
|
||||
<dd>
|
||||
{{ complaintInfo.consigneeName }}
|
||||
</dd>
|
||||
<dt>收货人</dt>
|
||||
<dd>{{ complaintInfo.consigneeName }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
收货地址
|
||||
</dt>
|
||||
<dd>
|
||||
{{ complaintInfo.consigneeAddressPath }}
|
||||
</dd>
|
||||
<dt>收货地址</dt>
|
||||
<dd>{{ complaintInfo.consigneeAddressPath }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
收货人手机
|
||||
</dt>
|
||||
<dd>
|
||||
{{ complaintInfo.consigneeMobile }}
|
||||
</dd>
|
||||
<dt>收货人手机</dt>
|
||||
<dd>{{ complaintInfo.consigneeMobile }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Order from "@/api/order";
|
||||
import { uploadFile } from "@/libs/axios";
|
||||
const emptyComplaint = () => ({
|
||||
id: "",
|
||||
orderComplaintCommunications: [],
|
||||
});
|
||||
|
||||
export default {
|
||||
name: "orderComplaint",
|
||||
name: "orderComplaintDetail",
|
||||
data() {
|
||||
return {
|
||||
//展示图片层
|
||||
visible: false,
|
||||
//上传图片路径
|
||||
uploadFileUrl: uploadFile,
|
||||
accessToken: "", // 验证token
|
||||
id: 0, // 投诉单id
|
||||
complaintInfo: "", // 投诉信息
|
||||
images: [], //会员申诉图片
|
||||
appealImages: [], //商家申诉的图片
|
||||
applyAppealImages: [], //商家申诉表单填写的图片
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
//商家回复内容
|
||||
loading: false,
|
||||
id: "",
|
||||
complaintInfo: emptyComplaint(),
|
||||
images: [],
|
||||
appealImages: [],
|
||||
submitLoading: false,
|
||||
params: {
|
||||
content: "",
|
||||
complainId: "",
|
||||
},
|
||||
//投诉
|
||||
appeal: {
|
||||
orderComplaintId: "",
|
||||
appealContent: "",
|
||||
appealImages: [],
|
||||
arbitrationParams: {
|
||||
arbitrationResult: "",
|
||||
},
|
||||
arbitrationResultShow: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getDetail();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 预览图片
|
||||
handleView(name) {
|
||||
this.imgName = name;
|
||||
this.visible = true;
|
||||
complainStatusText(v) {
|
||||
const map = {
|
||||
NEW: "新投诉",
|
||||
CANCEL: "已撤销",
|
||||
WAIT_APPEAL: "待申诉",
|
||||
COMMUNICATION: "对话中",
|
||||
WAIT_ARBITRATION: "等待仲裁",
|
||||
COMPLETE: "已完成",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
// 移除回复图片
|
||||
handleRemove(file) {
|
||||
this.appeal.appealImages = this.appeal.appealImages.filter(
|
||||
(i) => i.url !== file.url
|
||||
);
|
||||
},
|
||||
// 上传成功回调
|
||||
handleSuccessGoodsPicture(res, file) {
|
||||
if (file.response) {
|
||||
file.url = file.response.result;
|
||||
|
||||
this.appeal.appealImages.push(file);
|
||||
}
|
||||
},
|
||||
// 上传之前钩子
|
||||
handleBeforeUpload() {
|
||||
const check =
|
||||
this.images.images !== undefined && this.images.images.length > 5;
|
||||
if (check) {
|
||||
this.$Notice.warning({
|
||||
title: "Up to five pictures can be uploaded.",
|
||||
});
|
||||
}
|
||||
return !check;
|
||||
},
|
||||
// 上传格式错误
|
||||
handleFormatError(file) {
|
||||
this.$Notice.warning({
|
||||
title: "图片格式不正确",
|
||||
desc:
|
||||
"File format of " +
|
||||
file.name +
|
||||
" is incorrect, please select jpg or png.",
|
||||
});
|
||||
},
|
||||
// 上传大小限制
|
||||
handleMaxSize(file) {
|
||||
this.$Notice.warning({
|
||||
title: "超过文件大小限制",
|
||||
desc: "图片不能超过1mb",
|
||||
});
|
||||
},
|
||||
// 获取详情
|
||||
getDetail() {
|
||||
this.loading = true;
|
||||
API_Order.getComplainDetail(this.id).then((res) => {
|
||||
this.loading = false;
|
||||
handleStoreComplaint() {
|
||||
API_Order.storeComplain({
|
||||
complainStatus: "WAIT_APPEAL",
|
||||
complainId: this.complaintInfo.id,
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
this.complaintInfo = res.result;
|
||||
this.images = (res.result.images || "").split(",");
|
||||
this.appealImages = (res.result.appealImages || "").split(",");
|
||||
this.$Message.success("操作成功");
|
||||
this.getDetail();
|
||||
}
|
||||
});
|
||||
},
|
||||
//返回列表
|
||||
returnDataList() {
|
||||
this.$router.push({
|
||||
name: "orderComplaint",
|
||||
});
|
||||
getDetail() {
|
||||
if (!this.id) return;
|
||||
this.loading = true;
|
||||
API_Order.getOrderComplainDetail(this.id)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.complaintInfo = res.result || emptyComplaint();
|
||||
this.images = (res.result.images || "")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
this.appealImages = (res.result.appealImages || "")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
returnDataList() {
|
||||
this.$router.push({ name: "orderComplaint" });
|
||||
},
|
||||
arbitrationHandle() {
|
||||
this.arbitrationResultShow = true;
|
||||
},
|
||||
arbitrationHandleSubmit() {
|
||||
if (!this.arbitrationParams.arbitrationResult) {
|
||||
this.$Message.error("请填写仲裁内容");
|
||||
return;
|
||||
}
|
||||
this.submitLoading = true;
|
||||
API_Order.orderComplete(this.id, this.arbitrationParams)
|
||||
.then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("仲裁成功");
|
||||
this.arbitrationParams.arbitrationResult = "";
|
||||
this.arbitrationResultShow = false;
|
||||
this.getDetail();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
},
|
||||
//回复
|
||||
handleSubmit() {
|
||||
if (this.params.content === "") {
|
||||
if (!this.params.content) {
|
||||
this.$Message.error("请填写对话内容");
|
||||
return;
|
||||
}
|
||||
this.submitLoading = true;
|
||||
this.params.complainId = this.id;
|
||||
API_Order.addOrderComplaint(this.params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("对话成功");
|
||||
this.params.content = "";
|
||||
this.getDetail();
|
||||
}
|
||||
});
|
||||
},
|
||||
//申诉
|
||||
appealSubmit() {
|
||||
|
||||
if (this.appeal.appealContent === "") {
|
||||
this.$Message.error("请填写内容");
|
||||
return;
|
||||
}
|
||||
this.appeal.appealImages = this.appeal.appealImages.map(item=> item.url)
|
||||
this.appeal.orderComplaintId = this.id;
|
||||
API_Order.appeal(this.appeal).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("申诉成功");
|
||||
this.getDetail();
|
||||
}
|
||||
});
|
||||
API_Order.addOrderCommunication(this.params)
|
||||
.then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("对话成功");
|
||||
this.params.content = "";
|
||||
this.getDetail();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.id = this.$route.query.id;
|
||||
this.getDetail();
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken"),
|
||||
};
|
||||
},
|
||||
// 如果是从详情页返回列表页,修改列表页keepAlive为true,确保不刷新页面
|
||||
beforeRouteLeave(to, from, next){
|
||||
if(to.name === 'orderComplaint') {
|
||||
to.meta.keepAlive = true
|
||||
}
|
||||
next()
|
||||
}
|
||||
watch: {
|
||||
"$route.query.id"(val) {
|
||||
this.id = val;
|
||||
this.getDetail();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .ivu-col {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.complain-upload-list {
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
margin-right: 4px;
|
||||
}
|
||||
.complain-upload-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.complain-upload-list-cover {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.complain-upload-list:hover .complain-upload-list-cover {
|
||||
display: block;
|
||||
}
|
||||
.complain-upload-list-cover i {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
min-height: 600px;
|
||||
padding: 10px;
|
||||
@@ -546,4 +460,14 @@ export default {
|
||||
overflow-x: auto;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.price-text {
|
||||
color: #ff5c58;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,369 +1,374 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="商品" prop="goodsName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.goodsName"
|
||||
clearable
|
||||
placeholder="请输入商品名称"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.memberName"
|
||||
clearable
|
||||
placeholder="请输入会员名称"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="订单编号" prop="orderSn">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.orderSn"
|
||||
clearable
|
||||
placeholder="请输入订单编号"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
|
||||
<Form-item label="申请时间">
|
||||
<DatePicker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
clearable
|
||||
@on-change="selectDateRange"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<div class="order-tab">
|
||||
<Tabs v-model="currentStatus" @on-click="serviceStatusClick">
|
||||
<TabPane v-for="item in serviceStatusWithCount" :key="item.value" :label="item.title" :name="item.value"/>
|
||||
</Tabs>
|
||||
</div>
|
||||
<Table
|
||||
:loading="loading"
|
||||
class="mt_10"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="关键字" prop="keywords" style="display: block; width: 100%">
|
||||
<el-input
|
||||
v-model="searchForm.keywords"
|
||||
placeholder="请输入商品名称、订单编号搜索"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单编号" prop="orderSn">
|
||||
<el-input
|
||||
v-model="searchForm.orderSn"
|
||||
placeholder="请输入订单编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="售后单号" prop="sn">
|
||||
<el-input
|
||||
v-model="searchForm.sn"
|
||||
placeholder="请输入售后单号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
style="width: 360px"
|
||||
@change="selectDateRange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商家名称" prop="storeName">
|
||||
<el-input
|
||||
v-model="searchForm.storeName"
|
||||
placeholder="请输入商家名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="售后类型">
|
||||
<el-select
|
||||
v-model="searchForm.serviceType"
|
||||
placeholder="全部"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option label="退款" value="RETURN_MONEY" />
|
||||
<el-option label="退货" value="RETURN_GOODS" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 商品栏目格式化 -->
|
||||
<template slot="goodsSlot" slot-scope="{row}">
|
||||
<div style="margin-top: 5px;height: 60px; display: flex;">
|
||||
<div style="">
|
||||
<img :src="row.goodsImage" style="height: 50px;margin-top: 3px">
|
||||
</div>
|
||||
<el-card>
|
||||
<div class="order-tab">
|
||||
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
|
||||
<el-tab-pane
|
||||
v-for="item in serviceStatusWithCount"
|
||||
:key="item.value"
|
||||
:label="item.title"
|
||||
:name="item.value"
|
||||
/>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 13px;">
|
||||
<div class="div-zoom">
|
||||
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sn" label="售后服务单号" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column prop="orderSn" label="订单编号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="商品" min-width="300">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" style="margin-top: 5px; height: 80px; display: flex">
|
||||
<div>
|
||||
<img
|
||||
:src="row.goodsImage"
|
||||
style="width: 60px; height: 60px; margin-top: 3px; object-fit: cover; border-radius: 4px"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div style="margin-left: 13px">
|
||||
<div class="div-zoom">
|
||||
<a class="link-text" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
<div style="color: #999; font-size: 12px; margin-top: 5px">
|
||||
商品ID: {{ row.goodsId }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="memberId" label="会员ID" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="memberName" label="会员名称" width="140" />
|
||||
<el-table-column prop="storeName" label="店铺名称" width="100" show-overflow-tooltip />
|
||||
<el-table-column label="售后金额" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.applyRefundPrice, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="售后类型" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="serviceTypeTagType(row.serviceType)">
|
||||
{{ serviceTypeText(row.serviceType) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="售后状态" width="180">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="serviceStatusTagType(row.serviceStatus)">
|
||||
{{ serviceStatusText(row.serviceStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="申请时间" width="180" />
|
||||
<el-table-column label="操作" fixed="right" align="center" width="100">
|
||||
<template #default="{ row }">
|
||||
<a v-if="row" class="link-text" @click="detail(row)">查看</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Order from "@/api/order";
|
||||
import * as API_Order from "@/api/order";
|
||||
|
||||
export default {
|
||||
name: "returnGoodsOrder",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
// serviceType:"RETURN_GOODS",
|
||||
orderSn:"",
|
||||
memberName:"",
|
||||
goodsName:""
|
||||
export default {
|
||||
name: "after-sale-order",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
orderSn: "",
|
||||
memberName: "",
|
||||
serviceStatus: "",
|
||||
storeName: "",
|
||||
sn: "",
|
||||
keywords: "",
|
||||
},
|
||||
selectDate: null,
|
||||
data: [],
|
||||
total: 0,
|
||||
currentStatus: "",
|
||||
afterSaleNumData: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
serviceStatusWithCount() {
|
||||
return [
|
||||
{ title: "全部", value: "" },
|
||||
{
|
||||
title: `申请售后${this.afterSaleNumData.applyNum ? "(" + this.afterSaleNumData.applyNum + ")" : ""}`,
|
||||
value: "APPLY",
|
||||
},
|
||||
selectDate: null,
|
||||
columns: [
|
||||
|
||||
{
|
||||
title: "售后单号",
|
||||
key: "sn",
|
||||
minWidth: 150,
|
||||
},
|
||||
{
|
||||
title: "订单号",
|
||||
key: "orderSn",
|
||||
minWidth: 150,
|
||||
},
|
||||
|
||||
{
|
||||
title: "商品",
|
||||
key: "sn",
|
||||
minWidth: 200,
|
||||
slot: "goodsSlot",
|
||||
|
||||
},
|
||||
{
|
||||
title: "申请退款金额",
|
||||
key: "applyRefundPrice",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.applyRefundPrice,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "会员ID",
|
||||
key: "memberId",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
align: "center",
|
||||
key: "serviceStatus",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
if (params.row.serviceStatus == "APPLY") {
|
||||
return h('div', [h('tag', {props: {color: "blue"}}, '申请中'),]);
|
||||
} else if (params.row.serviceStatus == "PASS") {
|
||||
return h('div', [h('tag', {props: {color: "cyan"}}, '通过售后'),]);
|
||||
} else if (params.row.serviceStatus == "REFUSE") {
|
||||
return h('div', [h('tag', {props: {color: "volcano"}}, '拒绝售后'),]);
|
||||
} else if (params.row.serviceStatus == "BUYER_RETURN") {
|
||||
return h('div', [h('tag', {props: {color: "orange"}}, '买家退货,待卖家收货'),]);
|
||||
} else if (params.row.serviceStatus == "SELLER_CONFIRM") {
|
||||
return h('div', [h('tag', {props: {color: "gold"}}, '卖家确认收货'),]);
|
||||
} else if (params.row.serviceStatus == "SELLER_TERMINATION") {
|
||||
return h('div', [h('tag', {props: {color: "lime"}}, '卖家终止售后'),]);
|
||||
} else if (params.row.serviceStatus == "BUYER_CANCEL") {
|
||||
return h('div', [h('tag', {props: {color: "purple"}}, '买家取消售后'),]);
|
||||
} else if (params.row.serviceStatus == "COMPLETE") {
|
||||
return h('div', [h('tag', {props: {color: "green"}}, '完成售后'),]);
|
||||
}else if (params.row.serviceStatus == "WAIT_REFUND") {
|
||||
return h('div', [h('tag', {props: {color: "geekblue"}}, '待平台退款'),]);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "申请时间",
|
||||
key: "createTime",
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: 'right',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
serviceStatus: [
|
||||
{title: '全部', value: ''},
|
||||
{title: '申请售后', value: 'APPLY'},
|
||||
{title: '通过售后', value: 'PASS'},
|
||||
{title: '拒绝售后', value: 'REFUSE'},
|
||||
{title: '待收货', value: 'BUYER_RETURN'},
|
||||
{title: '确认收货', value: 'SELLER_CONFIRM'},
|
||||
{title: '完成售后', value: 'COMPLETE'},
|
||||
{title: '卖家终止售后', value: 'SELLER_TERMINATION'},
|
||||
{title: '买家取消售后', value: 'BUYER_CANCEL'},
|
||||
{title: '等待平台退款', value: 'WAIT_REFUND'}
|
||||
],
|
||||
currentStatus: '',
|
||||
afterSaleNumData: {} // 售后数量统计数据
|
||||
{
|
||||
title: `通过售后${this.afterSaleNumData.passNum ? "(" + this.afterSaleNumData.passNum + ")" : ""}`,
|
||||
value: "PASS",
|
||||
},
|
||||
{
|
||||
title: `拒绝售后${this.afterSaleNumData.refuseNum ? "(" + this.afterSaleNumData.refuseNum + ")" : ""}`,
|
||||
value: "REFUSE",
|
||||
},
|
||||
{
|
||||
title: `待收货${this.afterSaleNumData.buyerReturnNum ? "(" + this.afterSaleNumData.buyerReturnNum + ")" : ""}`,
|
||||
value: "BUYER_RETURN",
|
||||
},
|
||||
{
|
||||
title: `确认收货${this.afterSaleNumData.sellerConfirmNum ? "(" + this.afterSaleNumData.sellerConfirmNum + ")" : ""}`,
|
||||
value: "SELLER_CONFIRM",
|
||||
},
|
||||
{
|
||||
title: `完成售后${this.afterSaleNumData.completeNum ? "(" + this.afterSaleNumData.completeNum + ")" : ""}`,
|
||||
value: "COMPLETE",
|
||||
},
|
||||
{
|
||||
title: `卖家终止售后${this.afterSaleNumData.sellerTerminationNum ? "(" + this.afterSaleNumData.sellerTerminationNum + ")" : ""}`,
|
||||
value: "SELLER_TERMINATION",
|
||||
},
|
||||
{
|
||||
title: `买家取消售后${this.afterSaleNumData.buyerCancelNum ? "(" + this.afterSaleNumData.buyerCancelNum + ")" : ""}`,
|
||||
value: "BUYER_CANCEL",
|
||||
},
|
||||
{
|
||||
title: `等待平台退款${this.afterSaleNumData.waitRefundNum ? "(" + this.afterSaleNumData.waitRefundNum + ")" : ""}`,
|
||||
value: "WAIT_REFUND",
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
serviceTypeText(type) {
|
||||
const map = {
|
||||
RETURN_MONEY: "退款",
|
||||
RETURN_GOODS: "退货",
|
||||
EXCHANGE_GOODS: "换货",
|
||||
};
|
||||
return map[type] || type || "-";
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getAfterSaleNumData();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
this.getAfterSaleNumData();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
const defaultForm = {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
// serviceType:"RETURN_GOODS",
|
||||
orderSn:"",
|
||||
memberName:"",
|
||||
goodsName:""
|
||||
}
|
||||
this.searchForm = defaultForm;
|
||||
this.selectDate = ''
|
||||
this.getDataList();
|
||||
this.getAfterSaleNumData();
|
||||
},
|
||||
// 范围时间选择格式化
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
}
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.afterSaleOrderPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
// 获取售后数量统计
|
||||
getAfterSaleNumData() {
|
||||
const { serviceStatus, ...searchParams } = this.searchForm;
|
||||
API_Order.getAfterSaleNumVO(searchParams).then((res) => {
|
||||
if (res.success) {
|
||||
this.afterSaleNumData = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 退货订单详情
|
||||
detail(v) {
|
||||
let sn = v.sn;
|
||||
this.$options.filters.customRouterPush({
|
||||
name: "return-goods-order-detail",
|
||||
query: { sn: sn },
|
||||
})
|
||||
|
||||
},
|
||||
// 售后筛选
|
||||
serviceStatusClick(item) {
|
||||
this.currentStatus = item;
|
||||
// 如果是全部(空字符串),则删除serviceStatus字段
|
||||
if (item === 0) {
|
||||
delete this.searchForm.serviceStatus;
|
||||
} else {
|
||||
this.searchForm.serviceStatus = item;
|
||||
}
|
||||
this.getDataList();
|
||||
this.getAfterSaleNumData();
|
||||
},
|
||||
serviceTypeTagType(type) {
|
||||
const map = {
|
||||
RETURN_MONEY: "primary",
|
||||
RETURN_GOODS: "warning",
|
||||
EXCHANGE_GOODS: "success",
|
||||
};
|
||||
return map[type] || "info";
|
||||
},
|
||||
mounted () {
|
||||
this.init();
|
||||
serviceStatusText(status) {
|
||||
const map = {
|
||||
APPLY: "申请中",
|
||||
PASS: "通过售后",
|
||||
REFUSE: "拒绝售后",
|
||||
BUYER_RETURN: "买家退货,待卖家收货",
|
||||
SELLER_CONFIRM: "卖家确认收货",
|
||||
SELLER_TERMINATION: "卖家终止售后",
|
||||
BUYER_CANCEL: "买家取消售后",
|
||||
COMPLETE: "完成售后",
|
||||
WAIT_REFUND: "待平台退款",
|
||||
};
|
||||
return map[status] || status || "-";
|
||||
},
|
||||
computed: {
|
||||
// 带数量的售后状态
|
||||
serviceStatusWithCount() {
|
||||
return [
|
||||
{title: '全部', value: ''},
|
||||
{title: `申请售后${this.afterSaleNumData.applyNum ? '(' + this.afterSaleNumData.applyNum + ')' : ''}`, value: 'APPLY'},
|
||||
{title: `通过售后${this.afterSaleNumData.passNum ? '(' + this.afterSaleNumData.passNum + ')' : ''}`, value: 'PASS'},
|
||||
{title: `拒绝售后${this.afterSaleNumData.refuseNum ? '(' + this.afterSaleNumData.refuseNum + ')' : ''}`, value: 'REFUSE'},
|
||||
{title: `待收货${this.afterSaleNumData.buyerReturnNum ? '(' + this.afterSaleNumData.buyerReturnNum + ')' : ''}`, value: 'BUYER_RETURN'},
|
||||
{title: `确认收货${this.afterSaleNumData.sellerConfirmNum ? '(' + this.afterSaleNumData.sellerConfirmNum + ')' : ''}`, value: 'SELLER_CONFIRM'},
|
||||
{title: `完成售后${this.afterSaleNumData.completeNum ? '(' + this.afterSaleNumData.completeNum + ')' : ''}`, value: 'COMPLETE'},
|
||||
{title: `卖家终止售后${this.afterSaleNumData.sellerTerminationNum ? '(' + this.afterSaleNumData.sellerTerminationNum + ')' : ''}`, value: 'SELLER_TERMINATION'},
|
||||
{title: `买家取消售后${this.afterSaleNumData.buyerCancelNum ? '(' + this.afterSaleNumData.buyerCancelNum + ')' : ''}`, value: 'BUYER_CANCEL'},
|
||||
{title: `等待平台退款${this.afterSaleNumData.waitRefundNum ? '(' + this.afterSaleNumData.waitRefundNum + ')' : ''}`, value: 'WAIT_REFUND'}
|
||||
];
|
||||
serviceStatusTagType(status) {
|
||||
const map = {
|
||||
APPLY: "primary",
|
||||
PASS: "info",
|
||||
REFUSE: "warning",
|
||||
BUYER_RETURN: "warning",
|
||||
SELLER_CONFIRM: "",
|
||||
SELLER_TERMINATION: "success",
|
||||
BUYER_CANCEL: "danger",
|
||||
COMPLETE: "success",
|
||||
WAIT_REFUND: "primary",
|
||||
};
|
||||
return map[status] || "info";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getAfterSaleNumData();
|
||||
},
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
this.getAfterSaleNumData();
|
||||
},
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false
|
||||
next()
|
||||
}
|
||||
};
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getAfterSaleOrderPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
getAfterSaleNumData() {
|
||||
const { serviceStatus, ...searchParams } = this.searchForm;
|
||||
API_Order.getAfterSaleNumVO(searchParams).then((res) => {
|
||||
if (res.success) {
|
||||
this.afterSaleNumData = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
detail(v) {
|
||||
const sn = v.sn;
|
||||
this.$filters.customRouterPush({
|
||||
name: "after-order-detail",
|
||||
query: { sn: sn },
|
||||
});
|
||||
},
|
||||
onStatusTabClick(tab) {
|
||||
this.serviceStatusClick(tab.paneName);
|
||||
},
|
||||
serviceStatusClick(item) {
|
||||
this.currentStatus = item;
|
||||
if (item === "" || item === undefined) {
|
||||
delete this.searchForm.serviceStatus;
|
||||
} else {
|
||||
this.searchForm.serviceStatus = item;
|
||||
}
|
||||
this.getDataList();
|
||||
this.getAfterSaleNumData();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
// Tab组件样式
|
||||
.order-tab {
|
||||
::v-deep .ivu-tabs-tab {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-tab {
|
||||
:deep(.el-tabs__item) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,298 +1,197 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="商品" prop="goodsName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.goodsName"
|
||||
clearable
|
||||
placeholder="请输入商品名称"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.memberName"
|
||||
clearable
|
||||
placeholder="请输入会员名称"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="订单编号" prop="orderSn">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.orderSn"
|
||||
clearable
|
||||
placeholder="请输入订单编号"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
|
||||
<Form-item label="申请时间">
|
||||
<DatePicker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
clearable
|
||||
@on-change="selectDateRange"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
class="mt_10"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
|
||||
ref="table"
|
||||
>
|
||||
|
||||
<!-- 商品栏目格式化 -->
|
||||
<template slot="goodsSlot" slot-scope="{row}">
|
||||
<div style="margin-top: 5px;height: 90px; display: flex;">
|
||||
<div style="">
|
||||
<img :src="row.goodsImage" style="height: 80px;margin-top: 3px">
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 13px;">
|
||||
<div class="div-zoom">
|
||||
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
|
||||
</div>
|
||||
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
|
||||
<div slot="content">
|
||||
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
|
||||
</div>
|
||||
<img src="../../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
|
||||
</Poptip>
|
||||
</div>
|
||||
<el-card>
|
||||
<el-tabs v-model="activeTab" @tab-click="onTabClick">
|
||||
<el-tab-pane label="退款" name="RETURN_MONEY">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="取消" name="CANCEL">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="退货" name="RETURN_GOODS">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="投诉" name="COMPLAIN">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
<el-button @click="getDataList">刷新</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-table v-loading="loading" border :data="data" ref="table" style="width: 100%">
|
||||
<el-table-column prop="createBy" label="创建人" min-width="120" />
|
||||
<el-table-column prop="reason" label="原因" min-width="400" />
|
||||
<el-table-column prop="createTime" label="时间" min-width="100" />
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="售后原因" prop="reason">
|
||||
<el-input v-model="form.reason" maxlength="20" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Order from "@/api/order";
|
||||
import * as API_Order from "@/api/order";
|
||||
|
||||
export default {
|
||||
name: "returnMoneyOrder",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
serviceType:"RETURN_MONEY",
|
||||
orderSn:"",
|
||||
memberName:"",
|
||||
goodsName:""
|
||||
},
|
||||
selectDate: null,
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "退款编号",
|
||||
key: "sn",
|
||||
minWidth: 150,
|
||||
},
|
||||
{
|
||||
title: "订单号",
|
||||
key: "orderSn",
|
||||
minWidth: 150,
|
||||
},
|
||||
|
||||
{
|
||||
title: "商品",
|
||||
key: "sn",
|
||||
minWidth: 250,
|
||||
sortable: false,
|
||||
slot: "goodsSlot",
|
||||
},
|
||||
{
|
||||
title: "申请退款金额",
|
||||
key: "applyRefundPrice",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.applyRefundPrice,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
title: "会员",
|
||||
key: "memberName",
|
||||
minWidth: 130,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: "申请时间",
|
||||
key: "createTime",
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: "售后状态",
|
||||
key: "serviceStatus",
|
||||
minWidth: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.serviceStatus == "APPLY") {
|
||||
return h('div', [h('tag', {props: {color: "blue"}}, '申请中'),]);
|
||||
} else if (params.row.serviceStatus == "PASS") {
|
||||
return h('div', [h('tag', {props: {color: "cyan"}}, '通过售后'),]);
|
||||
} else if (params.row.serviceStatus == "REFUSE") {
|
||||
return h('div', [h('tag', {props: {color: "volcano"}}, '拒绝售后'),]);
|
||||
} else if (params.row.serviceStatus == "BUYER_CANCEL") {
|
||||
return h('div', [h('tag', {props: {color: "purple"}}, '买家取消售后'),]);
|
||||
} else if (params.row.serviceStatus == "COMPLETE") {
|
||||
return h('div', [h('tag', {props: {color: "green"}}, '完成售后'),]);
|
||||
}else if (params.row.serviceStatus == "WAIT_REFUND") {
|
||||
return h('div', [h('tag', {props: {color: "geekblue"}}, '待平台退款'),]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: 'right',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
};
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeTab: "RETURN_MONEY",
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
loading: true,
|
||||
submitLoading: false,
|
||||
form: { reason: "" },
|
||||
formValidate: {
|
||||
reason: [{ required: true, message: "请输入售后原因", trigger: "blur" }],
|
||||
},
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
serviceType: "RETURN_MONEY",
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onTabClick(tab) {
|
||||
this.handleClickType(tab.paneName);
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
serviceType:"RETURN_MONEY",
|
||||
orderSn:"",
|
||||
memberName:"",
|
||||
goodsName:""
|
||||
}
|
||||
this.selectDate = ''
|
||||
|
||||
this.getDataList();
|
||||
},
|
||||
// 范围时间重新赋值
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
}
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.afterSaleOrderPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleClickType(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.searchForm.serviceType = v;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getAfterSaleReasonPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
},
|
||||
// 退款订单详情
|
||||
detail(v) {
|
||||
let sn = v.sn;
|
||||
this.$options.filters.customRouterPush({
|
||||
name: "return-goods-order-detail",
|
||||
query: { sn: sn },
|
||||
})
|
||||
|
||||
},
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
add() {
|
||||
this.form.reason = "";
|
||||
this.modalVisible = true;
|
||||
this.modalTitle = "添加售后原因";
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false
|
||||
next()
|
||||
}
|
||||
};
|
||||
edit(v) {
|
||||
this.form.reason = v.reason;
|
||||
this.form.id = v.id;
|
||||
this.modalVisible = true;
|
||||
this.modalTitle = "修改售后原因";
|
||||
},
|
||||
handleSubmit() {
|
||||
this.form.serviceType = this.searchForm.serviceType;
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalTitle == "添加售后原因") {
|
||||
delete this.form.id;
|
||||
API_Order.addAfterSaleReason(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
API_Order.editAfterSaleReason(this.form.id, this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "确认要删除此售后原因?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
API_Order.delAfterSaleReason(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("售后原因已删除");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getDataList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,314 +1,297 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Row>
|
||||
<Col>
|
||||
<Card>
|
||||
<div class="main-content">
|
||||
<div class="div-flow-left">
|
||||
<div class="div-form-default">
|
||||
<h3>售后申请</h3>
|
||||
<dl>
|
||||
<dt>售后商品</dt>
|
||||
<dd>
|
||||
<div>
|
||||
<img :src="afterSaleInfo.goodsImage" style="height: 60px">
|
||||
</div>
|
||||
<a>{{ afterSaleInfo.goodsName }}</a><br>
|
||||
<span>{{ afterSaleInfo.num }}(数量)</span>
|
||||
</dd>
|
||||
<el-card>
|
||||
<div class="main-content">
|
||||
<div class="div-flow-left">
|
||||
<div class="div-form-default">
|
||||
<h3>退货申请</h3>
|
||||
<dl>
|
||||
<dt>退货商品</dt>
|
||||
<dd>
|
||||
<div>
|
||||
<img :src="afterSaleInfo.goodsImage" style="height: 60px">
|
||||
</div>
|
||||
<a @click="linkTo(afterSaleInfo.goodsId, afterSaleInfo.skuId)">{{ afterSaleInfo.goodsName }}
|
||||
</a><br>
|
||||
|
||||
</dl>
|
||||
<span>{{ afterSaleInfo.num }}(数量)</span>
|
||||
|
||||
<dl>
|
||||
<dt>退货退款编号</dt>
|
||||
<dd>{{ afterSaleInfo.sn }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>售后状态</dt>
|
||||
<dd>{{ filterStatus(afterSaleInfo.serviceStatus) }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>退货退款原因</dt>
|
||||
<dd>{{ afterSaleInfo.reason }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>申请退款金额</dt>
|
||||
<dd>
|
||||
<priceColorScheme :value="afterSaleInfo.applyRefundPrice" :color="$mainColor" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.actualRefundPrice">
|
||||
<dt>实际退款金额</dt>
|
||||
<dd>{{ afterSaleInfo.actualRefundPrice | unitPrice('¥') }}</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.refundPoint">
|
||||
<dt>退还积分</dt>
|
||||
<dd>{{ afterSaleInfo.refundPoint }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>退货数量</dt>
|
||||
<dd>{{ afterSaleInfo.num }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>问题描述</dt>
|
||||
<dd>{{ afterSaleInfo.problemDesc }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>凭证</dt>
|
||||
<dd v-if="afterSaleImage == ''">
|
||||
暂无凭证
|
||||
</dd>
|
||||
<dd v-else>
|
||||
<div class="div-img" @click="()=>{picFile=item; picVisible = true}" v-for="(item, index) in afterSaleImage" :key="index">
|
||||
<img class="complain-img" :src="item">
|
||||
|
||||
</div>
|
||||
|
||||
<Modal footer-hide mask-closable v-model="picVisible">
|
||||
<img :src="picFile" alt="无效的图片链接" style="width: 100%; margin: 0 auto; display: block" />
|
||||
</Modal>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="div-form-default" v-if="afterSaleInfo.serviceStatus=='APPLY'">
|
||||
<h3>商家处理意见</h3>
|
||||
<dl>
|
||||
<dt>商家</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
{{ afterSaleInfo.storeName }}
|
||||
</div>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>是否同意</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
<RadioGroup type="button" button-style="solid" v-model="params.serviceStatus">
|
||||
<Radio label="PASS">
|
||||
<span>同意</span>
|
||||
</Radio>
|
||||
<Radio label="REFUSE">
|
||||
<span>拒绝</span>
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>申请退款金额</dt>
|
||||
<dd>
|
||||
<priceColorScheme :value="afterSaleInfo.applyRefundPrice" :color="$mainColor" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="params.serviceStatus == 'PASS'">
|
||||
<dt>实际退款金额</dt>
|
||||
<dd>
|
||||
<InputNumber :min="0" v-model="params.actualRefundPrice" style="width:260px" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>备注信息</dt>
|
||||
<dd>
|
||||
<Input v-model="params.remark" type="textarea" maxlength="200" :rows="4" clearable style="width:260px" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<div style="text-align: right;width: 45%;margin-top: 10px">
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit" style="margin-left: 5px">
|
||||
确定
|
||||
</Button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="div-form-default" v-if="afterSaleInfo.serviceStatus !='APPLY'">
|
||||
<h3>商家处理</h3>
|
||||
<dl>
|
||||
<dt>商家</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
{{ afterSaleInfo.storeName }}
|
||||
</div>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>审核结果</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
<span v-if="params.serviceStatus=='PASS'">
|
||||
审核通过
|
||||
</span>
|
||||
<span v-else>
|
||||
审核拒绝
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>备注信息</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.auditRemark }}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>售后状态</dt>
|
||||
<dd>{{ afterSaleInfo.serviceName }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>退货退款编号</dt>
|
||||
<dd>{{ afterSaleInfo.sn }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>退货退款原因</dt>
|
||||
<dd>{{ afterSaleInfo.reason }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>申请退款金额</dt>
|
||||
<dd>
|
||||
<priceColorScheme :value="afterSaleInfo.applyRefundPrice" :color="$mainColor"></priceColorScheme>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.actualRefundPrice">
|
||||
<dt>实际退款金额</dt>
|
||||
<dd>
|
||||
<priceColorScheme :value="afterSaleInfo.actualRefundPrice" :color="$mainColor"></priceColorScheme>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.refundPoint">
|
||||
<dt>退还积分</dt>
|
||||
<dd>{{ afterSaleInfo.refundPoint }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>退货数量</dt>
|
||||
<dd>{{ afterSaleInfo.num }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>问题描述</dt>
|
||||
<dd>{{ afterSaleInfo.problemDesc }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>凭证</dt>
|
||||
<dd v-if="afterSaleImage == ''">暂无凭证</dd>
|
||||
<dd v-else>
|
||||
<div class="div-img" v-for="(item, index) in afterSaleImage" :key="index">
|
||||
<img class="complain-img" :src="item" />
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="div-flow-center">
|
||||
|
||||
<div class="div-form-default" v-if="afterSaleInfo.serviceStatus == 'APPLY'">
|
||||
<h3>处理意见</h3>
|
||||
<dl>
|
||||
<dt>商家</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
{{ afterSaleInfo.storeName }}
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>是否同意</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
<el-radio-group v-model="params.serviceStatus">
|
||||
<el-radio-button value="PASS">同意</el-radio-button>
|
||||
<el-radio-button value="REFUSE">拒绝</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>申请退款金额</dt>
|
||||
<dd>
|
||||
<priceColorScheme :value="afterSaleInfo.applyRefundPrice" :color="$mainColor"></priceColorScheme>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>实际退款金额</dt>
|
||||
<dd>
|
||||
<el-input-number :min="0" v-model="params.actualRefundPrice" style="width: 260px" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>备注信息</dt>
|
||||
<dd>
|
||||
<el-input
|
||||
v-model="params.remark"
|
||||
type="textarea"
|
||||
maxlength="200"
|
||||
:rows="4"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dd>
|
||||
<div style="text-align: right; width: 45%; margin-top: 10px">
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="handleSubmit"
|
||||
style="margin-left: 5px"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="div-flow-right">
|
||||
<div class="div-form-default">
|
||||
<h3>订单相关信息</h3>
|
||||
<dl>
|
||||
<dt>
|
||||
订单编号
|
||||
</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.orderSn }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.bankDepositName">
|
||||
<dt>银行开户行</dt>
|
||||
<dd>
|
||||
{{afterSaleInfo.bankDepositName}}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.bankAccountName">
|
||||
<dt>银行开户名</dt>
|
||||
<dd>
|
||||
{{afterSaleInfo.bankAccountName}}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.bankAccountNumber">
|
||||
<dt>银行卡号</dt>
|
||||
<dd>
|
||||
{{afterSaleInfo.bankAccountNumber}}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
<div class="div-form-default" v-if="afterSaleInfo.serviceStatus =='BUYER_RETURN' || afterSaleInfo.serviceStatus =='COMPLETE' && afterSaleInfo.serviceType !='RETURN_MONEY'">
|
||||
<h3>回寄物流信息</h3>
|
||||
<dl>
|
||||
<dt>
|
||||
物流公司
|
||||
</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.mlogisticsName }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
物流单号
|
||||
</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.mlogisticsNo }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>操作</dt>
|
||||
<dd>
|
||||
<Button type="info" :loading="submitLoading" @click="sellerConfirmSubmit('PASS')" style="margin-left: 5px" v-if="afterSaleInfo.afterSaleAllowOperationVO.rog">
|
||||
确认收货
|
||||
</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="sellerConfirmSubmit('REFUSE')" style="margin-left: 5px" v-if="afterSaleInfo.afterSaleAllowOperationVO.rog">
|
||||
拒收
|
||||
</Button>
|
||||
<Button type="default" :loading="submitLoading" @click="logisticsBuyer()" style="margin-left: 5px">
|
||||
查询物流
|
||||
</Button>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
<div class="div-form-default" v-if="afterSaleInfo.afterSaleAllowOperationVO.return_goods && afterSaleInfo.serviceType == 'EXCHANGE_GOODS'">
|
||||
<h3>换货</h3>
|
||||
<dl>
|
||||
<dt>
|
||||
换货
|
||||
</dt>
|
||||
<dd>
|
||||
<Button type="primary" :loading="submitLoading" @click="exchangeGoods" style="margin-left: 5px">
|
||||
发货
|
||||
</Button>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="div-form-default" v-if=" afterSaleInfo.serviceType == 'EXCHANGE_GOODS' && afterSaleInfo.serviceStatus =='SELLER_RE_DELIVERY'">
|
||||
<h3>物流信息</h3>
|
||||
<dl>
|
||||
<dt>
|
||||
物流公司
|
||||
</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.slogisticsName }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
物流单号
|
||||
</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.slogisticsNo }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>操作</dt>
|
||||
<dd>
|
||||
<Button type="primary" :loading="submitLoading" @click="logisticsSeller()" style="margin-left: 5px">
|
||||
查询物流
|
||||
</Button>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
<div class="div-form-default" v-if="afterSaleInfo.serviceStatus != 'APPLY'">
|
||||
<h3>商家处理</h3>
|
||||
<dl>
|
||||
<dt>商家</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
{{ afterSaleInfo.storeName }}
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<!-- <dl>
|
||||
<dt>审核结果</dt>
|
||||
<dd>
|
||||
<div class="div-content">
|
||||
<span v-if="params.serviceStatus=='PASS'">
|
||||
审核通过
|
||||
</span>
|
||||
<span v-else>
|
||||
审核拒绝
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</dd>
|
||||
</dl> -->
|
||||
<dl>
|
||||
<dt>备注信息</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.auditRemark || "暂无备注信息" }}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-flow-center"></div>
|
||||
<div class="div-flow-right">
|
||||
<div class="div-form-default">
|
||||
<h3>订单相关信息</h3>
|
||||
<dl>
|
||||
<dt>订单编号</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.orderSn }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.bankDepositName">
|
||||
<dt>银行开户行</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.bankDepositName }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.bankAccountName">
|
||||
<dt>银行开户名</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.bankAccountName }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl v-if="afterSaleInfo.bankAccountNumber">
|
||||
<dt>银行卡号</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.bankAccountNumber }}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div
|
||||
class="div-form-default"
|
||||
v-if="
|
||||
afterSaleInfo.afterSaleAllowOperationVO &&
|
||||
afterSaleInfo.afterSaleAllowOperationVO.refund
|
||||
"
|
||||
>
|
||||
<h3>平台退款</h3>
|
||||
<dl>
|
||||
<dt>银行开户行</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.bankDepositName }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>银行开户名</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.bankAccountName }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>银行卡号</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.bankAccountNumber }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>备注信息</dt>
|
||||
<dd>
|
||||
<el-input
|
||||
v-model="refundPriceForm.remark"
|
||||
type="textarea"
|
||||
maxlength="200"
|
||||
:rows="4"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>操作</dt>
|
||||
<dd>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="refundPriceSubmit"
|
||||
style="margin-left: 5px"
|
||||
>
|
||||
退款
|
||||
</el-button>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div
|
||||
class="div-form-default"
|
||||
v-if="
|
||||
afterSaleInfo.showDelivery && afterSaleInfo.serviceType === 'RETURN_GOODS'
|
||||
"
|
||||
>
|
||||
<h3>物流信息</h3>
|
||||
<dl>
|
||||
<dt>收货商家</dt>
|
||||
<dd>{{ afterSaleInfo.storeName }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>收货商家手机</dt>
|
||||
<dd>{{ storeMsg.salesConsigneeMobile }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>收货地址</dt>
|
||||
<dd>
|
||||
{{ storeMsg.salesConsigneeAddressPath }}
|
||||
{{ storeMsg.salesConsigneeDetail }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>物流公司</dt>
|
||||
<dd>{{ afterSaleInfo.mlogisticsName }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>物流单号</dt>
|
||||
<dd>
|
||||
{{ afterSaleInfo.mlogisticsNo }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>操作</dt>
|
||||
<dd>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
:loading="submitLoading"
|
||||
@click="logisticsSeller()"
|
||||
style="margin-left: 5px"
|
||||
>
|
||||
查询物流
|
||||
</el-button>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<!-- 订单发货 -->
|
||||
<Modal v-model="modalVisible" width="500px">
|
||||
<p slot="header">
|
||||
<span>订单发货</span>
|
||||
</p>
|
||||
<div>
|
||||
<Form ref="form" :model="form" :label-width="90" :rules="formValidate" style="position:relative">
|
||||
<FormItem label="物流公司" prop="logisticsId">
|
||||
<Select v-model="form.logisticsId" placeholder="请选择" style="width:250px">
|
||||
<Option v-for="(item, i) in checkedLogistics" :key="i" :value="item.id">{{ item.name }}
|
||||
</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label="物流单号" prop="logisticsNo">
|
||||
<Input v-model="form.logisticsNo" style="width:250px" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
|
||||
</div>
|
||||
|
||||
<div slot="footer" style="text-align: right">
|
||||
<Button size="large" @click="modalVisible = false">取消</Button>
|
||||
<Button type="success" size="large" @click="orderDeliverySubmit">发货</Button>
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
<!-- 查询物流 -->
|
||||
<Modal v-model="logisticsModal" width="40">
|
||||
<p slot="header">
|
||||
<span>查询物流</span>
|
||||
</p>
|
||||
<el-dialog v-model="logisticsModal" title="查询物流" width="640px" append-to-body>
|
||||
<div class="layui-layer-wrap">
|
||||
<dl>
|
||||
<dt>售后单号:</dt>
|
||||
@@ -319,92 +302,101 @@
|
||||
<dl>
|
||||
<dt>物流公司:</dt>
|
||||
<dd>
|
||||
<div class="text-box">{{ logisticsInfo.shipper }}</div>
|
||||
<div class="text-box">{{ afterSaleInfo.mlogisticsName }}</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>物流单号:</dt>
|
||||
<dd>
|
||||
<div nctype="ordersSn" class="text-box">{{ logisticsInfo.logisticCode }}</div>
|
||||
<div class="text-box">{{ afterSaleInfo.mlogisticsNo }}</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<div class="div-express-log">
|
||||
<ul class="express-log">
|
||||
<li v-for="(item,index) in logisticsInfo.traces" :key="index">
|
||||
<span class="time">{{ item.AcceptTime }}</span>
|
||||
<span class="detail">{{ item.AcceptStation }}</span>
|
||||
</li>
|
||||
<template v-if="Object.keys(logisticsInfo).length">
|
||||
<li v-for="(item, index) in logisticsInfo.traces" :key="index">
|
||||
<span class="time">{{ item.AcceptTime }}</span>
|
||||
<span class="detail">{{ item.AcceptStation }}</span>
|
||||
</li>
|
||||
</template>
|
||||
<template v-else>
|
||||
<li style="text-align: center">暂无物流信息</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div slot="footer" style="text-align: right">
|
||||
<Button @click="logisticsModal = false">取消</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="logisticsClose">取消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Order from "@/api/order";
|
||||
import uploadPicThumb from "@/views/my-components/lili/upload-pic-thumb";
|
||||
|
||||
import vueQr from "vue-qr";
|
||||
export default {
|
||||
name: "orderComplaint",
|
||||
components: {
|
||||
uploadPicThumb,
|
||||
"vue-qr": vueQr,
|
||||
},
|
||||
name: "orderDetail",
|
||||
data() {
|
||||
return {
|
||||
picFile: "", // 预览图片地址
|
||||
picVisible: false, // 预览图片
|
||||
sn: "", // 订单号
|
||||
logisticsModal: false, //查询物流模态框
|
||||
|
||||
logisticsInfo: {}, //物流信息
|
||||
form: {
|
||||
// 物流信息
|
||||
logisticsNo: "",
|
||||
logisticsId: "",
|
||||
}, //换货发货form
|
||||
formValidate: {
|
||||
logisticsNo: [
|
||||
{ required: true, message: "发货单号不能为空", trigger: "change" },
|
||||
],
|
||||
logisticsId: [
|
||||
{ required: true, message: "请选择物流公司", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
afterSaleInfo: {
|
||||
// 售后信息
|
||||
afterSaleAllowOperationVO: {
|
||||
return_goods: false,
|
||||
},
|
||||
},
|
||||
afterSaleInfo: {}, // 售后信息
|
||||
afterSaleImage: [], //会员申诉图片
|
||||
appealImages: [], //商家申诉的图片
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
checkedLogistics: [], //选中的物流公司集合
|
||||
storeMsg: {}, // 商家地址信息
|
||||
//商家处理意见
|
||||
params: {
|
||||
serviceStatus: "PASS",
|
||||
remark: "",
|
||||
actualRefundPrice: 0,
|
||||
},
|
||||
// 售后状态
|
||||
afterSaleStatus: [
|
||||
{ status: "APPLY", label: "申请中" },
|
||||
{ status: "PASS", label: "通过售后" },
|
||||
{ status: "REFUSE", label: "拒绝售后" },
|
||||
{ status: "BUYER_RETURN", label: "买家退货,待卖家收货" },
|
||||
{ status: "SELLER_RE_DELIVERY", label: "商家换货" },
|
||||
{ status: "SELLER_CONFIRM", label: "卖家确认收货" },
|
||||
{ status: "SELLER_TERMINATION", label: "卖家终止售后" },
|
||||
{ status: "BUYER_CONFIRM", label: "买家确认收货" },
|
||||
{ status: "BUYER_CANCEL", label: "买家取消售后" },
|
||||
{ status: "WAIT_REFUND", label: "待平台退款" },
|
||||
{ status: "COMPLETE", label: "完成售后" },
|
||||
//平台退款
|
||||
refundPriceForm: {
|
||||
remark: "",
|
||||
},
|
||||
afterSaleStatusList: [
|
||||
// 售后状态列表
|
||||
{
|
||||
name: "申请中",
|
||||
status: "APPLY",
|
||||
},
|
||||
{
|
||||
name: "通过售后",
|
||||
status: "PASS",
|
||||
},
|
||||
{
|
||||
name: "拒绝售后",
|
||||
status: "REFUSE",
|
||||
},
|
||||
{
|
||||
name: "买家退货,待卖家收货",
|
||||
status: "BUYER_RETURN",
|
||||
},
|
||||
{
|
||||
name: "卖家确认收货",
|
||||
status: "SELLER_CONFIRM",
|
||||
},
|
||||
{
|
||||
name: "卖家终止售后",
|
||||
status: "SELLER_TERMINATION",
|
||||
},
|
||||
{
|
||||
name: "买家取消售后",
|
||||
status: "BUYER_CANCEL",
|
||||
},
|
||||
{
|
||||
name: "完成售后",
|
||||
status: "COMPLETE",
|
||||
},
|
||||
{
|
||||
name: "待平台退款",
|
||||
status: "WAIT_REFUND",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
@@ -412,46 +404,56 @@ export default {
|
||||
// 获取售后详情
|
||||
getDetail() {
|
||||
this.loading = true;
|
||||
API_Order.afterSaleOrderDetail(this.sn).then((res) => {
|
||||
API_Order.getAfterSaleOrderDetail(this.sn).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.afterSaleInfo = res.result;
|
||||
this.afterSaleInfo.showDelivery = this.showDelivery(
|
||||
this.afterSaleInfo.serviceStatus
|
||||
);
|
||||
this.afterSaleInfo.serviceName = this.filterOrderStatus(
|
||||
this.afterSaleInfo.serviceStatus
|
||||
);
|
||||
this.afterSaleImage = (res.result.afterSaleImage || "").split(",");
|
||||
this.params.actualRefundPrice = res.result.applyRefundPrice;
|
||||
}
|
||||
});
|
||||
},
|
||||
//换货弹出框
|
||||
exchangeGoods() {
|
||||
API_Order.getLogisticsChecked().then((res) => {
|
||||
if (res.success) {
|
||||
this.checkedLogistics = res.result;
|
||||
this.modalVisible = true;
|
||||
this.getDetail();
|
||||
}
|
||||
});
|
||||
},
|
||||
//商家确认收货
|
||||
sellerConfirmSubmit(type) {
|
||||
let title = "确认收货";
|
||||
let content = "请确认已经收到退货货物?";
|
||||
let message = "收货成功";
|
||||
if (type !== "PASS") {
|
||||
title = "确认拒收";
|
||||
content = "确认拒收此货物?";
|
||||
message = "拒收成功";
|
||||
this.params.serviceStatus = "REFUSE";
|
||||
}
|
||||
//退货地址去掉逗号
|
||||
if (this.afterSaleInfo.mconsigneeAddressPath)
|
||||
this.afterSaleInfo.mconsigneeAddressPath = this.afterSaleInfo.mconsigneeAddressPath.replaceAll(
|
||||
",",
|
||||
" "
|
||||
);
|
||||
|
||||
this.params.actualRefundPrice = this.afterSaleInfo.applyRefundPrice;
|
||||
// 如果显示物流信息,展示商家地址
|
||||
if (this.afterSaleInfo.showDelivery) {
|
||||
API_Order.storeAddress(this.sn).then((resu) => {
|
||||
if (resu.success) {
|
||||
const obj = resu.result;
|
||||
obj.salesConsigneeAddressPath = obj.salesConsigneeAddressPath.replaceAll(
|
||||
",",
|
||||
""
|
||||
);
|
||||
this.storeMsg = obj;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
//平台退款
|
||||
refundPriceSubmit() {
|
||||
if (this.refundPriceForm.remark == "") {
|
||||
this.$Message.error("请输入退款备注");
|
||||
return;
|
||||
}
|
||||
this.$Modal.confirm({
|
||||
title: title,
|
||||
content: content,
|
||||
title: "确认退款",
|
||||
content: "请确认退款?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
API_Order.afterSaleSellerConfirm(this.sn, this.params).then((res) => {
|
||||
API_Order.refundPrice(this.sn, this.refundPriceForm).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success(message);
|
||||
this.$Message.success("收款成功");
|
||||
this.getDetail();
|
||||
}
|
||||
});
|
||||
@@ -460,15 +462,6 @@ export default {
|
||||
},
|
||||
//查询物流
|
||||
logisticsSeller() {
|
||||
this.logisticsModal = true;
|
||||
API_Order.getSellerDeliveryTraces(this.sn).then((res) => {
|
||||
if (res.success && res.result != null) {
|
||||
this.logisticsInfo = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
//查询物流
|
||||
logisticsBuyer() {
|
||||
this.logisticsModal = true;
|
||||
API_Order.getAfterSaleTraces(this.sn).then((res) => {
|
||||
if (res.success && res.result != null) {
|
||||
@@ -476,27 +469,18 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//换货发货
|
||||
orderDeliverySubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
API_Order.afterSaleSellerDelivery(this.sn, this.form).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("订单发货成功");
|
||||
this.modalVisible = false;
|
||||
this.getDataDetail();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//关闭物流弹出框
|
||||
logisticsClose() {
|
||||
this.logisticsModal = false;
|
||||
},
|
||||
//回复
|
||||
handleSubmit() {
|
||||
this.submitLoading = true;
|
||||
if (this.params.remark == "") {
|
||||
this.$Message.error("请输入备注信息");
|
||||
this.submitLoading = false;
|
||||
return;
|
||||
}
|
||||
if (this.params.actualRefundPrice == "") {
|
||||
this.$Message.error("请输入退款金额");
|
||||
return;
|
||||
}
|
||||
API_Order.afterSaleSellerReview(this.sn, this.params).then((res) => {
|
||||
@@ -507,39 +491,36 @@ export default {
|
||||
this.getDetail();
|
||||
}
|
||||
});
|
||||
this.submitLoading = false;
|
||||
},
|
||||
// 返回售后状态中文描述
|
||||
filterStatus(status) {
|
||||
let label = '';
|
||||
for (let i = 0; i < this.afterSaleStatus.length; i++) {
|
||||
const obj = this.afterSaleStatus[i];
|
||||
if (obj.status === status) {
|
||||
label = obj.label;
|
||||
break;
|
||||
filterOrderStatus(status) {
|
||||
// 获取订单状态中文
|
||||
const ob = this.afterSaleStatusList.filter((e) => {
|
||||
return e.status === status;
|
||||
});
|
||||
return ob.length > 0 ? ob[0].name : status;
|
||||
},
|
||||
// 根据订单状态判断是否显示物流信息
|
||||
showDelivery(status) {
|
||||
let flag = false;
|
||||
this.afterSaleStatusList.forEach((e, index) => {
|
||||
// 订单为买家退货,待卖家收货之后的状态,并且不是买家取消售后,展示物流信息
|
||||
if (e.status === status && index >= 3 && index !== 6) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
return label;
|
||||
});
|
||||
return flag;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.sn = this.$route.query.sn;
|
||||
this.getDetail();
|
||||
},
|
||||
// 如果是从详情页返回列表页,修改列表页keepAlive为true,确保不刷新页面
|
||||
beforeRouteLeave(to, from, next){
|
||||
if(to.name === 'returnGoodsOrder' || to.name === 'returnMoneyOrder') {
|
||||
to.meta.keepAlive = true
|
||||
}
|
||||
next()
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.ivu-row {
|
||||
display: block !important;
|
||||
<style lang="scss">
|
||||
.ivu-col {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
min-height: 600px;
|
||||
padding: 10px;
|
||||
@@ -573,7 +554,6 @@ export default {
|
||||
display: flex;
|
||||
|
||||
dt {
|
||||
display: inline-block;
|
||||
flex: 2;
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
@@ -584,8 +564,6 @@ export default {
|
||||
|
||||
dd {
|
||||
flex: 10;
|
||||
display: inline-block;
|
||||
|
||||
padding: 15px 0 15px 1%;
|
||||
margin: 0;
|
||||
border-left: 1px solid #f0f0f0;
|
||||
@@ -698,10 +676,10 @@ dl dt {
|
||||
margin: 0;
|
||||
border-bottom: dotted 1px #e6e6e6;
|
||||
overflow: hidden;
|
||||
|
||||
display: flex;
|
||||
dt {
|
||||
display: inline-block;
|
||||
width: 13%;
|
||||
flex: 2;
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
padding: 15px 1% 15px 0;
|
||||
@@ -711,7 +689,7 @@ dl dt {
|
||||
|
||||
dd {
|
||||
display: inline-block;
|
||||
width: 84%;
|
||||
flex: 10;
|
||||
padding: 15px 0 15px 1%;
|
||||
margin: 0;
|
||||
border-left: 1px solid #f0f0f0;
|
||||
|
||||
@@ -1,60 +1,62 @@
|
||||
<template>
|
||||
<Card>
|
||||
<el-card>
|
||||
<div class="step-list">
|
||||
<div class="step-item" @click="handleCheckStep(item)" :class="{'active':item.checked}" v-for="(item,index) in stepList" :key="index">
|
||||
<img class="img" :src="item.img" alt="">
|
||||
<div
|
||||
v-for="(item, index) in stepList"
|
||||
:key="index"
|
||||
class="step-item"
|
||||
:class="{ active: item.checked }"
|
||||
@click="handleCheckStep(item)"
|
||||
>
|
||||
<img class="img" :src="item.img" alt="" />
|
||||
<div>
|
||||
<h2>{{item.title}}</h2>
|
||||
<h2>{{ item.title }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-for="(item,index) in stepList" :key="index">
|
||||
<!-- 下载 -->
|
||||
<div v-if="item.checked && index ==0" class="tpl">
|
||||
|
||||
<Button @click="downLoad">下载导入模板</Button>
|
||||
<div v-for="(item, index) in stepList" :key="'step-' + index">
|
||||
<div v-if="item.checked && index === 0" class="tpl">
|
||||
<el-button @click="downLoad">下载导入模板</el-button>
|
||||
</div>
|
||||
<!-- 上传 -->
|
||||
<div v-if="item.checked && index ==1" class="tpl">
|
||||
<Upload :before-upload="handleUpload" name="files" style="width:50%; height:400px;" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
multiple type="drag" :action="action" :headers="accessToken">
|
||||
<div style="padding: 50px 0">
|
||||
<Icon type="ios-cloud-upload" size="102" style="color: #3399ff"></Icon>
|
||||
<h2>选择或拖拽文件上传</h2>
|
||||
</div>
|
||||
</Upload>
|
||||
<div v-if="item.checked && index === 1" class="tpl">
|
||||
<el-upload
|
||||
drag
|
||||
name="files"
|
||||
style="width: 50%; height: 400px"
|
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
:action="action"
|
||||
:headers="accessToken"
|
||||
:before-upload="handleUpload"
|
||||
:show-file-list="false"
|
||||
>
|
||||
<el-icon :size="102" style="color: #3399ff"><UploadFilled /></el-icon>
|
||||
<h2>选择或拖拽文件上传</h2>
|
||||
</el-upload>
|
||||
</div>
|
||||
<!-- 上传 -->
|
||||
<div v-if="item.checked && index ==2" class="tpl success">
|
||||
|
||||
<div v-if="item.checked && index === 2" class="tpl success">
|
||||
<h1>发货完成</h1>
|
||||
|
||||
<div>
|
||||
<Button class="btn" @click="close">关闭页面</Button>
|
||||
<Button class="btn" type="primary" @click="navigationToGoodsOrder">商品订单</Button>
|
||||
<el-button class="btn" @click="close">关闭页面</el-button>
|
||||
<el-button class="btn" type="primary" @click="navigationToGoodsOrder">商品订单</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</Card>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JsonExcel from "vue-json-excel";
|
||||
import { UploadFilled } from "@element-plus/icons-vue";
|
||||
import { downLoadDeliverExcel, uploadDeliverExcel } from "@/api/order.js";
|
||||
import { baseUrl } from "@/libs/axios.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
"download-excel": JsonExcel,
|
||||
},
|
||||
components: { UploadFilled },
|
||||
data() {
|
||||
return {
|
||||
file: "",
|
||||
action: baseUrl + "/order/order/batchDeliver", // 上传接口
|
||||
accessToken: {}, // 验证token
|
||||
// 步骤集合
|
||||
action: baseUrl + "/order/order/batchDeliver",
|
||||
accessToken: {},
|
||||
stepList: [
|
||||
{
|
||||
img: require("@/assets/download.png"),
|
||||
@@ -78,75 +80,55 @@ export default {
|
||||
this.accessToken.accessToken = this.getStore("accessToken");
|
||||
},
|
||||
methods: {
|
||||
// 点击选择步骤
|
||||
handleCheckStep(val) {
|
||||
if (val.title.search("3") == -1) {
|
||||
this.stepList.map((item) => {
|
||||
if (val.title.search("3") === -1) {
|
||||
this.stepList.forEach((item) => {
|
||||
item.checked = false;
|
||||
});
|
||||
val.checked = true;
|
||||
}
|
||||
},
|
||||
// 上传数据
|
||||
handleUpload(file) {
|
||||
this.file = file;
|
||||
this.upload();
|
||||
return false;
|
||||
},
|
||||
// 跳转订单列表
|
||||
navigationToGoodsOrder() {
|
||||
this.$router.push({
|
||||
path: "/order/orderList",
|
||||
});
|
||||
this.$router.push({ path: "/order/orderList" });
|
||||
},
|
||||
// 关闭页面
|
||||
close() {
|
||||
this.$store.commit("removeTag", "export-order-deliver");
|
||||
localStorage.storeOpenedList = JSON.stringify(
|
||||
this.$store.state.app.storeOpenedList
|
||||
);
|
||||
localStorage.storeOpenedList = JSON.stringify(this.$store.state.app.storeOpenedList);
|
||||
this.$router.go(-1);
|
||||
},
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*/
|
||||
async upload() {
|
||||
let fd = new FormData();
|
||||
const fd = new FormData();
|
||||
fd.append("files", this.file);
|
||||
let res = await uploadDeliverExcel(fd);
|
||||
const res = await uploadDeliverExcel(fd);
|
||||
if (res.success) {
|
||||
this.stepList.map((item) => {
|
||||
this.stepList.forEach((item) => {
|
||||
item.checked = false;
|
||||
});
|
||||
|
||||
this.stepList[2].checked = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载excel
|
||||
*/
|
||||
downLoad() {
|
||||
downLoadDeliverExcel()
|
||||
.then((res) => {
|
||||
const blob = new Blob([res], {
|
||||
type: "application/vnd.ms-excel;charset=utf-8",
|
||||
});
|
||||
//对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性
|
||||
//IE10以上支持blob但是依然不支持download
|
||||
if ("download" in document.createElement("a")) {
|
||||
//支持a标签download的浏览器
|
||||
const link = document.createElement("a"); //创建a标签
|
||||
link.download = "批量发货导入模板.xls"; //a标签添加属性
|
||||
const link = document.createElement("a");
|
||||
link.download = "批量发货导入模板.xls";
|
||||
link.style.display = "none";
|
||||
link.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(link);
|
||||
link.click(); //执行下载
|
||||
URL.revokeObjectURL(link.href); //释放url
|
||||
document.body.removeChild(link); //释放标签
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
document.body.removeChild(link);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
navigator.msSaveBlob(blob, "批量发货导入模板.xls");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -201,7 +183,7 @@ img {
|
||||
font-size: 28px;
|
||||
margin: 10px;
|
||||
}
|
||||
::v-deep .btn {
|
||||
:deep(.btn) {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,543 +1,414 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="关键字" prop="keywords" style="display: block; width: 100%;">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="关键字" prop="keywords" style="display: block; width: 100%">
|
||||
<el-input
|
||||
v-model="searchForm.keywords"
|
||||
placeholder="请输入商品名称/收货人/收货人手机号/店铺名称"
|
||||
clearable
|
||||
style="width: 500px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="订单编号" prop="orderSn">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.orderSn"
|
||||
clearable
|
||||
placeholder="请输入订单编号"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="会员名称" prop="buyerName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.buyerName"
|
||||
clearable
|
||||
placeholder="请输入会员名称"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="收货人" prop="shipName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.shipName"
|
||||
placeholder="请输入收货人姓名"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="订单类型" prop="orderType">
|
||||
<Select
|
||||
v-model="searchForm.orderPromotionType"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="NORMAL">普通订单</Option>
|
||||
<Option value="PINTUAN">拼团订单</Option>
|
||||
<Option value="GIFT">赠品订单</Option>
|
||||
<Option value="POINTS">积分订单</Option>
|
||||
<Option value="KANJIA">砍价订单</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="下单时间">
|
||||
<DatePicker
|
||||
</el-form-item>
|
||||
<el-form-item label="订单号" prop="orderSn">
|
||||
<el-input v-model="searchForm.orderSn" placeholder="请输入订单号" clearable style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称" prop="buyerName">
|
||||
<el-input v-model="searchForm.buyerName" placeholder="请输入会员名称" clearable style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="收货人" prop="shipName">
|
||||
<el-input v-model="searchForm.shipName" placeholder="请输入收货人姓名" clearable style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单类型" prop="orderType">
|
||||
<el-select v-model="searchForm.orderPromotionType" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="普通订单" value="NORMAL" />
|
||||
<el-option label="拼团订单" value="PINTUAN" />
|
||||
<el-option label="赠品订单" value="GIFT" />
|
||||
<el-option label="积分订单" value="POINTS" />
|
||||
<el-option label="砍价订单" value="KANJIA" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式" prop="paymentMethod">
|
||||
<el-select v-model="searchForm.paymentMethod" placeholder="请选择支付方式" clearable style="width: 240px">
|
||||
<el-option label="微信支付" value="WECHAT" />
|
||||
<el-option label="支付宝" value="ALIPAY" />
|
||||
<el-option label="余额支付" value="WALLET" />
|
||||
<el-option label="线下转账" value="BANK_TRANSFER" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="下单时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
format="yyyy-MM-dd"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
@on-change="selectDateRange"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn"
|
||||
>搜索</Button
|
||||
>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
style="width: 360px"
|
||||
@change="selectDateRange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<div class="order-tab">
|
||||
<Tabs v-model="currentStatus" @on-click="orderStatusClick">
|
||||
<TabPane v-for="(item,index) in orderStatusWithCount" :key="index" :label="item.title" :name="item.value">
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in orderStatusWithCount"
|
||||
:key="index"
|
||||
:label="item.title"
|
||||
:name="item.value"
|
||||
/>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div class="export">
|
||||
<Button type="primary" class="mr_10" @click="expressOrderDeliver">批量发货</Button>
|
||||
<Button @click="exportOrder" type="info" class="export">导出订单</Button>
|
||||
<Poptip @keydown.enter.native="orderVerification" placement="bottom-start" width="400">
|
||||
<Button class="export">
|
||||
核验订单
|
||||
</Button>
|
||||
<div class="api" slot="content">
|
||||
<h2>核验码</h2>
|
||||
<div style="margin:10px 0;">
|
||||
<Input v-model="orderCode" style="width:300px; margin-right:10px;" />
|
||||
<Button style="primary" @click="orderVerification">核验</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Poptip>
|
||||
<div>
|
||||
<el-button type="info" class="export" @click="exportOrder">导出订单</el-button>
|
||||
</div>
|
||||
<Table
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
|
||||
<el-table v-loading="loading" :data="data" ref="table" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="sn" label="订单号" min-width="240" show-overflow-tooltip />
|
||||
<el-table-column label="订单来源" width="120">
|
||||
<template #default="{ row }">{{ clientTypeText(row.clientType) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单类型" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="orderPromotionTagType(row.orderPromotionType)">
|
||||
{{ orderPromotionText(row.orderPromotionType) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="memberName" label="买家名称" min-width="130" show-overflow-tooltip />
|
||||
<el-table-column prop="memberId" label="会员ID" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="订单金额" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span :style="{ color: $mainColor }">{{ $filters.unitPrice(row.flowPrice, '¥') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付方式" width="120">
|
||||
<template #default="{ row }">{{ paymentMethodText(row.paymentMethod) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="orderStatusTagType(row.orderStatus)">{{ orderStatusText(row.orderStatus) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="下单时间" width="170" />
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="detail(row)">查看</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Order from "@/api/order";
|
||||
import JsonExcel from "vue-json-excel";
|
||||
import Cookies from "js-cookie";
|
||||
import {verificationCode} from "@/api/order";
|
||||
export default {
|
||||
name: "orderList",
|
||||
components: {
|
||||
"download-excel": JsonExcel,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
fields: {
|
||||
订单编号: "sn",
|
||||
下单时间: "createTime",
|
||||
客户名称: "memberName",
|
||||
支付方式: {
|
||||
field: "clientType",
|
||||
callback: (value) => {
|
||||
if (value == "H5") return "移动端";
|
||||
if (value == "PC") return "PC端";
|
||||
if (value == "WECHAT_MP") return "小程序端";
|
||||
if (value == "APP") return "移动应用端";
|
||||
return value;
|
||||
},
|
||||
},
|
||||
商品数量: "groupNum",
|
||||
付款状态: {
|
||||
field: "payStatus",
|
||||
callback: (value) =>
|
||||
value == "UNPAID" ? "未付款" : value == "PAID" ? "已付款" : "",
|
||||
},
|
||||
店铺: "storeName",
|
||||
},
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "", // 默认排序字段
|
||||
order: "", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
orderType: "",
|
||||
orderSn: "",
|
||||
keywords: "",
|
||||
buyerName: "",
|
||||
goodsName: "",
|
||||
shipName: "",
|
||||
orderStatus: "",
|
||||
orderType: "NORMAL",
|
||||
paymentMethod: "",
|
||||
orderPromotionType: "",
|
||||
},
|
||||
selectDate: null,
|
||||
columns: [
|
||||
{
|
||||
title: "订单号",
|
||||
key: "sn",
|
||||
minWidth: 200,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
if (params.row.sellerRemark) {
|
||||
return h("div", {}, params.row.sellerRemark + " ("+params.row.sn+")");
|
||||
} else {
|
||||
return h("div", {}, params.row.sn);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "订单来源",
|
||||
key: "clientType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.clientType == "H5") {
|
||||
return h("div", {}, "移动端");
|
||||
} else if (params.row.clientType == "PC") {
|
||||
return h("div", {}, "PC端");
|
||||
} else if (params.row.clientType == "WECHAT_MP") {
|
||||
return h("div", {}, "小程序端");
|
||||
} else if (params.row.clientType == "APP") {
|
||||
return h("div", {}, "APP端");
|
||||
} else {
|
||||
return h("div", {}, params.row.clientType);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "订单类型",
|
||||
key: "orderPromotionType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.orderPromotionType == "NORMAL") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "blue" } }, "普通订单"),
|
||||
]);
|
||||
} else if (params.row.orderPromotionType == "PINTUAN") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "volcano" } }, "拼团订单"),
|
||||
]);
|
||||
} else if (params.row.orderPromotionType == "GIFT") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "green" } }, "赠品订单"),
|
||||
]);
|
||||
} else if (params.row.orderPromotionType == "POINTS") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "geekblue" } }, "积分订单"),
|
||||
]);
|
||||
} else if (params.row.orderPromotionType == "KANJIA") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "pink" } }, "砍价订单"),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "买家名称",
|
||||
key: "memberName",
|
||||
minWidth: 130,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "会员ID",
|
||||
key: "memberId",
|
||||
minWidth: 120,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "订单金额",
|
||||
key: "flowPrice",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.flowPrice,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "订单状态",
|
||||
key: "orderStatus",
|
||||
minWidth: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.orderStatus == "UNPAID") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "magenta" } }, "未付款"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "PAID") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "blue" } }, "已付款"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "UNDELIVERED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "geekblue" } }, "待发货"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "STAY_PICKED_UP") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "geekblue" } }, "待自提"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "PARTS_DELIVERED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "cyan" } }, "部分发货"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "DELIVERED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "cyan" } }, "已发货"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "COMPLETED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "green" } }, "已完成"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "TAKE") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "volcano" } }, "待核验"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "CANCELLED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "red" } }, "已取消"),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "支付方式",
|
||||
key: "paymentMethod",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.paymentMethod == "NOT_ACTUALLY_PAID") {
|
||||
return h("div", {}, "-");
|
||||
} else if (params.row.paymentMethod == "WECHAT") {
|
||||
return h("div", {}, "微信支付");
|
||||
} else if (params.row.paymentMethod == "ALIPAY") {
|
||||
return h("div", {}, "支付宝");
|
||||
} else if (params.row.paymentMethod == "WALLET") {
|
||||
return h("div", {}, "余额支付");
|
||||
} else if (params.row.paymentMethod == "BANK_TRANSFER") {
|
||||
return h("div", {}, "线下转账");
|
||||
} else {
|
||||
return h("div", {}, params.row.paymentMethod || "-");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "下单时间",
|
||||
key: "createTime",
|
||||
width: 170,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
orderNumData: {}, // 新增:订单数量统计数据
|
||||
excelColumns: {
|
||||
// 导出excel的参数
|
||||
编号: "index",
|
||||
订单号: "sn",
|
||||
收货人: "consigneeName",
|
||||
收货人联系电话: "consigneeMobile",
|
||||
收货地址: "consigneeAddress",
|
||||
商品名称: "goodsName",
|
||||
商品价格: "goodsPrice",
|
||||
订单金额: "flowPrice",
|
||||
商品数量: "num",
|
||||
店铺名称: "storeName",
|
||||
创建时间: "createTime",
|
||||
},
|
||||
orderStatus: [
|
||||
{title: '全部', value: ''},
|
||||
{title: '未付款', value: 'UNPAID'},
|
||||
{title: '已付款', value: 'PAID'},
|
||||
{title: '待发货', value: 'UNDELIVERED'},
|
||||
{title: '部分发货', value: 'PARTS_DELIVERED'},
|
||||
{title: '已发货', value: 'DELIVERED'},
|
||||
{title: '待核验', value: 'TAKE'},
|
||||
{title: '待自提', value: 'STAY_PICKED_UP'},
|
||||
{title: '已完成', value: 'COMPLETED'},
|
||||
{title: '已关闭', value: 'CANCELLED'},
|
||||
],
|
||||
currentStatus: ''
|
||||
data: [],
|
||||
total: 0,
|
||||
orderNumData: {},
|
||||
currentStatus: "ALL",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 新增:带数量的订单状态选项
|
||||
orderStatusWithCount() {
|
||||
return [
|
||||
{title: '全部', value: ''},
|
||||
{title: `未付款${this.orderNumData.waitPayNum ? '(' + this.orderNumData.waitPayNum + ')' : ''}`, value: 'UNPAID'},
|
||||
{title: `已付款${this.orderNumData.waitDeliveryNum ? '(' + this.orderNumData.waitDeliveryNum + ')' : ''}`, value: 'PAID'},
|
||||
{title: `待发货${this.orderNumData.waitShipNum ? '(' + this.orderNumData.waitShipNum + ')' : ''}`, value: 'UNDELIVERED'},
|
||||
{title: `部分发货${this.orderNumData.partsDeliveredNumNum ? '(' + this.orderNumData.partsDeliveredNumNum + ')' : ''}`, value: 'PARTS_DELIVERED'},
|
||||
{title: `已发货${this.orderNumData.deliveredNum ? '(' + this.orderNumData.deliveredNum + ')' : ''}`, value: 'DELIVERED'},
|
||||
{title: `待核验${this.orderNumData.waitCheckNum ? '(' + this.orderNumData.waitCheckNum + ')' : ''}`, value: 'TAKE'},
|
||||
{title: `待自提${this.orderNumData.waitSelfPickNum ? '(' + this.orderNumData.waitSelfPickNum + ')' : ''}`, value: 'STAY_PICKED_UP'},
|
||||
{title: `已完成${this.orderNumData.finishNum ? '(' + this.orderNumData.finishNum + ')' : ''}`, value: 'COMPLETED'},
|
||||
{title: `已关闭${this.orderNumData.closeNum ? '(' + this.orderNumData.closeNum + ')' : ''}`, value: 'CANCELLED'},
|
||||
{ title: "全部", value: "ALL" },
|
||||
{
|
||||
title: `未付款${this.orderNumData.waitPayNum ? "(" + this.orderNumData.waitPayNum + ")" : ""}`,
|
||||
value: "UNPAID",
|
||||
},
|
||||
{
|
||||
title: `已付款${this.orderNumData.waitDeliveryNum ? "(" + this.orderNumData.waitDeliveryNum + ")" : ""}`,
|
||||
value: "PAID",
|
||||
},
|
||||
{
|
||||
title: `待发货${this.orderNumData.waitShipNum ? "(" + this.orderNumData.waitShipNum + ")" : ""}`,
|
||||
value: "UNDELIVERED",
|
||||
},
|
||||
{
|
||||
title: `部分发货${this.orderNumData.partsDeliveredNumNum ? "(" + this.orderNumData.partsDeliveredNumNum + ")" : ""}`,
|
||||
value: "PARTS_DELIVERED",
|
||||
},
|
||||
{
|
||||
title: `待收货${this.orderNumData.deliveredNum ? "(" + this.orderNumData.deliveredNum + ")" : ""}`,
|
||||
value: "DELIVERED",
|
||||
},
|
||||
{
|
||||
title: `待核验${this.orderNumData.waitCheckNum ? "(" + this.orderNumData.waitCheckNum + ")" : ""}`,
|
||||
value: "TAKE",
|
||||
},
|
||||
{
|
||||
title: `待自提${this.orderNumData.waitSelfPickNum ? "(" + this.orderNumData.waitSelfPickNum + ")" : ""}`,
|
||||
value: "STAY_PICKED_UP",
|
||||
},
|
||||
{
|
||||
title: `已完成${this.orderNumData.finishNum ? "(" + this.orderNumData.finishNum + ")" : ""}`,
|
||||
value: "COMPLETED",
|
||||
},
|
||||
{
|
||||
title: `已关闭${this.orderNumData.closeNum ? "(" + this.orderNumData.closeNum + ")" : ""}`,
|
||||
value: "CANCELLED",
|
||||
},
|
||||
];
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 核验订单
|
||||
*/
|
||||
async orderVerification() {
|
||||
let result = await verificationCode(this.orderCode);
|
||||
|
||||
if (result.success) {
|
||||
this.$router.push({
|
||||
name: "order-detail",
|
||||
query: { sn: result.result.sn || this.orderCode },
|
||||
});
|
||||
}
|
||||
onStatusTabClick(tab) {
|
||||
this.orderStatusClick(tab.paneName);
|
||||
},
|
||||
/**
|
||||
* 批量发货
|
||||
*/
|
||||
expressOrderDeliver() {
|
||||
this.$router.push({
|
||||
path: "/export-order-deliver",
|
||||
});
|
||||
clientTypeText(v) {
|
||||
const map = { H5: "移动端", PC: "PC端", WECHAT_MP: "小程序端", APP: "移动应用端" };
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
orderPromotionText(v) {
|
||||
const map = {
|
||||
NORMAL: "普通订单",
|
||||
PINTUAN: "拼团订单",
|
||||
GIFT: "赠品订单",
|
||||
POINTS: "积分订单",
|
||||
KANJIA: "砍价订单",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
orderPromotionTagType(v) {
|
||||
const map = {
|
||||
NORMAL: "primary",
|
||||
PINTUAN: "danger",
|
||||
GIFT: "success",
|
||||
POINTS: "info",
|
||||
KANJIA: "warning",
|
||||
};
|
||||
return map[v] || "info";
|
||||
},
|
||||
paymentMethodText(v) {
|
||||
const map = {
|
||||
NOT_ACTUALLY_PAID: "-",
|
||||
WECHAT: "微信支付",
|
||||
ALIPAY: "支付宝",
|
||||
WALLET: "余额支付",
|
||||
BANK_TRANSFER: "线下转账",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
orderStatusText(v) {
|
||||
const map = {
|
||||
UNPAID: "未付款",
|
||||
PAID: "已付款",
|
||||
UNDELIVERED: "待发货",
|
||||
STAY_PICKED_UP: "待自提",
|
||||
PARTS_DELIVERED: "部分发货",
|
||||
DELIVERED: "已发货",
|
||||
COMPLETED: "已完成",
|
||||
TAKE: "待核验",
|
||||
CANCELLED: "已关闭",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
orderStatusTagType(v) {
|
||||
const map = {
|
||||
UNPAID: "danger",
|
||||
PAID: "primary",
|
||||
UNDELIVERED: "info",
|
||||
STAY_PICKED_UP: "info",
|
||||
PARTS_DELIVERED: "warning",
|
||||
DELIVERED: "warning",
|
||||
COMPLETED: "success",
|
||||
TAKE: "warning",
|
||||
CANCELLED: "danger",
|
||||
};
|
||||
return map[v] || "info";
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getOrderNumData(); // 新增:获取订单数量统计
|
||||
this.getOrderNumData();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索订单
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
this.getOrderNumData(); // 新增:搜索时也更新数量统计
|
||||
this.getOrderNumData();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {};
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.selectDate = null;
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
this.searchForm.orderType = "NORMAL",
|
||||
// 重新加载数据
|
||||
this.getDataList();
|
||||
},
|
||||
// 起始时间处理
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
// 获取表格数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getOrderList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
API_Order.getOrderList(this.searchForm)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
detail(v) {
|
||||
this.$filters.customRouterPush({
|
||||
name: "order-detail",
|
||||
query: { sn: v.sn },
|
||||
});
|
||||
},
|
||||
// 导出订单
|
||||
async exportOrder() {
|
||||
if(this.searchForm.startDate==""||this.searchForm.endDate==""){
|
||||
if (!this.searchForm.startDate || !this.searchForm.endDate) {
|
||||
this.$Message.error("必须选择时间范围,搜索后进行导出!");
|
||||
}else{
|
||||
API_Order.exportOrder(this.searchForm)
|
||||
.then((res) => {
|
||||
const blob = new Blob([res], {
|
||||
type: "application/vnd.ms-excel;charset=utf-8",
|
||||
});
|
||||
//对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性
|
||||
//IE10以上支持blob但是依然不支持download
|
||||
if ("download" in document.createElement("a")) {
|
||||
//支持a标签download的浏览器
|
||||
const link = document.createElement("a"); //创建a标签
|
||||
link.download = "订单列表.xlsx"; //a标签添加属性
|
||||
link.style.display = "none";
|
||||
link.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(link);
|
||||
link.click(); //执行下载
|
||||
URL.revokeObjectURL(link.href); //释放url
|
||||
document.body.removeChild(link); //释放标签
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return;
|
||||
}
|
||||
API_Order.exportOrder(this.searchForm)
|
||||
.then((res) => {
|
||||
const blob = new Blob([res], {
|
||||
type: "application/vnd.ms-excel;charset=utf-8",
|
||||
});
|
||||
}
|
||||
|
||||
if ("download" in document.createElement("a")) {
|
||||
const link = document.createElement("a");
|
||||
link.download = "订单列表.xlsx";
|
||||
link.style.display = "none";
|
||||
link.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
document.body.removeChild(link);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, "订单列表.xlsx");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
// 查看订单详情
|
||||
detail(v) {
|
||||
let sn = v.sn;
|
||||
this.$options.filters.customRouterPush({
|
||||
name: "order-detail",
|
||||
query: { sn: sn },
|
||||
})
|
||||
|
||||
},
|
||||
// 订单筛选
|
||||
orderStatusClick(name) {
|
||||
if (name === 0) {
|
||||
// 点击"全部"时,设置为空字符串,在getDataList中会被过滤掉
|
||||
this.searchForm.orderStatus = '';
|
||||
if (name === "ALL" || name === "" || name === undefined) {
|
||||
this.searchForm.orderStatus = "";
|
||||
this.currentStatus = "ALL";
|
||||
} else {
|
||||
// 其他状态正常赋值
|
||||
this.searchForm.orderStatus = name;
|
||||
this.currentStatus = name;
|
||||
}
|
||||
this.currentStatus = name;
|
||||
|
||||
this.getDataList();
|
||||
},
|
||||
getOrderNumData() {
|
||||
// 创建一个不包含orderStatus字段的搜索参数
|
||||
const { orderStatus, ...searchParams } = this.searchForm;
|
||||
API_Order.getOrderNum(searchParams).then((res) => {
|
||||
if (res.success) {
|
||||
this.orderNumData = res.result;
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取订单数量统计失败:', err);
|
||||
});
|
||||
API_Order.getOrderNum(searchParams)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.orderNumData = res.result;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("获取订单数量统计失败:", err);
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false;
|
||||
next();
|
||||
},
|
||||
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.export {
|
||||
margin: 10px 20px 10px 0;
|
||||
}
|
||||
// Tab组件样式
|
||||
.order-tab {
|
||||
::v-deep .ivu-tabs-tab {
|
||||
:deep(.el-tabs__item) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,245 +1,191 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="订单编号" prop="orderSn">
|
||||
<Input type="text" v-model="searchForm.orderSn" clearable placeholder="请输入订单编号" style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="会员名称" prop="buyerName">
|
||||
<Input type="text" v-model="searchForm.buyerName" clearable placeholder="请输入会员名称" style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="订单状态" prop="orderStatus">
|
||||
<Select v-model="searchForm.orderStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<Option value="UNPAID">未付款</Option>
|
||||
<Option value="PAID">已付款</Option>
|
||||
<Option value="COMPLETED">已完成</Option>
|
||||
<Option value="TAKE">待核验</Option>
|
||||
<Option value="CANCELLED">已取消</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="下单时间">
|
||||
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd" clearable @on-change="selectDateRange" placeholder="选择起始时间" style="width: 240px"></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<div>
|
||||
<Poptip @keydown.enter.native="orderVerification" placement="bottom-start" width="400">
|
||||
<Button class="export">
|
||||
核验订单
|
||||
</Button>
|
||||
<div class="api" slot="content">
|
||||
<h2>核验码</h2>
|
||||
<div style="margin:10px 0;">
|
||||
<Input v-model="orderCode" style="width:300px; margin-right:10px;" />
|
||||
<Button style="primary" @click="orderVerification">核验</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Poptip>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="订单号" prop="orderSn">
|
||||
<el-input
|
||||
v-model="searchForm.orderSn"
|
||||
placeholder="请输入订单号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称" prop="buyerName">
|
||||
<el-input
|
||||
v-model="searchForm.buyerName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="下单时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
value-format="YYYY-MM-DD"
|
||||
clearable
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
@change="selectDateRange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<div class="order-tab">
|
||||
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in orderStatus"
|
||||
:key="index"
|
||||
:label="item.title"
|
||||
:name="item.value"
|
||||
/>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom" @on-sort-change="changeSort"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small"
|
||||
show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
@sort-change="changeSort"
|
||||
>
|
||||
<el-table-column prop="sn" label="订单号" min-width="230" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="下单时间" width="200" />
|
||||
<el-table-column label="订单来源" width="95">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">
|
||||
<span v-if="row.clientType == 'H5'">移动端</span>
|
||||
<span v-else-if="row.clientType == 'PC'">PC端</span>
|
||||
<span v-else-if="row.clientType == 'WECHAT_MP'">小程序端</span>
|
||||
<span v-else-if="row.clientType == 'APP'">移动应用端</span>
|
||||
<span v-else>{{ row.clientType }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="memberName" label="买家名称" width="130" />
|
||||
<el-table-column label="订单金额" prop="flowPrice" min-width="120" sortable="custom">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.flowPrice" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单状态" width="95">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-if="row.orderStatus == 'UNPAID'" type="danger">未付款</el-tag>
|
||||
<el-tag v-else-if="row.orderStatus == 'PAID'" type="primary">已付款</el-tag>
|
||||
<el-tag v-else-if="row.orderStatus == 'COMPLETED'" type="success">已完成</el-tag>
|
||||
<el-tag v-else-if="row.orderStatus == 'TAKE'" type="warning">待核验</el-tag>
|
||||
<el-tag v-else-if="row.orderStatus == 'CANCELLED'" type="info">已关闭</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a
|
||||
class="link-text"
|
||||
:class="{ disabled: row.orderStatus != 'UNPAID' }"
|
||||
@click="row.orderStatus == 'UNPAID' && confirmPrice(row)"
|
||||
>收款</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="detail(row)">查看</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Order from "@/api/order";
|
||||
import { verificationCode } from "@/api/order";
|
||||
export default {
|
||||
name: "virtualOrderList",
|
||||
name: "fictitiousOrderList",
|
||||
data() {
|
||||
return {
|
||||
orderCode: "", // 核验码
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "",
|
||||
order: "",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
orderType: "VIRTUAL",
|
||||
orderSn: "",
|
||||
buyerName: "",
|
||||
orderStatus: "",
|
||||
orderType: "VIRTUAL",
|
||||
},
|
||||
selectDate: null,
|
||||
columns: [
|
||||
{
|
||||
title: "订单号",
|
||||
key: "sn",
|
||||
minWidth: 240,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "订单来源",
|
||||
key: "clientType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.clientType == "H5") {
|
||||
return h("div", {}, "移动端");
|
||||
} else if (params.row.clientType == "PC") {
|
||||
return h("div", {}, "PC端");
|
||||
} else if (params.row.clientType == "WECHAT_MP") {
|
||||
return h("div", {}, "小程序端");
|
||||
} else if (params.row.clientType == "APP") {
|
||||
return h("div", {}, "移动应用端");
|
||||
} else {
|
||||
return h("div", {}, params.row.clientType);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "买家名称",
|
||||
key: "memberName",
|
||||
minWidth: 130,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "订单金额",
|
||||
key: "flowPrice",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.flowPrice,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
title: "订单状态",
|
||||
key: "orderStatus",
|
||||
minWidth: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.orderStatus == "UNPAID") {
|
||||
return h("div", [h("tag", {props: {color: "magenta"}}, "未付款")]);
|
||||
} else if (params.row.orderStatus == "PAID") {
|
||||
return h("div", [h("tag", {props: {color: "blue"}}, "已付款")]);
|
||||
} else if (params.row.orderStatus == "UNDELIVERED") {
|
||||
return h("div", [h("tag", {props: {color: "geekblue"}}, "待发货")]);
|
||||
} else if (params.row.orderStatus == "DELIVERED") {
|
||||
return h("div", [h("tag", {props: {color: "cyan"}}, "已发货")]);
|
||||
} else if (params.row.orderStatus == "COMPLETED") {
|
||||
return h("div", [h("tag", {props: {color: "green"}}, "已完成")]);
|
||||
} else if (params.row.orderStatus == "TAKE") {
|
||||
return h("div", [h("tag", {props: {color: "volcano"}}, "待核验")]);
|
||||
} else if (params.row.orderStatus == "CANCELLED") {
|
||||
return h("div", [h("tag", {props: {color: "red"}}, "已取消")]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "下单时间",
|
||||
key: "createTime",
|
||||
width: 170,
|
||||
sortable: true,
|
||||
sortType: "desc",
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
orderStatus: [
|
||||
{ title: "全部", value: "" },
|
||||
{ title: "未付款", value: "UNPAID" },
|
||||
{ title: "已付款", value: "PAID" },
|
||||
{ title: "待核验", value: "TAKE" },
|
||||
{ title: "已完成", value: "COMPLETED" },
|
||||
{ title: "已关闭", value: "CANCELLED" },
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
currentStatus: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 核验订单
|
||||
*/
|
||||
async orderVerification() {
|
||||
let result = await verificationCode(this.orderCode);
|
||||
|
||||
if (result.success) {
|
||||
this.$router.push({
|
||||
name: "order-detail",
|
||||
query: { sn: result.result.sn || this.orderCode },
|
||||
});
|
||||
}
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {};
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm.orderType = "VIRTUAL";
|
||||
this.selectDate = null;
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
// 重新加载数据
|
||||
this.getDataList();
|
||||
},
|
||||
// 表格排序
|
||||
changeSort(e) {
|
||||
this.searchForm.sort = e.key;
|
||||
this.searchForm.order = e.order;
|
||||
if (e.order === "normal") {
|
||||
this.searchForm.order = "";
|
||||
}
|
||||
this.searchForm.sort = e.prop;
|
||||
this.searchForm.order = e.order === "ascending" ? "asc" : e.order === "descending" ? "desc" : "";
|
||||
this.getDataList();
|
||||
},
|
||||
// 时间段重新赋值
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
}
|
||||
},
|
||||
// 获取商品列表
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getOrderList(this.searchForm).then((res) => {
|
||||
@@ -250,29 +196,44 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 跳转详情
|
||||
confirmPrice(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认收款",
|
||||
content: "您确定要收款吗?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
API_Order.orderPay(v.sn).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("收款成功");
|
||||
this.getDataList();
|
||||
}
|
||||
this.$Modal.remove();
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
detail(v) {
|
||||
let sn = v.sn;
|
||||
this.$options.filters.customRouterPush({
|
||||
this.$filters.customRouterPush({
|
||||
name: "order-detail",
|
||||
query: { sn: sn },
|
||||
})
|
||||
query: { sn: sn, orderType: v.orderType },
|
||||
});
|
||||
},
|
||||
onStatusTabClick(tab) {
|
||||
const item = tab.paneName;
|
||||
this.currentStatus = item;
|
||||
this.searchForm.orderStatus = item;
|
||||
this.getDataList();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false
|
||||
next()
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
.export {
|
||||
margin: 10px 20px 10px 0;
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-tab {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,52 +1,95 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="订单编号" prop="orderSn">
|
||||
<Input type="text" v-model="searchForm.orderSn" clearable placeholder="请输入订单编号" style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input type="text" v-model="searchForm.memberName" clearable placeholder="请输入会员名称" style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="发票抬头" prop="receiptTitle">
|
||||
<Input type="text" v-model="searchForm.receiptTitle" clearable placeholder="请输入发票抬头" style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="状态" prop="receiptStatus">
|
||||
<Select v-model="searchForm.receiptStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<Option :value="0">未开票</Option>
|
||||
<Option :value="1">已开票</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<el-card>
|
||||
<el-form ref="searchForm" :model="searchForm" inline label-width="70px" class="search-form">
|
||||
<el-form-item label="订单编号" prop="orderSn">
|
||||
<el-input v-model="searchForm.orderSn" clearable placeholder="请输入订单编号" style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input v-model="searchForm.memberName" clearable placeholder="请输入会员名称" style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="发票抬头" prop="receiptTitle">
|
||||
<el-input v-model="searchForm.receiptTitle" clearable placeholder="请输入发票抬头" style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="receiptStatus">
|
||||
<el-select v-model="searchForm.receiptStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="未开票" :value="0" />
|
||||
<el-option label="已开票" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
<el-button class="search-btn" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Card>
|
||||
<div class="receipt-tip">
|
||||
订单状态为已发货/已完成可开票
|
||||
<el-card>
|
||||
<div class="receipt-tip">订单状态为已发货/已完成可开票</div>
|
||||
<el-table ref="table" v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
|
||||
<el-table-column label="订单号" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="$router.push({ name: 'order-detail', query: { sn: row.orderSn } })">
|
||||
{{ row.orderSn }}
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="90" show-overflow-tooltip />
|
||||
<el-table-column label="发票抬头" min-width="90" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.receiptTitle || "暂未填写" }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="纳税人识别号" min-width="100" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.taxpayerId || "暂未填写" }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发票内容" min-width="90" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.receiptContent || "暂未填写" }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发票金额" width="150">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme :value="row.receiptPrice" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发票状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="Number(row.receiptStatus) === 0 ? 'warning' : 'success'">
|
||||
{{ Number(row.receiptStatus) === 0 ? "未开票" : "已开票" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="orderStatusTagType(row.orderStatus)">{{ orderStatusText(row.orderStatus) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" style="margin-right: 12px" @click="openReceiptModal(row, 'detail')">详情</a>
|
||||
<a
|
||||
class="link-text"
|
||||
:class="{ disabled: !canInvoicing(row) }"
|
||||
@click="canInvoicing(row) && openReceiptModal(row, 'invoicing')"
|
||||
>
|
||||
开票
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table">
|
||||
<!-- 订单详情格式化 -->
|
||||
<template slot="orderSlot" slot-scope="scope">
|
||||
<a @click="$router.push({name: 'order-detail',query: {sn: scope.row.orderSn}})">{{scope.row.orderSn}}</a>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small"
|
||||
show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal
|
||||
v-model="receiptModalVisible"
|
||||
title="发票信息"
|
||||
:mask-closable="false"
|
||||
width="680"
|
||||
>
|
||||
<div v-if="receiptDetailLoading" class="receipt-modal-loading">
|
||||
<Spin size="large" />
|
||||
</div>
|
||||
<div v-else class="receipt-modal-content">
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="receiptModalVisible" title="发票信息" :close-on-click-modal="false" width="680px">
|
||||
<div v-loading="receiptDetailLoading" class="receipt-modal-content">
|
||||
<div v-if="hasValue(currentReceipt.orderSn)" class="receipt-item">
|
||||
<span class="receipt-label">订单号:</span>
|
||||
<span class="receipt-value">{{ currentReceipt.orderSn }}</span>
|
||||
@@ -110,39 +153,31 @@
|
||||
<div v-if="hasValue(getInvoiceAddress(currentReceipt))" class="receipt-item">
|
||||
<span class="receipt-label">发票附件:</span>
|
||||
<span class="receipt-value">
|
||||
<a @click="viewInvoiceFile(getInvoiceAddress(currentReceipt))">查看附件</a>
|
||||
<a class="link-text" @click="viewInvoiceFile(getInvoiceAddress(currentReceipt))">查看附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<template #footer>
|
||||
<template v-if="receiptModalMode === 'invoicing'">
|
||||
<Upload
|
||||
<el-upload
|
||||
:action="uploadFileUrl"
|
||||
:data="receiptUploadData"
|
||||
:headers="{ ...accessToken }"
|
||||
:format="['jpg', 'jpeg', 'png', 'pdf']"
|
||||
:max-size="10240"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
:show-file-list="false"
|
||||
:on-success="handleInvoiceUploadSuccess"
|
||||
:on-error="handleInvoiceUploadError"
|
||||
:on-format-error="handleInvoiceFormatError"
|
||||
:on-exceeded-size="handleInvoiceMaxSize"
|
||||
:show-upload-list="false"
|
||||
:before-upload="beforeInvoiceUpload"
|
||||
style="display: inline-block; margin-right: 8px"
|
||||
>
|
||||
<Button :disabled="receiptDetailLoading">上传发票</Button>
|
||||
</Upload>
|
||||
<Button @click="receiptModalVisible = false">取消</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="invoiceSubmitting"
|
||||
@click="submitInvoicing"
|
||||
>
|
||||
确认开票
|
||||
</Button>
|
||||
<el-button :disabled="receiptDetailLoading">上传发票</el-button>
|
||||
</el-upload>
|
||||
<el-button @click="receiptModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="invoiceSubmitting" @click="submitInvoicing">确认开票</el-button>
|
||||
</template>
|
||||
<Button v-else @click="receiptModalVisible = false">关闭</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<el-button v-else @click="receiptModalVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -154,178 +189,61 @@ export default {
|
||||
name: "receipt",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
receiptModalVisible: false,
|
||||
receiptDetailLoading: false,
|
||||
invoiceSubmitting: false,
|
||||
receiptModalMode: "detail",
|
||||
uploadFileUrl: uploadFile,
|
||||
accessToken: {},
|
||||
receiptUploadData: {
|
||||
directoryPath: "receipt"
|
||||
},
|
||||
receiptUploadData: { directoryPath: "receipt" },
|
||||
currentReceipt: {},
|
||||
selectedReceiptRow: null,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
receiptStatus: "", // 发票状态
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
receiptStatus: "",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "订单号",
|
||||
key: "orderSn",
|
||||
minWidth: 120,
|
||||
slot: "orderSlot",
|
||||
},
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 90,
|
||||
tooltip: true,
|
||||
},
|
||||
|
||||
{
|
||||
title: "发票抬头",
|
||||
key: "receiptTitle",
|
||||
minWidth: 90,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("div", params.row.receiptTitle || "暂未填写");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "纳税人识别号",
|
||||
key: "taxpayerId",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("div", params.row.taxpayerId || "暂未填写");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "发票内容",
|
||||
key: "receiptContent",
|
||||
minWidth: 90,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("div", params.row.receiptContent || "暂未填写");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "发票金额",
|
||||
key: "billPrice",
|
||||
width: 150,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.receiptPrice,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "发票状态",
|
||||
key: "receiptStatus",
|
||||
width: 100,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
if (Number(params.row.receiptStatus) === 0) {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "volcano" } }, "未开票"),
|
||||
]);
|
||||
} else {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "green" } }, "已开票"),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "订单状态",
|
||||
key: "orderStatus",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.orderStatus == "UNPAID") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "magenta" } }, "未付款"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "PAID") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "blue" } }, "已付款"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "UNDELIVERED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "geekblue" } }, "待发货"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "DELIVERED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "cyan" } }, "已发货"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "COMPLETED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "green" } }, "已完成"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "TAKE") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "volcano" } }, "待核验"),
|
||||
]);
|
||||
} else if (params.row.orderStatus == "CANCELLED") {
|
||||
return h("div", [
|
||||
h("tag", { props: { color: "red" } }, "已取消"),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: 'right',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
const disabled = !this.canInvoicing(params.row);
|
||||
const detailStyle = { color: "#2d8cf0", cursor: "pointer", textDecoration: "none", marginRight: "12px" };
|
||||
const style = disabled
|
||||
? { color: "#c5c8ce", cursor: "not-allowed", textDecoration: "none" }
|
||||
: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" };
|
||||
const on = disabled ? {} : { click: () => { this.openReceiptModal(params.row, "invoicing"); } };
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: detailStyle,
|
||||
on: { click: () => { this.openReceiptModal(params.row, "detail"); } },
|
||||
},
|
||||
"详情"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style,
|
||||
on,
|
||||
},
|
||||
"开票"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
orderStatusText(status) {
|
||||
const map = {
|
||||
UNPAID: "未付款",
|
||||
PAID: "已付款",
|
||||
UNDELIVERED: "待发货",
|
||||
DELIVERED: "已发货",
|
||||
COMPLETED: "已完成",
|
||||
TAKE: "待核验",
|
||||
CANCELLED: "已取消",
|
||||
};
|
||||
return map[status] || status;
|
||||
},
|
||||
orderStatusTagType(status) {
|
||||
const map = {
|
||||
UNPAID: "danger",
|
||||
PAID: "primary",
|
||||
UNDELIVERED: "",
|
||||
DELIVERED: "info",
|
||||
COMPLETED: "success",
|
||||
TAKE: "warning",
|
||||
CANCELLED: "danger",
|
||||
};
|
||||
return map[status] || "";
|
||||
},
|
||||
canInvoicing(row) {
|
||||
if (!row) return false;
|
||||
const orderStatus = row.orderStatus;
|
||||
const receiptStatus = Number(row.receiptStatus);
|
||||
return (orderStatus === "COMPLETED" || orderStatus === "DELIVERED") && receiptStatus === 0;
|
||||
return (
|
||||
(row.orderStatus === "COMPLETED" || row.orderStatus === "DELIVERED") &&
|
||||
Number(row.receiptStatus) === 0
|
||||
);
|
||||
},
|
||||
initUploadAccessToken() {
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken")
|
||||
};
|
||||
this.accessToken = { accessToken: this.getStore("accessToken") };
|
||||
},
|
||||
hasValue(value) {
|
||||
if (value === null || value === undefined) return false;
|
||||
@@ -334,11 +252,6 @@ export default {
|
||||
hasPrice(value) {
|
||||
return value !== null && value !== undefined && value !== "";
|
||||
},
|
||||
formatValue(value) {
|
||||
if (value === null || value === undefined) return "暂无";
|
||||
const text = String(value).trim();
|
||||
return text ? text : "暂无";
|
||||
},
|
||||
formatPrice(value) {
|
||||
if (value === null || value === undefined || value === "") return "暂无";
|
||||
return `¥${value}`;
|
||||
@@ -354,26 +267,6 @@ export default {
|
||||
if (receiptType === "电子普通发票" || receiptType === "增值税专用发票") return receiptType;
|
||||
return this.isVatSpecialReceipt(receipt) ? "增值税专用发票" : "电子普通发票";
|
||||
},
|
||||
formatReceiptHeaderType(receipt) {
|
||||
if (!receipt) return "暂无";
|
||||
if (this.isVatSpecialReceipt(receipt)) return "单位";
|
||||
if (receipt.companyName) return "单位";
|
||||
if (receipt.personalName) return "个人";
|
||||
const receiptTitle = receipt.receiptTitle != null ? String(receipt.receiptTitle).trim() : "";
|
||||
if (receiptTitle === "单位" || receiptTitle === "个人") return receiptTitle;
|
||||
return receipt.taxpayerId ? "单位" : "个人";
|
||||
},
|
||||
getReceiptTitleLabel(receipt) {
|
||||
return this.formatReceiptHeaderType(receipt) === "单位" ? "单位名称" : "个人名称";
|
||||
},
|
||||
getReceiptTitleName(receipt) {
|
||||
if (!receipt) return "";
|
||||
if (receipt.companyName) return receipt.companyName;
|
||||
if (receipt.personalName) return receipt.personalName;
|
||||
const receiptTitle = receipt.receiptTitle != null ? String(receipt.receiptTitle).trim() : "";
|
||||
if (receiptTitle === "单位" || receiptTitle === "个人") return "";
|
||||
return receiptTitle;
|
||||
},
|
||||
getInvoiceAddress(receipt) {
|
||||
if (!receipt) return "";
|
||||
return receipt.invoiceAddress || receipt.invoiceFileUrl || "";
|
||||
@@ -382,11 +275,24 @@ export default {
|
||||
const invoiceAddress = this.getInvoiceAddress(this.currentReceipt);
|
||||
return invoiceAddress ? { invoiceAddress } : {};
|
||||
},
|
||||
beforeInvoiceUpload(file) {
|
||||
const allowed = ["image/jpeg", "image/jpg", "image/png", "application/pdf"];
|
||||
const okType = allowed.includes(file.type) || /\.(jpg|jpeg|png|pdf)$/i.test(file.name);
|
||||
if (!okType) {
|
||||
this.$Message.warning("请上传 jpg、jpeg、png 或 pdf 格式文件");
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 10) {
|
||||
this.$Message.warning("发票附件不能超过 10MB");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
handleInvoiceUploadSuccess(res) {
|
||||
if (res && res.success && res.result) {
|
||||
this.$set(this.currentReceipt, "invoiceAddress", res.result);
|
||||
this.currentReceipt.invoiceAddress = res.result;
|
||||
if (this.selectedReceiptRow) {
|
||||
this.$set(this.selectedReceiptRow, "invoiceAddress", res.result);
|
||||
this.selectedReceiptRow.invoiceAddress = res.result;
|
||||
}
|
||||
this.$Message.success("发票上传成功");
|
||||
} else {
|
||||
@@ -396,57 +302,35 @@ export default {
|
||||
handleInvoiceUploadError() {
|
||||
this.$Message.error("发票上传失败");
|
||||
},
|
||||
handleInvoiceFormatError() {
|
||||
this.$Notice.warning({
|
||||
title: "文件格式不正确",
|
||||
desc: "请上传 jpg、jpeg、png 或 pdf 格式文件"
|
||||
});
|
||||
},
|
||||
handleInvoiceMaxSize() {
|
||||
this.$Notice.warning({
|
||||
title: "超过文件大小限制",
|
||||
desc: "发票附件不能超过 10MB"
|
||||
});
|
||||
},
|
||||
viewInvoiceFile(url) {
|
||||
if (!url) return;
|
||||
window.open(url, "_blank");
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getData();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getData();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getData();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getData();
|
||||
},
|
||||
// 重置搜索条件
|
||||
handleReset() {
|
||||
this.searchForm = {};
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
receiptStatus: "",
|
||||
};
|
||||
this.getData();
|
||||
},
|
||||
// 时间段从新赋值
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
}
|
||||
},
|
||||
// 获取数据
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Order.getReceiptPage(this.searchForm).then((res) => {
|
||||
@@ -456,8 +340,6 @@ export default {
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
async openReceiptModal(row, mode = "detail") {
|
||||
if (!row) return;
|
||||
@@ -512,16 +394,8 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
|
||||
.receipt-modal-loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 240px;
|
||||
}
|
||||
|
||||
.receipt-modal-content {
|
||||
max-height: 460px;
|
||||
overflow-y: auto;
|
||||
@@ -554,4 +428,14 @@ export default {
|
||||
color: #17233d;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.link-text.disabled {
|
||||
color: #c5c8ce;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,166 +1,103 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<Card>
|
||||
<Form ref="form" :model="form" :label-width="120" :rules="formRule">
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form ref="form" :model="form" label-width="120px" :rules="formRule">
|
||||
<div class="base-info-item">
|
||||
<h4>基本信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="活动名称" prop="promotionName">
|
||||
<Input
|
||||
<el-form-item label="活动名称" prop="promotionName">
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
type="text"
|
||||
v-model="form.promotionName"
|
||||
placeholder="活动名称"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="优惠券名称" prop="couponName">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="优惠券名称" prop="couponName">
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
type="text"
|
||||
v-model="form.couponName"
|
||||
placeholder="优惠券名称"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="优惠券类型" prop="couponType">
|
||||
<Select :disabled="disabled" v-model="form.couponType" style="width: 260px">
|
||||
<Option value="DISCOUNT">打折</Option>
|
||||
<Option value="PRICE">减免现金</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label="折扣" prop="discount" v-if="form.couponType == 'DISCOUNT'">
|
||||
<InputNumber
|
||||
</el-form-item>
|
||||
<el-form-item label="优惠券类型" prop="couponType">
|
||||
<el-select :disabled="disabled" v-model="form.couponType" style="width: 260px">
|
||||
<el-option label="打折" value="DISCOUNT" />
|
||||
<el-option label="减免现金" value="PRICE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="折扣"
|
||||
prop="couponDiscount"
|
||||
v-if="form.couponType == 'DISCOUNT'"
|
||||
>
|
||||
<el-input-number
|
||||
:disabled="disabled"
|
||||
placeholder="折扣"
|
||||
:max="9.9"
|
||||
:min="0.1"
|
||||
:step="0.1"
|
||||
precision="1"
|
||||
:precision="1"
|
||||
v-model="form.couponDiscount"
|
||||
style="width: 260px"/>
|
||||
style="width: 260px"
|
||||
/>
|
||||
<span class="describe">请输入0-10的数字,可有一位小数</span>
|
||||
</FormItem>
|
||||
<FormItem label="面额" prop="price" v-if="form.couponType == 'PRICE'">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="面额" prop="price" v-if="form.couponType == 'PRICE'">
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
type="text"
|
||||
v-model="form.price"
|
||||
placeholder="面额"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="活动类型" prop="getType">
|
||||
<Select :disabled="disabled" v-model="form.getType" style="width: 260px">
|
||||
<Option value="FREE">免费领取</Option>
|
||||
<Option value="ACTIVITY">活动赠送</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动类型" prop="getType">
|
||||
<el-select :disabled="disabled" v-model="form.getType" style="width: 260px">
|
||||
<el-option label="免费领取" value="FREE" />
|
||||
<el-option label="活动赠送" value="ACTIVITY" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<FormItem label="发放数量" v-if="form.getType == 'FREE'" prop="publishNum">
|
||||
<Input
|
||||
<el-form-item label="店铺承担比例" prop="storeCommission">
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
v-model="form.storeCommission"
|
||||
placeholder="店铺承担比例"
|
||||
style="width: 260px"
|
||||
>
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
<span class="describe">店铺承担比例,输入0-100之间数值</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="发放数量" prop="publishNum" v-if="form.getType === 'FREE'">
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
v-model="form.publishNum"
|
||||
placeholder="发放数量"
|
||||
style="width: 260px"
|
||||
/>
|
||||
<span class="tips ml_10">如果发放数量为0时,则代表不限制发放数量</span>
|
||||
</FormItem>
|
||||
</div>
|
||||
<h4>使用限制</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="消费门槛" prop="consumeThreshold">
|
||||
<Input
|
||||
:disabled="disabled"
|
||||
type="text"
|
||||
v-model="form.consumeThreshold"
|
||||
placeholder="消费门槛"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="领取限制"
|
||||
v-if="form.getType == 'FREE'"
|
||||
<div class="tips">如果发放数量为0时,则代表不限制发放数量</div>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="领取数量限制"
|
||||
prop="couponLimitNum"
|
||||
v-if="form.getType === 'FREE'"
|
||||
>
|
||||
<Input
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
v-model="form.couponLimitNum"
|
||||
placeholder="领取限制"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
<span class="tips ml_10">如果领取限制为0时,则代表不限制领取数量</span>
|
||||
</FormItem>
|
||||
<FormItem label="有效期" prop="rangeTime">
|
||||
<DatePicker
|
||||
:disabled="disabled"
|
||||
type="datetimerange"
|
||||
v-model="form.rangeTime"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="请选择"
|
||||
:options="options"
|
||||
style="width: 260px"
|
||||
>
|
||||
</DatePicker>
|
||||
</FormItem>
|
||||
<FormItem label="使用范围" prop="scopeType">
|
||||
<RadioGroup type="button" button-style="solid" v-model="form.scopeType">
|
||||
<Radio :disabled="disabled" label="ALL">全品类</Radio>
|
||||
<Radio :disabled="disabled" label="PORTION_GOODS">指定商品</Radio>
|
||||
<Radio :disabled="disabled" label="PORTION_GOODS_CATEGORY">部分商品分类</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
|
||||
<FormItem style="width: 100%" v-if="form.scopeType == 'PORTION_GOODS'">
|
||||
<div style="display: flex; margin-bottom: 10px">
|
||||
<Button :disabled="disabled" type="primary" @click="openSkuList"
|
||||
>选择商品</Button
|
||||
>
|
||||
<Button
|
||||
:disabled="disabled"
|
||||
type="error"
|
||||
ghost
|
||||
style="margin-left: 10px"
|
||||
@click="delSelectGoods"
|
||||
>批量删除</Button
|
||||
>
|
||||
</div>
|
||||
<Table
|
||||
class="mt_10"
|
||||
:disabled="disabled"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="form.promotionGoodsList"
|
||||
@on-selection-change="changeSelect"
|
||||
>
|
||||
<template slot-scope="{ row }" slot="QRCode">
|
||||
<img
|
||||
:src="row.QRCode || '../../../assets/lili.png'"
|
||||
width="50px"
|
||||
height="50px"
|
||||
alt=""
|
||||
/>
|
||||
</template>
|
||||
</Table>
|
||||
</FormItem>
|
||||
|
||||
<FormItem v-if="form.scopeType == 'PORTION_GOODS_CATEGORY'">
|
||||
<Cascader
|
||||
:disabled="disabled"
|
||||
@on-change="getGoodsCategory"
|
||||
:data="goodsCategoryList"
|
||||
style="width: 300px"
|
||||
v-model="form.scopeIdGoods"
|
||||
></Cascader>
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="范围描述" prop="description">
|
||||
<Input
|
||||
<div class="tips">如果领取数量为0时,则代表不限制领取数量</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="范围描述" prop="description">
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
@@ -170,40 +107,168 @@
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</FormItem>
|
||||
<div>
|
||||
<Button
|
||||
</el-form-item>
|
||||
</div>
|
||||
<h4>使用限制</h4>
|
||||
<div class="form-item-view">
|
||||
<el-form-item label="消费门槛" prop="consumeThreshold">
|
||||
<el-input
|
||||
:disabled="disabled"
|
||||
type="text"
|
||||
@click="$router.push({ name: 'coupon' })"
|
||||
>返回</Button
|
||||
v-model="form.consumeThreshold"
|
||||
placeholder="消费门槛"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="有效期" prop="rangeTime">
|
||||
<div v-if="form.getType == 'ACTIVITY'">
|
||||
<el-radio-group v-model="rangeTimeType">
|
||||
<el-radio :disabled="disabled" :value="1" v-if="form.getType !== 'ACTIVITY'">起止时间</el-radio>
|
||||
<el-radio :disabled="disabled" :value="0">固定时间</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div v-if="rangeTimeType == 1">
|
||||
<el-date-picker
|
||||
:disabled="disabled"
|
||||
type="datetimerange"
|
||||
v-model="form.rangeTime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
:disabled-date="options.disabledDate"
|
||||
style="width: 260px"
|
||||
/>
|
||||
</div>
|
||||
<div class="effectiveDays" v-if="rangeTimeType == 0">
|
||||
领取当天开始
|
||||
<el-input-number
|
||||
:disabled="disabled"
|
||||
v-model="form.effectiveDays"
|
||||
:min="1"
|
||||
style="width: 100px"
|
||||
:max="365"
|
||||
/>
|
||||
天内有效(1-365间的整数)
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="使用范围" prop="scopeType">
|
||||
<el-radio-group v-model="form.scopeType">
|
||||
<el-radio-button :disabled="disabled" value="ALL">全品类</el-radio-button>
|
||||
<el-radio-button :disabled="disabled" value="PORTION_GOODS">指定商品</el-radio-button>
|
||||
<el-radio-button :disabled="disabled" value="PORTION_GOODS_CATEGORY">部分商品分类</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item style="width: 100%" v-if="form.scopeType == 'PORTION_GOODS'">
|
||||
<div style="display: flex; margin-bottom: 10px">
|
||||
<el-button :disabled="disabled" type="primary" @click="openSkuList">选择商品</el-button>
|
||||
<el-button
|
||||
:disabled="disabled"
|
||||
type="danger"
|
||||
plain
|
||||
style="margin-left: 10px"
|
||||
@click="delSelectGoods"
|
||||
>批量删除</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
border
|
||||
:data="form.promotionGoodsList"
|
||||
style="width: 100%"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
<Button
|
||||
<el-table-column type="selection" width="60" align="center" />
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="商品价格" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" width="90">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.quantity }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template #default="{ $index }">
|
||||
<el-button
|
||||
:disabled="disabled"
|
||||
type="danger"
|
||||
size="small"
|
||||
plain
|
||||
@click="delGoods($index)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.scopeType == 'PORTION_GOODS_CATEGORY'">
|
||||
<el-cascader
|
||||
:disabled="disabled"
|
||||
:options="goodsCategoryList"
|
||||
style="width: 260px"
|
||||
v-model="form.scopeIdGoods"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div>
|
||||
<el-button :disabled="disabled" link @click="closeCurrentPage">返回</el-button>
|
||||
<el-button
|
||||
:disabled="disabled"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="handleSubmit"
|
||||
>提交</Button
|
||||
>
|
||||
>提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<sku-select ref="skuSelect" @selectedGoodsData="selectedGoodsData"></sku-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { saveShopCoupon, getShopCoupon, editShopCoupon } from "@/api/promotion";
|
||||
import {
|
||||
savePlatformCoupon,
|
||||
getPlatformCoupon,
|
||||
editPlatformCoupon,
|
||||
} from "@/api/promotion";
|
||||
import { getGoodsCategoryAll } from "@/api/goods";
|
||||
import { regular } from "@/utils";
|
||||
import skuSelect from "@/views/lili-dialog";
|
||||
|
||||
export default {
|
||||
name: "addCoupon",
|
||||
name: "edit-platform-coupon",
|
||||
components: {
|
||||
skuSelect,
|
||||
},
|
||||
watch: {
|
||||
"form.getType": {
|
||||
handler(val) {
|
||||
if (val == "FREE") {
|
||||
this.rangeTimeType = 1;
|
||||
} else {
|
||||
this.rangeTimeType = 0;
|
||||
}
|
||||
if (this.rangeTimeType == 0) {
|
||||
delete this.formRule.rangeTime;
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
$route(e) {
|
||||
this.id = e.query.id;
|
||||
if (this.id) {
|
||||
this.getCoupon();
|
||||
} else {
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const checkPrice = (rule, value, callback) => {
|
||||
if (!value && value !== 0) {
|
||||
@@ -227,41 +292,37 @@ export default {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
modalType: 0, // 判断是新增还是编辑优惠券 0 新增 1 编辑
|
||||
disabled: this.$route.query.onlyView,
|
||||
rangeTimeType: 1,
|
||||
modalType: 0,
|
||||
form: {
|
||||
/** 店铺承担比例 */
|
||||
sellerCommission: 0,
|
||||
/** 发行数量 */
|
||||
publishNum: 1,
|
||||
/** 运费承担者 */
|
||||
storeCommission: 0,
|
||||
publishNum: 0,
|
||||
scopeType: "ALL",
|
||||
/** 限领数量 */
|
||||
couponLimitNum: 1,
|
||||
/** 活动类型 */
|
||||
couponType: "PRICE",
|
||||
/** 优惠券名称 */
|
||||
couponName: "",
|
||||
promotionName: "",
|
||||
getType: "FREE",
|
||||
promotionGoodsList: [],
|
||||
scopeIdGoods: [],
|
||||
rangeDayType: "FIXEDTIME",
|
||||
rangeDayType: "",
|
||||
effectiveDays: 1,
|
||||
},
|
||||
id: this.$route.query.id,
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
selectedGoods: [], // 已选商品列表,便于删除
|
||||
goodsCategoryList: [], // 商品分类列表
|
||||
submitLoading: false,
|
||||
selectedGoods: [],
|
||||
goodsCategoryList: [],
|
||||
formRule: {
|
||||
promotionName: [{ required: true, message: "活动名称不能为空" }],
|
||||
couponName: [{ required: true, message: "优惠券名称不能为空" }],
|
||||
price: [{ required: true, message: "请输入面额" }, { validator: checkPrice }],
|
||||
rangeTime: [{ required: true, message: "请选择优惠券有效期" }],
|
||||
consumeThreshold: [
|
||||
{ required: true, message: "请输入消费门槛" },
|
||||
{ validator: checkWeight },
|
||||
],
|
||||
rangeTime: [{ required: true, message: "请选择优惠券有效期" }],
|
||||
couponDiscount: [
|
||||
{ required: true, message: "请输入折扣" },
|
||||
{
|
||||
@@ -269,7 +330,7 @@ export default {
|
||||
message: "请输入0-10的数字,可有一位小数",
|
||||
},
|
||||
],
|
||||
sellerCommission: [
|
||||
storeCommission: [
|
||||
{ required: true, message: "请输入店铺承担比例" },
|
||||
{ pattern: regular.rate, message: "请输入0-100的正整数" },
|
||||
],
|
||||
@@ -278,65 +339,11 @@ export default {
|
||||
{ pattern: regular.Integer, message: "请输入正整数" },
|
||||
],
|
||||
couponLimitNum: [
|
||||
{ required: true, message: "请输入领取限制" },
|
||||
{ required: true, message: "领取限制不能为空" },
|
||||
{ pattern: regular.Integer, message: "请输入正整数" },
|
||||
],
|
||||
description: [{ required: true, message: "请输入范围描述" }],
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "商品价格",
|
||||
key: "price",
|
||||
minWidth: 40,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
minWidth: 40,
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
minWidth: 50,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
if (this.disabled) {
|
||||
return h("div");
|
||||
}
|
||||
return h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.delGoods(params.index);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
// 时间选择器可选范围
|
||||
options: {
|
||||
disabledDate(date) {
|
||||
return date && date.valueOf() < Date.now() - 86400000;
|
||||
@@ -346,18 +353,17 @@ export default {
|
||||
},
|
||||
async mounted() {
|
||||
await this.getCagetoryList();
|
||||
// 如果id不为空则查询信息
|
||||
if (this.id) {
|
||||
this.getCoupon();
|
||||
this.modalType = 1;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取回显数据
|
||||
getCoupon() {
|
||||
getShopCoupon(this.id).then((res) => {
|
||||
getPlatformCoupon(this.id).then((res) => {
|
||||
let data = res.result;
|
||||
if (!data.promotionGoodsList) data.promotionGoodsList = [];
|
||||
this.rangeTimeType = data.rangeDayType === "DYNAMICTIME" ? 0 : 1;
|
||||
if (data.scopeType == "PORTION_GOODS_CATEGORY") {
|
||||
let prevCascader = data.scopeId.split(",");
|
||||
function next(params, prev) {
|
||||
@@ -381,6 +387,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next(this.goodsCategoryList, []);
|
||||
data.scopeIdGoods = prevCascader;
|
||||
}
|
||||
@@ -391,23 +398,27 @@ export default {
|
||||
this.form = data;
|
||||
});
|
||||
},
|
||||
/** 保存优惠券 */
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
const params = JSON.parse(JSON.stringify(this.form));
|
||||
params.startTime = this.$options.filters.unixToDate(
|
||||
this.form.rangeTime[0] / 1000
|
||||
);
|
||||
params.endTime = this.$options.filters.unixToDate(
|
||||
this.form.rangeTime[1] / 1000
|
||||
);
|
||||
if (params.getType == "ACTIVITY") {
|
||||
params.couponLimitNum = 0;
|
||||
params.publishNum = 0;
|
||||
params.getType != "ACTIVITY" ? delete params.effectiveDays : "";
|
||||
|
||||
if (this.rangeTimeType == 1) {
|
||||
params.rangeDayType = "FIXEDTIME";
|
||||
const rangeTime = this.form.rangeTime;
|
||||
const start = rangeTime[0] instanceof Date ? rangeTime[0] : new Date(rangeTime[0]);
|
||||
const end = rangeTime[1] instanceof Date ? rangeTime[1] : new Date(rangeTime[1]);
|
||||
params.startTime = this.$filters.unixToDate(start.getTime() / 1000);
|
||||
params.endTime = this.$filters.unixToDate(end.getTime() / 1000);
|
||||
delete params.effectiveDays;
|
||||
} else {
|
||||
params.rangeDayType = "DYNAMICTIME";
|
||||
delete params.rangeTime;
|
||||
}
|
||||
delete params.rangeTime;
|
||||
|
||||
let scopeId = [];
|
||||
|
||||
if (
|
||||
params.scopeType == "PORTION_GOODS" &&
|
||||
(!params.promotionGoodsList || params.promotionGoodsList.length == 0)
|
||||
@@ -425,7 +436,6 @@ export default {
|
||||
}
|
||||
|
||||
if (params.scopeType == "PORTION_GOODS") {
|
||||
//指定商品
|
||||
params.promotionGoodsList.forEach((item) => {
|
||||
scopeId.push(item.skuId);
|
||||
});
|
||||
@@ -433,7 +443,6 @@ export default {
|
||||
} else if (params.scopeType == "ALL") {
|
||||
delete params.promotionGoodsList;
|
||||
} else if (params.scopeType == "PORTION_GOODS_CATEGORY") {
|
||||
//部分商品分类
|
||||
scopeId = this.filterCategoryId(params.scopeIdGoods, []);
|
||||
params.scopeId = scopeId.toString();
|
||||
delete params.promotionGoodsList;
|
||||
@@ -442,9 +451,9 @@ export default {
|
||||
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete params.id;
|
||||
saveShopCoupon(params).then((res) => {
|
||||
|
||||
savePlatformCoupon(params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("优惠券发送成功");
|
||||
@@ -452,11 +461,10 @@ export default {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
delete params.consumeLimit;
|
||||
delete params.updateTime;
|
||||
|
||||
editShopCoupon(params).then((res) => {
|
||||
editPlatformCoupon(params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("优惠券修改成功");
|
||||
@@ -467,18 +475,12 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 关闭当前页面
|
||||
closeCurrentPage() {
|
||||
this.$store.commit("removeTag", "add-coupon");
|
||||
localStorage.storeOpenedList = JSON.stringify(
|
||||
this.$store.state.app.storeOpenedList
|
||||
);
|
||||
this.$router.push({
|
||||
name: "coupon",
|
||||
});
|
||||
this.$store.commit("removeTag", "add-platform-coupon");
|
||||
localStorage.pageOpenedList = JSON.stringify(this.$store.state.app.pageOpenedList);
|
||||
this.$router.go(-1);
|
||||
},
|
||||
openSkuList() {
|
||||
// 显示商品选择器
|
||||
this.$refs.skuSelect.open("goods");
|
||||
let data = JSON.parse(JSON.stringify(this.form.promotionGoodsList));
|
||||
data.forEach((e) => {
|
||||
@@ -487,11 +489,9 @@ export default {
|
||||
this.$refs.skuSelect.goodsData = data;
|
||||
},
|
||||
changeSelect(e) {
|
||||
// 已选商品批量选择
|
||||
this.selectedGoods = e;
|
||||
},
|
||||
delSelectGoods() {
|
||||
// 多选删除商品
|
||||
if (this.selectedGoods.length <= 0) {
|
||||
this.$Message.warning("您还未选择要删除的数据");
|
||||
return;
|
||||
@@ -502,20 +502,19 @@ export default {
|
||||
onOk: () => {
|
||||
let ids = [];
|
||||
this.selectedGoods.forEach(function (e) {
|
||||
ids.push(e.id);
|
||||
ids.push(e.skuId);
|
||||
});
|
||||
|
||||
this.form.promotionGoodsList = this.form.promotionGoodsList.filter((item) => {
|
||||
return !ids.includes(item.id);
|
||||
return !ids.includes(item.skuId);
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
delGoods(index) {
|
||||
// 删除商品
|
||||
this.form.promotionGoodsList.splice(index, 1);
|
||||
},
|
||||
selectedGoodsData(item) {
|
||||
// 回显已选商品
|
||||
let list = [];
|
||||
item.forEach((e) => {
|
||||
list.push({
|
||||
@@ -524,22 +523,20 @@ export default {
|
||||
originalPrice: e.price,
|
||||
quantity: e.quantity,
|
||||
storeId: e.storeId,
|
||||
sellerName: e.sellerName,
|
||||
storeName: e.storeName,
|
||||
skuId: e.id,
|
||||
categoryPath: e.categoryPath,
|
||||
thumbnail: e.small,
|
||||
goodsType: e.goodsType,
|
||||
goodsId: e.goodsId,
|
||||
originPrice: e.price,
|
||||
});
|
||||
});
|
||||
this.form.promotionGoodsList = list;
|
||||
},
|
||||
getGoodsCategory(e) {
|
||||
// 获取级联选择器商品分类id
|
||||
},
|
||||
|
||||
async getCagetoryList() {
|
||||
// 获取全部商品分类
|
||||
let data = await getGoodsCategoryAll();
|
||||
this.goodsCategoryList = this.filterCategory(data.result);
|
||||
// 过滤出可显示的值
|
||||
|
||||
let data = await getCategoryTree();
|
||||
this.goodsCategoryList = data.result;
|
||||
this.goodsCategoryList = this.goodsCategoryList.map((item) => {
|
||||
if (item.children) {
|
||||
item.children = item.children.map((child) => {
|
||||
@@ -566,19 +563,7 @@ export default {
|
||||
return { value: item.id, label: item.name, children: item.children };
|
||||
});
|
||||
},
|
||||
filterCategory(list) {
|
||||
// 递归删除空children
|
||||
list.forEach((item) => {
|
||||
if (item.children.length == 0) {
|
||||
delete item.children;
|
||||
} else {
|
||||
this.filterCategory(item.children);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
},
|
||||
filterCategoryId(list, idArr) {
|
||||
// 递归获取分类id
|
||||
list.forEach((e) => {
|
||||
if (e instanceof Array) {
|
||||
this.filterCategoryId(e, idArr);
|
||||
@@ -604,16 +589,20 @@ h4 {
|
||||
line-height: 40px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.describe {
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
color: #999;
|
||||
}
|
||||
.ivu-form-item {
|
||||
margin-bottom: 24px !important;
|
||||
}
|
||||
.wrapper {
|
||||
min-height: 1000px;
|
||||
|
||||
.effectiveDays {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
|
||||
> * {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
.tips {
|
||||
font-size: 12px;
|
||||
|
||||
@@ -1,219 +1,190 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Button style="margin-bottom: 10px" @click="back()">返回</Button>
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="75"
|
||||
class="search-form mb_10"
|
||||
>
|
||||
<Form-item label="优惠券名称" prop="couponName">
|
||||
<Input
|
||||
type="text"
|
||||
<el-button style="margin-bottom: 10px" @click="back()">返回</el-button>
|
||||
|
||||
<el-card>
|
||||
<el-form ref="searchForm" :model="searchForm" inline label-width="75px" class="search-form mb_10">
|
||||
<el-form-item label="优惠券名称" prop="couponName">
|
||||
<el-input
|
||||
v-model="searchForm.couponName"
|
||||
placeholder="请输入优惠券名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="优惠券状态" prop="memberCouponStatus">
|
||||
<Select
|
||||
v-model="searchForm.memberCouponStatus"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="NEW">已领取</Option>
|
||||
<Option value="USED">已使用</Option>
|
||||
<Option value="EXPIRE">已过期</Option>
|
||||
<Option value="CLOSED">已作废</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="活动时间">
|
||||
<DatePicker
|
||||
</el-form-item>
|
||||
<el-form-item label="获取方式" prop="getType">
|
||||
<el-select v-model="searchForm.getType" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="免费获取" value="FREE" />
|
||||
<el-option label="活动获取" value="ACTIVITY" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="优惠券状态" prop="memberCouponStatus">
|
||||
<el-select v-model="searchForm.memberCouponStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="已领取" value="NEW" />
|
||||
<el-option label="已使用" value="USED" />
|
||||
<el-option label="已过期" value="EXPIRE" />
|
||||
<el-option label="已作废" value="CLOSED" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="daterange"
|
||||
clearable
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
type="primary"
|
||||
icon="ios-search"
|
||||
class="search-btn"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
v-if="refreshTable"
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
@on-selection-change="changeSelect"
|
||||
style="width: 100%"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="130" fixed="left" />
|
||||
<el-table-column prop="couponName" label="优惠券名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="发布店铺" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ (row.storeName === "platform" && "平台") || row.storeName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="面额/折扣" width="100">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme
|
||||
v-if="row && row.price"
|
||||
:value="row.price"
|
||||
:color="$mainColor"
|
||||
/>
|
||||
<span v-else-if="row">{{ row.discount }}折</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="consumeThreshold" label="使用门槛" width="130" />
|
||||
<el-table-column label="获取方式" width="120">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-if="row.getType === 'FREE'" type="danger">免费获取</el-tag>
|
||||
<el-tag v-else-if="row.getType === 'ACTIVITY'" type="warning">活动获取</el-tag>
|
||||
<el-tag v-else-if="row.getType === 'INSIDE'" type="success">内购</el-tag>
|
||||
<el-tag v-else>未知</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会员优惠券状态" width="130">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-if="row.memberCouponStatus == 'NEW'" type="primary">已领取</el-tag>
|
||||
<el-tag v-else-if="row.memberCouponStatus == 'USED'" type="success">已使用</el-tag>
|
||||
<el-tag v-else-if="row.memberCouponStatus == 'EXPIRE'" type="danger">已过期</el-tag>
|
||||
<el-tag v-else-if="row.memberCouponStatus == 'CLOSED'" type="info">已作废</el-tag>
|
||||
<el-tag v-else type="danger">未知</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="优惠券类型" width="120">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-if="row.couponType === 'DISCOUNT'" type="warning">打折</el-tag>
|
||||
<el-tag v-else-if="row.couponType === 'PRICE'" type="danger">减免现金</el-tag>
|
||||
<el-tag v-else>未知</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="品类描述" width="120">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-if="row.scopeType == 'ALL'">全品类</el-tag>
|
||||
<el-tag v-else-if="row.scopeType == 'PORTION_GOODS_CATEGORY'" type="warning">商品分类</el-tag>
|
||||
<el-tag v-else-if="row.scopeType == 'PORTION_SHOP_CATEGORY'" type="danger">店铺分类</el-tag>
|
||||
<el-tag v-else-if="row.scopeType == 'PORTION_GOODS'" type="danger">指定商品</el-tag>
|
||||
<el-tag v-else type="danger">未知</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="有效时间" width="150">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<span v-if="row.getType === 'ACTIVITY' && row.rangeDayType === 'DYNAMICTIME'">长期有效</span>
|
||||
<div v-else-if="row.startTime && row.endTime">
|
||||
{{ row.startTime }}<br />{{ row.endTime }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[10, 20, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCouponReceiveList } from "@/api/promotion";
|
||||
import {
|
||||
memberPromotionsStatusRender,
|
||||
promotionsScopeTypeRender,
|
||||
} from "@/utils/promotions";
|
||||
|
||||
export default {
|
||||
name: "coupon-recevie",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
getType: "", // 默认排序方式
|
||||
couponId: this.$route.query.couponId, // 优惠券id
|
||||
},
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
fixed: "left",
|
||||
},
|
||||
{
|
||||
title: "优惠券名称",
|
||||
key: "couponName",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "面额/折扣",
|
||||
key: "price",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.price) {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
} else {
|
||||
return h("div", params.row.discount + "折");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "使用门槛",
|
||||
key: "consumeThreshold",
|
||||
width: 130,
|
||||
},
|
||||
{
|
||||
title: "会员优惠券状态",
|
||||
width: 130,
|
||||
key: "memberCouponStatus",
|
||||
render: (h, params) => {
|
||||
return memberPromotionsStatusRender(
|
||||
h,
|
||||
params.row.memberCouponStatus
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "优惠券类型",
|
||||
key: "couponType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.couponType === "DISCOUNT") {
|
||||
return h("Tag", { props: { color: "orange" } }, "打折");
|
||||
} else if (params.row.couponType === "PRICE") {
|
||||
return h("Tag", { props: { color: "magenta" } }, "减免现金");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "purple" } }, "未知");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "品类描述",
|
||||
key: "scopeType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
return promotionsScopeTypeRender(h, params);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "有效时间",
|
||||
width: 150,
|
||||
render: (h, params) => {
|
||||
if (
|
||||
params?.row?.getType === "ACTIVITY" &&
|
||||
params?.row?.rangeDayType === "DYNAMICTIME"
|
||||
) {
|
||||
return h("div", "长期有效");
|
||||
} else if (params?.row?.startTime && params?.row?.endTime) {
|
||||
return h("div", {
|
||||
domProps: {
|
||||
innerHTML:
|
||||
params.row.startTime + "<br/>" + params.row.endTime,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
refreshTable: true, // 修改选中状态后刷新表格
|
||||
selectDate: [], //选中的信息
|
||||
};
|
||||
},
|
||||
props: {
|
||||
promotionStatus: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
getType: "",
|
||||
couponId: this.$route.query.couponId,
|
||||
},
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
data: [],
|
||||
total: 0,
|
||||
refreshTable: true,
|
||||
selectDate: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route(e) {
|
||||
// 监听路由,参数变化调取接口
|
||||
this.searchForm.couponId = e.query.couponId;
|
||||
if (this.couponId) {
|
||||
this.getDataList();
|
||||
} else {
|
||||
this.$refs.form.resetFields();
|
||||
this.$refs.searchForm?.resetFields();
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -223,40 +194,29 @@ export default {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
check() {
|
||||
// 选中的优惠券
|
||||
this.$emit("selected", this.selectList);
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
// 改变页码
|
||||
this.searchForm.pageNumber = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
// 改变页数
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
// 搜索
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
/**
|
||||
* 选择优惠券
|
||||
*/
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
if (this.getType === "ACTIVITY") this.check();
|
||||
},
|
||||
getDataList() {
|
||||
// 获取数据
|
||||
this.loading = true;
|
||||
if (this.selectDate && this.selectDate[0] && this.selectDate[1]) {
|
||||
this.searchForm.startTime = this.selectDate[0].getTime();
|
||||
@@ -268,13 +228,10 @@ export default {
|
||||
getCouponReceiveList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -1,249 +1,330 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row>
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="100"
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="优惠券名称">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.couponName"
|
||||
placeholder="请输入优惠券名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="活动状态" prop="promotionStatus">
|
||||
<Select
|
||||
v-model="searchForm.promotionStatus"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="NEW">未开始</Option>
|
||||
<Option value="START">已开始/上架</Option>
|
||||
<Option value="END">已结束/下架</Option>
|
||||
<Option value="CLOSE">紧急关闭/作废</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="活动时间">
|
||||
<DatePicker
|
||||
v-model="selectDate"
|
||||
type="daterange"
|
||||
clearable
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
type="primary"
|
||||
class="search-btn"
|
||||
icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operator padding-row">
|
||||
<Button @click="add" type="primary">添加</Button>
|
||||
<Button @click="delAll" class="ml_10">批量关闭</Button>
|
||||
<Button @click="receivePage()" class="ml_10" type="info">优惠券领取记录</Button>
|
||||
</Row>
|
||||
<Table
|
||||
class="mt_10"
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
@on-selection-change="changeSelect"
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="90px"
|
||||
class="search-form mb_10"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<template slot-scope="{ row }" slot="action">
|
||||
<a
|
||||
v-if="row.promotionStatus === 'NEW' || row.promotionStatus === 'CLOSE'"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="see(row)"
|
||||
>编辑</a>
|
||||
<a
|
||||
v-else
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="see(row, 'only')"
|
||||
>查看</a>
|
||||
<span style="margin: 0 8px; color: #dcdee2">|</span>
|
||||
<a
|
||||
v-if="row.promotionStatus === 'START' || row.promotionStatus === 'NEW'"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="remove(row)"
|
||||
>关闭</a>
|
||||
<span
|
||||
v-if="row.promotionStatus === 'START' || row.promotionStatus === 'NEW'"
|
||||
style="margin: 0 8px; color: #dcdee2"
|
||||
>|</span>
|
||||
<a
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="receivePage(row.id)"
|
||||
>领取记录</a>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-form-item label="优惠券名称" prop="couponName">
|
||||
<el-input
|
||||
v-model="searchForm.couponName"
|
||||
placeholder="请输入优惠券名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="获取方式" prop="getType">
|
||||
<el-select v-model="searchForm.getType" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="免费获取" value="FREE" />
|
||||
<el-option label="活动获取" value="ACTIVITY" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动状态" prop="promotionStatus">
|
||||
<el-select
|
||||
v-model="searchForm.promotionStatus"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option label="未开始" value="NEW" />
|
||||
<el-option label="已开始/上架" value="START" />
|
||||
<el-option label="已结束/下架" value="END" />
|
||||
<el-option label="紧急关闭/作废" value="CLOSE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="daterange"
|
||||
clearable
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<div class="operation padding-row" v-if="getType !== 'ACTIVITY'">
|
||||
<el-button type="primary" @click="add">添加优惠券</el-button>
|
||||
<el-button @click="delAll">批量关闭</el-button>
|
||||
<el-button type="info" @click="receivePage()">优惠券领取记录</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
row-key="id"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
<el-table-column type="selection" width="52" align="center" />
|
||||
<el-table-column prop="couponName" label="优惠券名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="面额/折扣" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">
|
||||
<span v-if="row.price" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
<span v-else>{{ row.couponDiscount }}折</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已领取数量/总数量" width="180">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">
|
||||
{{ row.receivedNum }}/{{ row.publishNum === 0 ? "不限制" : row.publishNum }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已被使用的数量/已领取数量" width="200">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.usedNum }}/{{ row.receivedNum }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="获取方式" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="getTypeTagType(row.getType)">{{ getTypeText(row.getType) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="优惠券类型" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="couponTypeTagType(row.couponType)">
|
||||
{{ couponTypeText(row.couponType) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="品类描述" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="scopeTypeTagType(row.scopeType)">
|
||||
{{ scopeTypeText(row.scopeType) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="活动时间" width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="activity-time" v-html="formatActivityTime(row)"></div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="showStatusColumn"
|
||||
label="状态"
|
||||
width="100"
|
||||
align="center"
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="promotionStatusTagType(row.promotionStatus)">
|
||||
{{ promotionStatusText(row.promotionStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="showActionColumn"
|
||||
label="操作"
|
||||
width="250"
|
||||
align="center"
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a
|
||||
v-if="row.promotionStatus === 'CLOSE' || row.promotionStatus === 'NEW'"
|
||||
class="link-text"
|
||||
@click="see(row)"
|
||||
>
|
||||
编辑
|
||||
</a>
|
||||
<a v-else class="link-text" @click="see(row, 'onlyView')">查看</a>
|
||||
<span
|
||||
v-if="row.promotionStatus === 'START' || row.promotionStatus === 'NEW'"
|
||||
class="op-split"
|
||||
>
|
||||
|
|
||||
</span>
|
||||
<a
|
||||
v-if="row.promotionStatus === 'START' || row.promotionStatus === 'NEW'"
|
||||
class="link-text"
|
||||
@click="close(row)"
|
||||
>
|
||||
关闭
|
||||
</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="receivePage(row.id)">领取记录</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[10, 20, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getShopCouponList, updateCouponStatus } from "@/api/promotion";
|
||||
import {
|
||||
promotionsStatusRender,
|
||||
promotionsScopeTypeRender,
|
||||
} from "@/utils/promotions";
|
||||
getPlatformCouponList,
|
||||
updatePlatformCouponStatus,
|
||||
deletePlatformCoupon,
|
||||
} from "@/api/promotion";
|
||||
import { formatPromotionCouponValidityHtml } from "@/utils/promotions";
|
||||
|
||||
export default {
|
||||
name: "coupon",
|
||||
props: {
|
||||
getType: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
promotionStatus: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
selectedList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectDate: [],
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "startTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
getType: "",
|
||||
},
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
},
|
||||
{
|
||||
title: "优惠券名称",
|
||||
key: "couponName",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "面额/折扣",
|
||||
key: "price",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.couponType === "PRICE") {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
} else if(params.row.couponType === "DISCOUNT") {
|
||||
return h("div", (params.row.couponDiscount || 0) + "折");
|
||||
}else{
|
||||
return h("div", "未知");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "已领取数量/总数量",
|
||||
key: "publishNum",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
params.row.receivedNum +
|
||||
"/" +
|
||||
(params.row.publishNum === 0 ? "不限制" : params.row.publishNum)
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "已被使用的数量/已领取数量",
|
||||
key: "publishNum",
|
||||
render: (h, params) => {
|
||||
return h("div", params.row.usedNum + "/" + params.row.receivedNum);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "优惠券类型",
|
||||
key: "couponType",
|
||||
render: (h, params) => {
|
||||
let text = "未知";
|
||||
if (params.row.couponType === "DISCOUNT") {
|
||||
text = "打折";
|
||||
} else if (params.row.couponType === "PRICE") {
|
||||
text = "减免现金";
|
||||
}
|
||||
return h("div", [text]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "品类描述",
|
||||
key: "scopeType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
return promotionsScopeTypeRender(h, params);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "活动时间",
|
||||
width: 150,
|
||||
render: (h, params) => {
|
||||
if (
|
||||
params?.row?.getType === "ACTIVITY" &&
|
||||
params?.row?.rangeDayType === "DYNAMICTIME"
|
||||
) {
|
||||
return h("div", "长期有效");
|
||||
} else if (params?.row?.startTime && params?.row?.endTime) {
|
||||
return h("div", {
|
||||
domProps: {
|
||||
innerHTML:
|
||||
params.row.startTime + "<br/>" + params.row.endTime,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
width: 100,
|
||||
key: "promotionStatus",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return promotionsStatusRender(h, params);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
maxWidth: 240,
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
data: [],
|
||||
total: 0,
|
||||
selectDate: [],
|
||||
showActionColumn: true,
|
||||
showStatusColumn: true,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route(to) {
|
||||
if (to.fullPath == "/promotions/manager-coupon") {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
selectedList: {
|
||||
handler(val) {
|
||||
this.$nextTick(() => {
|
||||
this.syncTableSelection(val);
|
||||
});
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getDataList();
|
||||
formatActivityTime(row) {
|
||||
return formatPromotionCouponValidityHtml(row);
|
||||
},
|
||||
promotionStatusText(status) {
|
||||
const map = {
|
||||
NEW: "未开始",
|
||||
START: "已开始",
|
||||
END: "已结束",
|
||||
CLOSE: "已关闭",
|
||||
};
|
||||
return map[status] || "未知";
|
||||
},
|
||||
promotionStatusTagType(status) {
|
||||
const map = {
|
||||
NEW: "info",
|
||||
START: "success",
|
||||
END: "danger",
|
||||
CLOSE: "danger",
|
||||
};
|
||||
return map[status] || "danger";
|
||||
},
|
||||
scopeTypeText(type) {
|
||||
const map = {
|
||||
ALL: "全品类",
|
||||
PORTION_GOODS_CATEGORY: "商品分类",
|
||||
PORTION_SHOP_CATEGORY: "店铺分类",
|
||||
PORTION_GOODS: "指定商品",
|
||||
};
|
||||
return map[type] || "未知";
|
||||
},
|
||||
scopeTypeTagType(type) {
|
||||
const map = {
|
||||
ALL: "info",
|
||||
PORTION_GOODS_CATEGORY: "warning",
|
||||
PORTION_SHOP_CATEGORY: "warning",
|
||||
PORTION_GOODS: "primary",
|
||||
};
|
||||
return map[type] || "danger";
|
||||
},
|
||||
getTypeText(type) {
|
||||
const map = {
|
||||
FREE: "免费获取",
|
||||
ACTIVITY: "活动获取",
|
||||
INSIDE: "内购",
|
||||
IGAME: "游戏人生",
|
||||
};
|
||||
return map[type] || "未知";
|
||||
},
|
||||
getTypeTagType(type) {
|
||||
const map = {
|
||||
FREE: "danger",
|
||||
ACTIVITY: "warning",
|
||||
INSIDE: "success",
|
||||
IGAME: "success",
|
||||
};
|
||||
return map[type] || "";
|
||||
},
|
||||
couponTypeText(type) {
|
||||
const map = {
|
||||
DISCOUNT: "打折",
|
||||
PRICE: "减免现金",
|
||||
};
|
||||
return map[type] || "未知";
|
||||
},
|
||||
couponTypeTagType(type) {
|
||||
const map = {
|
||||
DISCOUNT: "primary",
|
||||
PRICE: "info",
|
||||
};
|
||||
return map[type] || "";
|
||||
},
|
||||
syncTableSelection(selected) {
|
||||
const table = this.$refs.table;
|
||||
if (!table) return;
|
||||
table.clearSelection();
|
||||
if (!selected || !selected.length) return;
|
||||
this.data.forEach((row) => {
|
||||
if (selected.some((item) => item.id === row.id)) {
|
||||
table.toggleRowSelection(row, true);
|
||||
}
|
||||
});
|
||||
},
|
||||
check() {
|
||||
this.$emit("selected", this.selectList);
|
||||
},
|
||||
receivePage(id) {
|
||||
if (id) {
|
||||
@@ -252,116 +333,121 @@ export default {
|
||||
this.$router.push({ name: "coupon-receive" });
|
||||
}
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
add() {
|
||||
this.$router.push({ name: "add-coupon" });
|
||||
},
|
||||
/** 跳转至领取详情页面 */
|
||||
receiveInfo(v) {
|
||||
this.$router.push({ name: "member-receive-coupon", query: { id: v.id } });
|
||||
},
|
||||
info(v) {
|
||||
this.$router.push({ name: "platform-coupon-info", query: { id: v.id } });
|
||||
this.$router.push({ name: "add-platform-coupon" });
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
handleReset() {
|
||||
this.searchForm = {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "startTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
};
|
||||
this.selectDate = "";
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
clearSelectAll() {
|
||||
this.$refs.table.selectAll(false);
|
||||
this.$refs.table?.clearSelection();
|
||||
},
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
if (this.getType === "ACTIVITY") this.check();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
if (this.selectDate && this.selectDate[0] && this.selectDate[1]) {
|
||||
this.searchForm.startTime = this.selectDate[0].getTime();
|
||||
this.searchForm.endTime = this.selectDate[1].getTime();
|
||||
this.searchForm.startTime = new Date(this.selectDate[0]).getTime();
|
||||
this.searchForm.endTime = new Date(this.selectDate[1]).getTime();
|
||||
} else {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
}
|
||||
getShopCouponList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
getPlatformCouponList(this.searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
this.$nextTick(() => {
|
||||
if (this.selectedList.length) {
|
||||
this.syncTableSelection(this.selectedList);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 跳转编辑优惠券页面
|
||||
see(v, only) {
|
||||
let data;
|
||||
only ? (data = { onlyView: true, id: v.id }) : (data = { id: v.id });
|
||||
this.$router.push({ name: "add-coupon", query: data });
|
||||
const data = only ? { onlyView: true, id: v.id } : { id: v.id };
|
||||
this.$router.push({ name: "edit-platform-coupon", query: data });
|
||||
},
|
||||
// 下架优惠券
|
||||
remove(v) {
|
||||
close(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认下架",
|
||||
content: "确认要下架此优惠券么?",
|
||||
title: "确认关闭",
|
||||
content: "确认要关闭此优惠券么?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
this.loading = false;
|
||||
let params = {
|
||||
updatePlatformCouponStatus({
|
||||
couponIds: v.id,
|
||||
};
|
||||
updateCouponStatus(params).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("下架成功");
|
||||
this.clearSelectAll();
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
effectiveDays: 0,
|
||||
})
|
||||
.then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("优惠券已关闭");
|
||||
this.getDataList();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$Modal.remove();
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "确认要删除此优惠券么?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
deletePlatformCoupon(v.id)
|
||||
.then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("优惠券已删除");
|
||||
this.getDataList();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$Modal.remove();
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 批量下架
|
||||
delAll() {
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要关闭的优惠券");
|
||||
this.$Message.warning("您还未选择要下架的优惠券");
|
||||
return;
|
||||
}
|
||||
this.$Modal.confirm({
|
||||
title: "确认关闭",
|
||||
content: "您确认要关闭所选的 " + this.selectCount + " 条数据?",
|
||||
title: "确认下架",
|
||||
content: "您确认要下架所选的 " + this.selectCount + " 条数据?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
let ids = [];
|
||||
this.selectList.forEach(function (e) {
|
||||
ids.push(e.id);
|
||||
});
|
||||
|
||||
let params = {
|
||||
const ids = this.selectList.map((e) => e.id);
|
||||
updatePlatformCouponStatus({
|
||||
couponIds: ids.toString(),
|
||||
};
|
||||
updateCouponStatus(params).then((res) => {
|
||||
promotionStatus: "CLOSE",
|
||||
}).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("下架成功");
|
||||
@@ -374,13 +460,40 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.getType) {
|
||||
this.searchForm.getType = this.getType;
|
||||
this.showActionColumn = false;
|
||||
}
|
||||
if (this.promotionStatus) {
|
||||
this.searchForm.promotionStatus = this.promotionStatus;
|
||||
this.showStatusColumn = false;
|
||||
}
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
.search-form {
|
||||
width: 100% !important;
|
||||
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
.activity-time {
|
||||
line-height: 1.5;
|
||||
word-break: break-all;
|
||||
}
|
||||
.mb_10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.padding-row {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,276 +1,255 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Form ref="form" :model="form" :label-width="120" :rules="formRule">
|
||||
<el-card>
|
||||
<el-form ref="form" :model="form" label-width="120px">
|
||||
<div class="base-info-item">
|
||||
<h4>基本信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="活动名称" prop="promotionName">
|
||||
<Input type="text" v-model="form.promotionName" :disabled="form.promotionStatus != 'NEW'" placeholder="活动名称"
|
||||
clearable style="width: 280px" />
|
||||
</FormItem>
|
||||
<FormItem label="活动时间" prop="rangeTime">
|
||||
<DatePicker type="datetimerange" v-model="form.rangeTime" :disabled="form.promotionStatus != 'NEW'"
|
||||
format="yyyy-MM-dd HH:mm:ss" placeholder="请选择" :options="options" style="width: 280px">
|
||||
</DatePicker>
|
||||
</FormItem>
|
||||
<FormItem label="活动描述" prop="description">
|
||||
<Input v-model="form.description" :disabled="form.promotionStatus != 'NEW'" type="textarea" :rows="4"
|
||||
clearable style="width: 280px" />
|
||||
</FormItem>
|
||||
<el-form-item label="活动名称" prop="promotionName">
|
||||
<el-input
|
||||
v-model="form.promotionName"
|
||||
disabled
|
||||
placeholder="活动名称"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间" prop="rangeTime">
|
||||
<el-date-picker
|
||||
type="datetimerange"
|
||||
v-model="form.rangeTime"
|
||||
disabled
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placeholder="请选择"
|
||||
:disabled-date="options.disabledDate"
|
||||
style="width: 320px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动描述" prop="description">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
disabled
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<h4>优惠设置</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="优惠门槛" prop="fullMoney">
|
||||
<Input type="text" v-model="form.fullMoney" :disabled="form.promotionStatus != 'NEW'" placeholder="优惠门槛"
|
||||
clearable style="width: 280px" />
|
||||
<el-form-item label="优惠门槛" prop="fullMoney">
|
||||
<el-input
|
||||
v-model="form.fullMoney"
|
||||
disabled
|
||||
placeholder="优惠门槛"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
<span class="describe">消费达到当前金额可以参与优惠</span>
|
||||
</FormItem>
|
||||
<FormItem label="优惠方式">
|
||||
<RadioGroup type="button" button-style="solid" v-model="form.discountType">
|
||||
<Radio :disabled="form.promotionStatus != 'NEW'" label="fullMinusFlag">减现金</Radio>
|
||||
<Radio :disabled="form.promotionStatus != 'NEW'" label="fullRateFlag">打折</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem v-if="form.discountType == 'fullMinusFlag'" label="优惠金额" prop="fullMinus">
|
||||
<Input :disabled="form.promotionStatus != 'NEW'" type="text" v-model="form.fullMinus" placeholder="优惠金额"
|
||||
clearable style="width: 280px" />
|
||||
</FormItem>
|
||||
<FormItem v-if="form.discountType == 'fullRateFlag'" label="优惠折扣" prop="fullRate">
|
||||
<InputNumber :disabled="form.promotionStatus != 'NEW'"
|
||||
</el-form-item>
|
||||
<el-form-item label="赠送优惠券">
|
||||
<el-radio-group v-model="form.discountType">
|
||||
<el-radio-button value="fullMinusFlag" disabled>减现金</el-radio-button>
|
||||
<el-radio-button value="fullRateFlag" disabled>打折</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.discountType == 'fullMinusFlag'"
|
||||
label="优惠金额"
|
||||
prop="fullMinus"
|
||||
>
|
||||
<el-input
|
||||
disabled
|
||||
v-model="form.fullMinus"
|
||||
placeholder="优惠金额"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.discountType == 'fullRateFlag'"
|
||||
label="优惠折扣"
|
||||
prop="fullRate"
|
||||
>
|
||||
<el-input-number
|
||||
placeholder="优惠折扣"
|
||||
:max="9.9"
|
||||
:min="0.1"
|
||||
:step="0.1"
|
||||
precision="1"
|
||||
:precision="1"
|
||||
v-model="form.fullRate"
|
||||
style="width: 260px"/>
|
||||
style="width: 260px"
|
||||
/>
|
||||
<span class="describe">优惠折扣为0-10之间数字,可有一位小数</span>
|
||||
</FormItem>
|
||||
<FormItem label="额外赠送">
|
||||
<Checkbox :disabled="form.promotionStatus != 'NEW'" v-model="form.freeFreightFlag">免邮费</Checkbox>
|
||||
<Checkbox :disabled="form.promotionStatus != 'NEW'" v-model="form.couponFlag">送优惠券</Checkbox>
|
||||
<Checkbox :disabled="form.promotionStatus != 'NEW'" v-model="form.giftFlag">送赠品</Checkbox>
|
||||
<Checkbox :disabled="form.promotionStatus != 'NEW'" v-if="Cookies.get('userInfoSeller') &&
|
||||
JSON.parse(Cookies.get('userInfoSeller')).selfOperated
|
||||
" v-model="form.pointFlag">送积分</Checkbox>
|
||||
</FormItem>
|
||||
<FormItem v-if="form.couponFlag" label="赠送优惠券" prop="couponId">
|
||||
<Select v-model="form.couponId" :disabled="form.promotionStatus != 'NEW'" filterable
|
||||
:remote-method="getCouponList" placeholder="输入优惠券名称搜索" :loading="couponLoading" style="width: 280px">
|
||||
<Option v-for="item in couponList" :value="item.id" :key="item.id">{{ item.couponName }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem v-if="form.giftFlag" label="赠品" prop="giftId">
|
||||
<Select :disabled="form.promotionStatus != 'NEW'" v-model="form.giftId" filterable
|
||||
:remote-method="getGiftList" placeholder="输入赠品名称搜索" :loading="giftLoading" style="width: 280px">
|
||||
<Option v-for="item in giftList" :value="item.id" :key="item.id">
|
||||
{{ item.goodsName }}
|
||||
</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem v-if="form.pointFlag" label="赠积分" prop="point">
|
||||
<InputNumber :min="0" :disabled="form.promotionStatus != 'NEW'" v-model="form.point" type="number"
|
||||
style="width: 280px" />
|
||||
</FormItem>
|
||||
<FormItem label="使用范围" prop="scopeType">
|
||||
<RadioGroup type="button" button-style="solid" v-model="form.scopeType">
|
||||
<Radio :disabled="form.promotionStatus != 'NEW'" label="ALL">全品类</Radio>
|
||||
<Radio :disabled="form.promotionStatus != 'NEW'" label="PORTION_GOODS">指定商品</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
<el-form-item label="额外赠送">
|
||||
<el-checkbox v-model="form.freeFreightFlag" disabled>免邮费</el-checkbox>
|
||||
<el-checkbox v-model="form.couponFlag" disabled>送优惠券</el-checkbox>
|
||||
<el-checkbox v-model="form.giftFlag" disabled>送赠品</el-checkbox>
|
||||
<el-checkbox v-model="form.pointFlag" disabled>送积分</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.couponFlag" label="赠送优惠券" prop="couponId">
|
||||
<el-select
|
||||
v-model="form.couponId"
|
||||
:disabled="form.promotionStatus != 'NEW'"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="getCouponList"
|
||||
placeholder="输入优惠券名称搜索"
|
||||
:loading="couponLoading"
|
||||
style="width: 280px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in couponList"
|
||||
:value="item.id"
|
||||
:key="item.id"
|
||||
:label="item.couponName"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.giftFlag" label="赠品" prop="giftId">
|
||||
<el-select
|
||||
v-model="form.giftId"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="getGiftList"
|
||||
placeholder="输入赠品名称搜索"
|
||||
disabled
|
||||
:loading="giftLoading"
|
||||
style="width: 260px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in giftList"
|
||||
:value="item.id"
|
||||
:key="item.id"
|
||||
:label="item.goodsName"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.pointFlag" label="赠积分" prop="point">
|
||||
<el-input
|
||||
v-model="form.point"
|
||||
type="number"
|
||||
disabled
|
||||
style="width: 260px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="使用范围" prop="scopeType">
|
||||
<el-radio-group v-model="form.scopeType">
|
||||
<el-radio-button value="ALL" disabled>全品类</el-radio-button>
|
||||
<el-radio-button value="PORTION_GOODS" disabled>指定商品</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<FormItem style="width: 100%" v-if="form.scopeType == 'PORTION_GOODS'">
|
||||
<div style="display: flex; margin-bottom: 10px" v-if="form.promotionStatus == 'NEW'">
|
||||
<Button type="primary" @click="openSkuList">选择商品</Button>
|
||||
<Button type="error" ghost style="margin-left: 10px" @click="delSelectGoods">批量删除</Button>
|
||||
</div>
|
||||
<Table border :columns="columns" :data="form.promotionGoodsList" @on-selection-change="changeSelect">
|
||||
<template slot-scope="{ row }" slot="QRCode">
|
||||
<img :src="row.QRCode || '../../../assets/lili.png'" width="50px" height="50px" alt="" />
|
||||
</template>
|
||||
<template slot-scope="{ index }" slot="action">
|
||||
<a
|
||||
v-if="form.promotionStatus == 'NEW' || !id"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="delGoods(index)"
|
||||
>删除</a>
|
||||
</template>
|
||||
</Table>
|
||||
</FormItem>
|
||||
<el-form-item
|
||||
style="width: 100%"
|
||||
v-if="form.scopeType == 'PORTION_GOODS'"
|
||||
>
|
||||
<el-table border :data="form.promotionGoodsList" style="width: 100%">
|
||||
<el-table-column type="selection" width="60" align="center" />
|
||||
<el-table-column label="商品名称" min-width="120" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text mr_10" @click="linkTo(row.goodsId, row.skuId)">{{
|
||||
row.goodsName
|
||||
}}</a>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../../assets/qrcode.svg"
|
||||
style="vertical-align: middle"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt=""
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" width="90">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.quantity }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
|
||||
<div>
|
||||
<Button type="text" @click="closeCurrentPage">返回</Button>
|
||||
<Button type="primary" :disabled="form.promotionStatus != 'NEW' && !!id" :loading="submitLoading"
|
||||
@click="handleSubmit">提交</Button>
|
||||
<el-button @click="$router.push({ name: 'promotions/full-discount' })">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</Card>
|
||||
<sku-select ref="skuSelect" @selectedGoodsData="selectedGoodsData"></sku-select>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getShopCouponList,
|
||||
getFullDiscountById,
|
||||
newFullDiscount,
|
||||
editFullDiscount,
|
||||
} from "@/api/promotion";
|
||||
import { getPlatformCouponList, getFullDiscountById } from "@/api/promotion";
|
||||
import { getGoodsSkuListDataSeller } from "@/api/goods";
|
||||
import { regular } from "@/utils";
|
||||
import skuSelect from "@/views/lili-dialog";
|
||||
import Cookies from "js-cookie";
|
||||
import vueQr from "vue-qr";
|
||||
export default {
|
||||
name: "full-discount-add",
|
||||
name: "add-full-discount",
|
||||
components: {
|
||||
skuSelect,
|
||||
"vue-qr": vueQr,
|
||||
},
|
||||
data () {
|
||||
const checkPrice = (rule, value, callback) => {
|
||||
if (!value && value !== 0) {
|
||||
return callback(new Error("面额不能为空"));
|
||||
} else if (!regular.money.test(value)) {
|
||||
callback(new Error("请输入正整数或者两位小数"));
|
||||
} else if (parseFloat(value) > 99999999) {
|
||||
callback(new Error("面额设置超过上限值"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const checkWeight = (rule, value, callback) => {
|
||||
if (!value && typeof value !== "number") {
|
||||
callback(new Error("优惠门槛不能为空"));
|
||||
} else if (!regular.money.test(value)) {
|
||||
callback(new Error("请输入正整数或者两位小数"));
|
||||
} else if (parseFloat(value) > 99999999) {
|
||||
callback(new Error("优惠门槛设置超过上限值"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
data() {
|
||||
return {
|
||||
Cookies,
|
||||
form: {
|
||||
// 活动表单
|
||||
discountType: "fullMinusFlag",
|
||||
scopeType: "ALL",
|
||||
promotionGoodsList: [],
|
||||
promotionStatus: "NEW",
|
||||
},
|
||||
id: this.$route.query.id, // 活动id
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
selectedGoods: [], // 已选商品列表,便于删除
|
||||
formRule: {
|
||||
// 验证规则
|
||||
promotionName: [{ required: true, message: "活动名称不能为空" }],
|
||||
rangeTime: [{ required: true, message: "请选择活动时间" }],
|
||||
description: [{ required: true, message: "请填写活动描述" }],
|
||||
price: [
|
||||
{ required: true, message: "请输入面额" },
|
||||
{ validator: checkPrice },
|
||||
],
|
||||
consumptionLimit: [{ required: true, validator: checkWeight }],
|
||||
fullMoney: [{ required: true, validator: checkWeight }],
|
||||
fullMinus: [
|
||||
{ required: true, message: "请填写优惠金额" },
|
||||
{ pattern: regular.money, message: "请输入正确金额" },
|
||||
],
|
||||
fullRate: [
|
||||
{ required: true, message: "请填写优惠折扣" },
|
||||
{
|
||||
pattern: regular.discount,
|
||||
message: "请输入0-10的数字,可有一位小数",
|
||||
},
|
||||
],
|
||||
couponId: [{ required: true, message: "请选择优惠券" }],
|
||||
giftId: [{ required: true, message: "请选择赠品" }],
|
||||
point: [{ required: true, message: "请填写积分" }],
|
||||
},
|
||||
couponList: [], // 店铺优惠券列表
|
||||
giftList: [], // 赠品列表
|
||||
giftLoading: false, // 请求赠品状态
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "商品价格",
|
||||
key: "price",
|
||||
minWidth: 40,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
minWidth: 40,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
minWidth: 50,
|
||||
},
|
||||
],
|
||||
id: this.$route.query.id,
|
||||
couponList: [],
|
||||
giftList: [],
|
||||
giftLoading: false,
|
||||
couponLoading: false,
|
||||
options: {
|
||||
disabledDate (date) {
|
||||
disabledDate(date) {
|
||||
return date && date.valueOf() < Date.now() - 86400000;
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
async mounted () {
|
||||
async mounted() {
|
||||
if (this.id) {
|
||||
this.getDetail();
|
||||
this.columns.shift()
|
||||
this.columns.pop()
|
||||
}
|
||||
await this.getCouponList();
|
||||
await this.getGiftList();
|
||||
this.getCouponList();
|
||||
this.getGiftList();
|
||||
},
|
||||
methods: {
|
||||
// 关闭当前页面
|
||||
closeCurrentPage () {
|
||||
this.$store.commit("removeTag", "full-cut-detail");
|
||||
localStorage.storeOpenedList = JSON.stringify(
|
||||
this.$store.state.app.storeOpenedList
|
||||
);
|
||||
this.$router.go(-1);
|
||||
},
|
||||
openSkuList () {
|
||||
// 显示商品选择器
|
||||
this.$refs.skuSelect.open("goods");
|
||||
let data = JSON.parse(JSON.stringify(this.form.promotionGoodsList));
|
||||
data.forEach((e) => {
|
||||
e.id = e.skuId;
|
||||
});
|
||||
this.$refs.skuSelect.goodsData = data;
|
||||
},
|
||||
getDetail () {
|
||||
// 获取活动详情
|
||||
getDetail() {
|
||||
getFullDiscountById(this.id).then((res) => {
|
||||
|
||||
let data = res.result;
|
||||
if (data.scopeType === "ALL") {
|
||||
if (!data.scopeType === "ALL") {
|
||||
data.promotionGoodsList = [];
|
||||
}
|
||||
if (data.fullMinusFlag) {
|
||||
data.discountType = "fullMinusFlag";
|
||||
delete data.fullMinusFlag;
|
||||
} else {
|
||||
data.discountType = "fullRateFlag";
|
||||
data.discountType = "fullMinusFlag";
|
||||
delete data.fullRateFlag;
|
||||
}
|
||||
data.rangeTime = [];
|
||||
@@ -279,142 +258,26 @@ export default {
|
||||
this.form = data;
|
||||
});
|
||||
},
|
||||
/** 保存 */
|
||||
handleSubmit () {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
const params = JSON.parse(JSON.stringify(this.form));
|
||||
const strat = this.$options.filters.unixToDate(
|
||||
this.form.rangeTime[0] / 1000
|
||||
);
|
||||
const end = this.$options.filters.unixToDate(
|
||||
this.form.rangeTime[1] / 1000
|
||||
);
|
||||
params.startTime = strat;
|
||||
params.endTime = end;
|
||||
|
||||
if (
|
||||
params.scopeType == "PORTION_GOODS" &&
|
||||
(!params.promotionGoodsList ||
|
||||
params.promotionGoodsList.length == 0)
|
||||
) {
|
||||
this.$Modal.warning({ title: "提示", content: "请选择指定商品" });
|
||||
return;
|
||||
}
|
||||
if (params.scopeType == "ALL") {
|
||||
delete params.promotionGoodsList;
|
||||
params.number = -1;
|
||||
} else {
|
||||
let scopeId = [];
|
||||
params.number = 1;
|
||||
params.promotionGoodsList.forEach((e) => {
|
||||
e.startTime = params.startTime;
|
||||
e.endTime = params.endTime;
|
||||
scopeId.push(e.skuId);
|
||||
});
|
||||
params.scopeId = scopeId.toString();
|
||||
}
|
||||
if (params.discountType == "fullMinusFlag") {
|
||||
params.fullMinusFlag = true;
|
||||
} else {
|
||||
params.fullRateFlag = true;
|
||||
}
|
||||
delete params.rangeTime;
|
||||
this.submitLoading = true;
|
||||
if (!this.id) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete params.id;
|
||||
newFullDiscount(params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加活动成功");
|
||||
this.closeCurrentPage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
delete params.updateTime;
|
||||
|
||||
editFullDiscount(params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("编辑活动成功");
|
||||
this.closeCurrentPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
changeSelect (e) {
|
||||
// 已选商品批量选择
|
||||
this.selectedGoods = e;
|
||||
},
|
||||
delSelectGoods () {
|
||||
// 多选删除商品
|
||||
if (this.selectedGoods.length <= 0) {
|
||||
this.$Message.warning("您还未选择要删除的数据");
|
||||
return;
|
||||
}
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除所选商品吗?",
|
||||
onOk: () => {
|
||||
let ids = [];
|
||||
this.selectedGoods.forEach(function (e) {
|
||||
ids.push(e.id);
|
||||
});
|
||||
this.form.promotionGoodsList = this.form.promotionGoodsList.filter(
|
||||
(item) => {
|
||||
return !ids.includes(item.id);
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
delGoods (index) {
|
||||
// 删除商品
|
||||
this.form.promotionGoodsList.splice(index, 1);
|
||||
},
|
||||
selectedGoodsData (item) {
|
||||
// 回显已选商品
|
||||
let list = [];
|
||||
item.forEach((e) => {
|
||||
list.push({
|
||||
goodsName: e.goodsName,
|
||||
price: e.price,
|
||||
quantity: e.quantity,
|
||||
storeId: e.storeId,
|
||||
goodsId:e.goodsId,
|
||||
storeName: e.storeName,
|
||||
thumbnail: e.thumbnail,
|
||||
skuId: e.id,
|
||||
});
|
||||
});
|
||||
this.form.promotionGoodsList = list;
|
||||
},
|
||||
getCouponList (query) {
|
||||
// 优惠券列表
|
||||
getCouponList(query) {
|
||||
let params = {
|
||||
pageSize: 10,
|
||||
pageNumber: 0,
|
||||
pageSize: 20,
|
||||
pageNumber: 1,
|
||||
getType: "ACTIVITY",
|
||||
storeId: "",
|
||||
couponName: query,
|
||||
promotionStatus: "START",
|
||||
};
|
||||
this.couponLoading = true;
|
||||
getShopCouponList(params).then((res) => {
|
||||
getPlatformCouponList(params).then((res) => {
|
||||
this.couponLoading = false;
|
||||
if (res.success) {
|
||||
this.couponList = res.result.records;
|
||||
}
|
||||
});
|
||||
},
|
||||
getGiftList (query) {
|
||||
// 赠品列表
|
||||
getGiftList(query) {
|
||||
let params = {
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
pageNumber: 1,
|
||||
id: query === this.form.giftId ? this.form.giftId : null,
|
||||
goodsName: query === this.form.giftId ? null : query,
|
||||
@@ -422,7 +285,7 @@ export default {
|
||||
authFlag: "PASS"
|
||||
};
|
||||
this.giftLoading = true;
|
||||
getGoodsSkuListDataSeller(params).then((res) => {
|
||||
getGoodsSkuData(params).then((res) => {
|
||||
this.giftLoading = false;
|
||||
if (res.success) {
|
||||
this.giftList = res.result.records;
|
||||
@@ -445,14 +308,14 @@ h4 {
|
||||
line-height: 40px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.describe {
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.ivu-form-item {
|
||||
margin-bottom: 24px !important;
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,218 +1,154 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="活动名称">
|
||||
<Input type="text" v-model="searchForm.promotionName" placeholder="请输入活动名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="活动状态" prop="promotionStatus">
|
||||
<Select v-model="searchForm.promotionStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<Option value="NEW">未开始</Option>
|
||||
<Option value="START">已开始/上架</Option>
|
||||
<Option value="END">已结束/下架</Option>
|
||||
<Option value="CLOSE">紧急关闭/作废</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="活动时间">
|
||||
<DatePicker v-model="selectDate" type="daterange" clearable placeholder="选择起始时间" style="width: 240px">
|
||||
</DatePicker>
|
||||
</Form-item>
|
||||
<Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="ml_10">重置</Button>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operation">
|
||||
<Button type="primary" @click="newAct">新增</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table">
|
||||
<template slot-scope="{ row }" slot="applyEndTime">
|
||||
{{ unixDate(row.applyEndTime) }}
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="promotionType">
|
||||
{{ row.fullMinusFlag ? "满减" : "满折" }}
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="hours">
|
||||
<Tag v-for="item in unixHours(row.hours)" :key="item">{{ item }}</Tag>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="action">
|
||||
<div>
|
||||
<a v-if="row.promotionStatus == 'NEW'" @click="edit(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">编辑</a>
|
||||
<a v-else @click="edit(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">查看</a>
|
||||
<span v-if="row.promotionStatus === 'START' || row.promotionStatus === 'CLOSE'" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-if="row.promotionStatus === 'START'" @click="openOrClose(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">关闭</a>
|
||||
<a v-if="row.promotionStatus === 'CLOSE'" @click="openOrClose(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">开启</a>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="page operation">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small" show-total show-elevator
|
||||
show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<div class="search full-cut">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="活动名称" prop="promotionName">
|
||||
<el-input
|
||||
v-model="searchForm.promotionName"
|
||||
placeholder="请输入活动名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动状态" prop="promotionStatus">
|
||||
<el-select
|
||||
v-model="searchForm.promotionStatus"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option label="未开始" value="NEW" />
|
||||
<el-option label="已开始/上架" value="START" />
|
||||
<el-option label="已结束/下架" value="END" />
|
||||
<el-option label="紧急关闭/作废" value="CLOSE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="daterange"
|
||||
clearable
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="promotionName" label="活动名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="startTime" label="开始时间" width="170" />
|
||||
<el-table-column prop="endTime" label="结束时间" width="170" />
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="活动类型" min-width="80">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.fullMinusFlag ? "满减" : "满折" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="活动状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="promotionStatusTagType(row.promotionStatus)">
|
||||
{{ promotionStatusText(row.promotionStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="140" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="view(row)">查看</a>
|
||||
<template v-if="row.promotionStatus === 'NEW' || row.promotionStatus === 'START'">
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="openOrClose(row)">关闭</a>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getFullDiscountList,
|
||||
delFullDiscount,
|
||||
updateFullDiscount,
|
||||
} from "@/api/promotion.js";
|
||||
import { getFullDiscountList, updateFullDiscount } from "@/api/promotion.js";
|
||||
|
||||
export default {
|
||||
name: "full-cut",
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
total: 0,
|
||||
selectDate: [],
|
||||
loading: false, // 表单加载状态
|
||||
total: 0,
|
||||
loading: false,
|
||||
searchForm: {
|
||||
// 列表请求参数
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "startTime",
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "活动名称",
|
||||
key: "promotionName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "开始时间",
|
||||
key: "startTime",
|
||||
minWidth: 60,
|
||||
},
|
||||
{
|
||||
title: "结束时间",
|
||||
key: "endTime",
|
||||
minWidth: 60,
|
||||
},
|
||||
{
|
||||
title: "活动类型",
|
||||
slot: "promotionType",
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: "活动状态",
|
||||
key: "promotionStatus",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
let text = "未知",
|
||||
color = "default";
|
||||
if (params.row.promotionStatus == "NEW") {
|
||||
text = "未开始";
|
||||
color = "default";
|
||||
} else if (params.row.promotionStatus == "START") {
|
||||
text = "已开始";
|
||||
color = "green";
|
||||
} else if (params.row.promotionStatus == "END") {
|
||||
text = "已结束";
|
||||
color = "blue";
|
||||
} else if (params.row.promotionStatus == "CLOSE") {
|
||||
text = "已关闭";
|
||||
color = "red";
|
||||
}
|
||||
return h("div", [
|
||||
h(
|
||||
"Tag",
|
||||
{
|
||||
props: {
|
||||
color: color,
|
||||
},
|
||||
},
|
||||
text
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
align: "center",
|
||||
width: 200,
|
||||
},
|
||||
],
|
||||
data: [], // 表格数据
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 改变页码
|
||||
newAct () {
|
||||
this.$router.push({ name: "full-discount-detail" });
|
||||
},
|
||||
// 初始化数据
|
||||
init () {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePage (v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePageSize (v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch () {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset () {
|
||||
this.selectDate = "";
|
||||
this.searchForm = {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "startTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
promotionStatusText(status) {
|
||||
const map = {
|
||||
NEW: "未开始",
|
||||
START: "已开始",
|
||||
END: "已结束",
|
||||
CLOSE: "已关闭",
|
||||
};
|
||||
return map[status] || "未知";
|
||||
},
|
||||
promotionStatusTagType(status) {
|
||||
const map = {
|
||||
NEW: "info",
|
||||
START: "success",
|
||||
END: "danger",
|
||||
CLOSE: "danger",
|
||||
};
|
||||
return map[status] || "danger";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 编辑
|
||||
edit (row) {
|
||||
this.$router.push({ name: "full-discount-detail", query: { id: row.id } });
|
||||
},
|
||||
// 删除
|
||||
del (row) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
// 记得确认修改此处
|
||||
content: "确认删除此活动吗?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
delFullDiscount(row.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("删除成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
// 开启或关闭活动
|
||||
openOrClose (row) {
|
||||
openOrClose(row) {
|
||||
let name = "开启";
|
||||
let status = "START";
|
||||
if (row.promotionStatus === "START") {
|
||||
if (row.promotionStatus === "NEW" || row.promotionStatus === "START") {
|
||||
name = "关闭";
|
||||
status = "CLOSE";
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
// 记得确认修改此处
|
||||
content: `确认${name}此活动吗?需要一定时间才能生效,请耐心等待`,
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
updateFullDiscount(row.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -222,57 +158,21 @@ export default {
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
let sTime = new Date();
|
||||
sTime.setMinutes(sTime.getMinutes() + 10);
|
||||
let eTime = new Date(new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000 - 1);
|
||||
this.openStartTime = sTime.getTime();
|
||||
this.openEndTime = eTime.getTime();
|
||||
this.$Modal.confirm({
|
||||
title: "确认开启(默认为当前时间的十分钟之后)",
|
||||
content: "您确认要开启此拼团活动?",
|
||||
onOk: () => {
|
||||
let params = {
|
||||
startTime: this.openStartTime,
|
||||
endTime: this.openEndTime,
|
||||
};
|
||||
updateFullDiscount(row.id, params).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("开启活动成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
render: (h) => {
|
||||
return h("div", [
|
||||
h("DatePicker", {
|
||||
props: {
|
||||
type: "datetimerange",
|
||||
placeholder: "请选择开始时间和结束时间",
|
||||
value: [sTime, eTime],
|
||||
},
|
||||
style: {
|
||||
width: "350px",
|
||||
},
|
||||
on: {
|
||||
input: (val) => {
|
||||
if (val[0]) {
|
||||
this.openStartTime = val[0].getTime();
|
||||
}
|
||||
if (val[1]) {
|
||||
this.openEndTime = val[1].getTime();
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList () {
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
if (this.selectDate && this.selectDate[0] && this.selectDate[1]) {
|
||||
this.searchForm.startTime = this.selectDate[0].getTime();
|
||||
@@ -289,21 +189,29 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
view(row) {
|
||||
this.$router.push({ name: "full-discount-detail", query: { id: row.id } });
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave (to, from, next) {
|
||||
from.meta.keepAlive = false;
|
||||
next();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
|
||||
.operation {
|
||||
margin: 10px 0;
|
||||
<style lang="scss" scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdfe6;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,194 +1,142 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card style="position: relative">
|
||||
<Spin size="large" fix v-if="spinShow"></Spin>
|
||||
<Alert type="warning">
|
||||
<template slot="desc">
|
||||
为了方便在创建直播间时从选择商品,请尽量提前提审直播商品
|
||||
</template>
|
||||
</Alert>
|
||||
<el-card v-loading="spinShow" style="position: relative">
|
||||
<el-alert type="warning" show-icon :closable="false" style="margin-bottom: 16px">
|
||||
为了方便在创建直播间时从选择商品,请尽量提前提审直播商品
|
||||
</el-alert>
|
||||
|
||||
<Form :model="liveForm" ref="liveForm" :rules="liveRulesForm" :label-width="120">
|
||||
<FormItem label="直播标题" prop="name">
|
||||
<Input
|
||||
<el-form ref="liveForm" :model="liveForm" :rules="liveRulesForm" label-width="120px">
|
||||
<el-form-item label="直播标题" prop="name">
|
||||
<el-input :disabled="liveStatus != 'NEW'" v-model="liveForm.name" style="width: 460px" />
|
||||
<div class="tips">直播间名字,最短3个汉字,最长17个汉字,1个汉字相当于2个字符</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="主播昵称" prop="anchorName">
|
||||
<el-input :disabled="liveStatus != 'NEW'" v-model="liveForm.anchorName" style="width: 360px" />
|
||||
<div class="tips">主播昵称,最短2个汉字,最长15个汉字,1个汉字相当于2个字符</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="直播时间" prop="startTime">
|
||||
<el-date-picker
|
||||
:disabled="liveStatus != 'NEW'"
|
||||
v-model="liveForm.name"
|
||||
style="width: 460px"
|
||||
></Input>
|
||||
<div class="tips">
|
||||
直播间名字,最短3个汉字,最长17个汉字,1个汉字相当于2个字符
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="主播昵称" prop="anchorName">
|
||||
<Input
|
||||
:disabled="liveStatus != 'NEW'"
|
||||
v-model="liveForm.anchorName"
|
||||
style="width: 360px"
|
||||
></Input>
|
||||
<div class="tips">
|
||||
主播昵称,最短2个汉字,最长15个汉字,1个汉字相当于2个字符
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="直播时间" prop="startTime">
|
||||
<DatePicker
|
||||
:disabled="liveStatus != 'NEW'"
|
||||
format="yyyy-MM-dd HH:mm"
|
||||
type="datetimerange"
|
||||
v-model="times"
|
||||
@on-change="handleChangeTime"
|
||||
:options="optionsTime"
|
||||
placeholder="直播计划开始时间-直播计划结束时间"
|
||||
style="width: 300px"
|
||||
>
|
||||
</DatePicker>
|
||||
type="datetimerange"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
:disabled-date="disabledDate"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
style="width: 360px"
|
||||
@change="handleChangeTime"
|
||||
/>
|
||||
<div class="tips">
|
||||
直播开播时间需要在当前时间的10分钟后并且,开始时间不能在6个月后,直播计划结束时间(开播时间和结束时间间隔不得短于30分钟,不得超过24小时)
|
||||
</div>
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="主播微信号" prop="anchorWechat">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="主播微信号" prop="anchorWechat">
|
||||
<el-input
|
||||
:disabled="liveStatus != 'NEW'"
|
||||
v-model="liveForm.anchorWechat"
|
||||
style="width: 360px"
|
||||
placeholder="主播微信号"
|
||||
></Input>
|
||||
/>
|
||||
<div class="tips">
|
||||
主播微信号,如果未实名认证,需要先前往“小程序直播”小程序进行<a
|
||||
target="_black"
|
||||
主播微信号,如果未实名认证,需要先前往“小程序直播”小程序进行
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://res.wx.qq.com/op_res/9rSix1dhHfK4rR049JL0PHJ7TpOvkuZ3mE0z7Ou_Etvjf-w1J_jVX0rZqeStLfwh"
|
||||
>实名验证</a
|
||||
>
|
||||
>实名验证</a>
|
||||
</div>
|
||||
</FormItem>
|
||||
|
||||
<!-- 分享卡片 -->
|
||||
<FormItem label="分享卡片封面" prop="feedsImg">
|
||||
<upload-pic-thumb v-model="liveForm.feedsImg" :multiple="false"></upload-pic-thumb>
|
||||
</el-form-item>
|
||||
<el-form-item label="分享卡片封面" prop="feedsImg">
|
||||
<upload-pic-thumb v-model="liveForm.feedsImg" :multiple="false" />
|
||||
<div class="tips">直播间分享图,图片规则:建议像素800*640,大小不超过1M;</div>
|
||||
</FormItem>
|
||||
|
||||
<!-- 直播间背景墙 -->
|
||||
<FormItem label="直播间背景墙" prop="coverImg">
|
||||
<upload-pic-thumb v-model="liveForm.coverImg" :multiple="false"></upload-pic-thumb>
|
||||
</el-form-item>
|
||||
<el-form-item label="直播间背景墙" prop="coverImg">
|
||||
<upload-pic-thumb v-model="liveForm.coverImg" :multiple="false" />
|
||||
<div class="tips">直播间背景图,图片规则:建议像素1080*1920,大小不超过1M</div>
|
||||
</FormItem>
|
||||
|
||||
<!-- 直播间背景墙 -->
|
||||
<FormItem label="直播间分享图" prop="shareImg">
|
||||
<upload-pic-thumb v-model="liveForm.shareImg" :multiple="false"></upload-pic-thumb>
|
||||
</el-form-item>
|
||||
<el-form-item label="直播间分享图" prop="shareImg">
|
||||
<upload-pic-thumb v-model="liveForm.shareImg" :multiple="false" />
|
||||
<div class="tips">直播间分享图,图片规则:建议像素800*640,大小不超过1M</div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
|
||||
<FormItem label="商品" v-if="$route.query.id">
|
||||
<Button
|
||||
type="primary"
|
||||
ghost
|
||||
@click="liveGoodsVisible = true"
|
||||
:disabled="liveStatus != 'NEW'"
|
||||
icon="md-add"
|
||||
>添加商品</Button
|
||||
>
|
||||
<Table class="goods-table" :columns="liveColumns" :data="liveData">
|
||||
<template slot-scope="{ row, index }" slot="goodsName">
|
||||
<div class="flex-goods">
|
||||
<Badge v-if="index == 0 || index == 1" color="volcano"></Badge>
|
||||
<img class="thumbnail" :src="row.thumbnail || row.goodsImage" />
|
||||
{{ row.goodsName || row.name }}
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="{ row }" class="price" slot="price">
|
||||
<div>
|
||||
<div v-if="row.priceType == 1">{{ row.price | unitPrice("¥") }}</div>
|
||||
<el-form-item v-if="$route.query.id" label="商品">
|
||||
<el-button type="primary" plain :disabled="liveStatus != 'NEW'" @click="liveGoodsVisible = true">
|
||||
添加商品
|
||||
</el-button>
|
||||
<el-table class="goods-table" :data="liveData" style="width: 100%">
|
||||
<el-table-column label="商品" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="flex-goods">
|
||||
<el-badge v-if="$index === 0 || $index === 1" value=" " type="danger" />
|
||||
<img class="thumbnail" :src="row.thumbnail || row.goodsImage" alt="" />
|
||||
{{ row.goodsName || row.name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.priceType == 1">{{ $filters.unitPrice(row.price, "¥") }}</div>
|
||||
<div v-if="row.priceType == 2">
|
||||
{{ row.price | unitPrice("¥") }}至{{ row.price2 | unitPrice("¥") }}
|
||||
{{ $filters.unitPrice(row.price, "¥") }}至{{ $filters.unitPrice(row.price2, "¥") }}
|
||||
</div>
|
||||
<div v-if="row.priceType == 3">
|
||||
{{ row.price2 | unitPrice("¥")
|
||||
}}<span class="original-price">{{ row.price | unitPrice("¥") }}</span>
|
||||
{{ $filters.unitPrice(row.price2, "¥") }}
|
||||
<span class="original-price">{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="quantity">
|
||||
<div>{{ row.quantity }}</div>
|
||||
</template>
|
||||
<template slot-scope="{ row, index }" slot="action">
|
||||
<div class="action">
|
||||
<a
|
||||
v-if="liveStatus == 'NEW'"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="deleteGoods(row, index)"
|
||||
>删除</a>
|
||||
<span v-if="liveStatus == 'NEW'" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a
|
||||
v-if="liveStatus == 'NEW'"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="onMove(row.id, 1)"
|
||||
>上移</a>
|
||||
<span v-if="liveStatus == 'NEW'" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a
|
||||
v-if="liveStatus == 'NEW'"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="onMove(row.id, 0)"
|
||||
>下移</a>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<div class="tips">
|
||||
直播间商品中前两个商品将自动被选为封面,伴随直播间在直播列表中显示
|
||||
</div>
|
||||
</FormItem>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" width="100">
|
||||
<template #default="{ row }">{{ row.quantity }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="250">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="action">
|
||||
<template v-if="liveStatus == 'NEW'">
|
||||
<a class="link-text" @click="deleteGoods(row, $index)">删除</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="onMove(row.id, 1)">上移</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="onMove(row.id, 0)">下移</a>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="tips">直播间商品中前两个商品将自动被选为封面,伴随直播间在直播列表中显示</div>
|
||||
</el-form-item>
|
||||
|
||||
<FormItem>
|
||||
<Button type="primary" v-if="liveStatus == 'NEW'" @click="createLives()"
|
||||
>保存</Button
|
||||
>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Card>
|
||||
<!-- 浏览图片 -->
|
||||
<Modal title="查看图片" v-model="imageVisible">
|
||||
<img :src="imageSrc" v-if="imageVisible" style="width: 100%" />
|
||||
</Modal>
|
||||
<el-form-item>
|
||||
<el-button v-if="liveStatus == 'NEW'" type="primary" @click="createLives">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Modal width="800" v-model="liveGoodsVisible" footer-hide>
|
||||
<liveGoods @selectedGoods="callBackData" reviewed />
|
||||
</Modal>
|
||||
<el-dialog v-model="imageVisible" title="查看图片" width="600px">
|
||||
<img v-if="imageVisible" :src="imageSrc" style="width: 100%" alt="" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="liveGoodsVisible" width="800px" :show-footer="false">
|
||||
<liveGoods reviewed @selectedGoods="callBackData" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { uploadFile } from "@/libs/axios";
|
||||
import uploadPicThumb from "@/views/my-components/lili/upload-pic-thumb";
|
||||
import {
|
||||
addLive,
|
||||
addLiveGoods,
|
||||
editLive,
|
||||
getLiveInfo,
|
||||
delRoomLiveGoods,
|
||||
} from "@/api/promotion";
|
||||
import { addLive, addLiveGoods, editLive, getLiveInfo, delRoomLiveGoods } from "@/api/promotion";
|
||||
import liveGoods from "./liveGoods";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
liveGoods,
|
||||
uploadPicThumb,
|
||||
},
|
||||
components: { liveGoods, uploadPicThumb },
|
||||
data() {
|
||||
return {
|
||||
spinShow: false, // loading加载
|
||||
liveGoodsVisible: false, //选择商品
|
||||
imageVisible: false, //查看图片的dailog
|
||||
imageSrc: "", //查看图片的路径
|
||||
action: uploadFile, // 上传地址
|
||||
accessToken: {}, // 验证token
|
||||
liveStatus: "NEW", //当前直播状态
|
||||
// 不能选择今天以前的时间
|
||||
optionsTime: {
|
||||
disabledDate(date) {
|
||||
return date && date.valueOf() < Date.now() - 86400000;
|
||||
},
|
||||
},
|
||||
// 直播间数据上传规则
|
||||
spinShow: false,
|
||||
liveGoodsVisible: false,
|
||||
imageVisible: false,
|
||||
imageSrc: "",
|
||||
action: uploadFile,
|
||||
accessToken: {},
|
||||
liveStatus: "NEW",
|
||||
liveRulesForm: {
|
||||
name: [
|
||||
{ required: true, message: "请输入直播标题", trigger: "blur" },
|
||||
@@ -199,129 +147,72 @@ export default {
|
||||
{ max: 15, min: 2, message: "主播昵称最短2个汉字,最长15个汉字" },
|
||||
],
|
||||
anchorWechat: [{ required: true, message: "请输入主播微信号", trigger: "blur" }],
|
||||
startTime: [
|
||||
{
|
||||
required: true,
|
||||
message: "请正确输入开始时间以及结束时间",
|
||||
},
|
||||
],
|
||||
startTime: [{ required: true, message: "请正确输入开始时间以及结束时间" }],
|
||||
feedsImg: [{ required: true, message: "分享卡片封面不能为空", trigger: "blur" }],
|
||||
coverImg: [{ required: true, message: "直播间背景墙不能为空", trigger: "blur" }],
|
||||
shareImg: [{ required: true, message: "直播间分享图不能为空", trigger: "blur" }],
|
||||
},
|
||||
liveForm: {
|
||||
name: "", //直播标题
|
||||
anchorName: "", //主播昵称
|
||||
anchorWechat: "", //主播微信号
|
||||
feedsImg: "", //分享卡片封面
|
||||
coverImg: "", //直播间背景墙
|
||||
shareImg: "", //分享图
|
||||
name: "",
|
||||
anchorName: "",
|
||||
anchorWechat: "",
|
||||
feedsImg: "",
|
||||
coverImg: "",
|
||||
shareImg: "",
|
||||
startTime: "",
|
||||
},
|
||||
|
||||
times: [], //接收直播时间数据
|
||||
// 直播商品表格表头
|
||||
liveColumns: [
|
||||
{
|
||||
title: "商品",
|
||||
slot: "goodsName",
|
||||
},
|
||||
{
|
||||
title: "价格",
|
||||
slot: "price",
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
slot: "quantity",
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
width: 250,
|
||||
},
|
||||
],
|
||||
liveData: [], //直播商品集合
|
||||
times: [],
|
||||
liveData: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
/**
|
||||
* 如果query.id有值说明是查看详情
|
||||
* liveStatus 可以判断当前直播状态 从而区分数据 是否是未开始、已开启、已关闭、
|
||||
*/
|
||||
if (this.$route.query.id) {
|
||||
// 获取直播间详情
|
||||
this.getLiveDetail();
|
||||
}
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken"),
|
||||
};
|
||||
this.accessToken = { accessToken: this.getStore("accessToken") };
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 删除直播间商品
|
||||
*/
|
||||
disabledDate(date) {
|
||||
return date && date.valueOf() < Date.now() - 86400000;
|
||||
},
|
||||
async deleteGoods(val, index) {
|
||||
this.$Spin.show();
|
||||
let res = await delRoomLiveGoods(this.liveForm.roomId, val.liveGoodsId);
|
||||
this.spinShow = true;
|
||||
const res = await delRoomLiveGoods(this.liveForm.roomId, val.liveGoodsId);
|
||||
if (res.success) {
|
||||
this.$Message.success("删除成功!");
|
||||
this.liveData.splice(index, 1);
|
||||
this.$Spin.hide();
|
||||
} else {
|
||||
this.$Spin.hide();
|
||||
}
|
||||
this.spinShow = false;
|
||||
},
|
||||
/**
|
||||
* 获取直播间详情
|
||||
*/
|
||||
async getLiveDetail() {
|
||||
let result = await getLiveInfo(this.$route.query.id);
|
||||
|
||||
// 将数据回调到liveform里面
|
||||
const result = await getLiveInfo(this.$route.query.id);
|
||||
if (result.success) {
|
||||
console.log(result);
|
||||
let data = result.result;
|
||||
for (let key in data) {
|
||||
const data = result.result;
|
||||
for (const key in data) {
|
||||
this.liveForm[key] = data[key];
|
||||
}
|
||||
// 将选择的商品回调给表格
|
||||
|
||||
this.liveData = data.commodityList;
|
||||
|
||||
// 将时间格式化
|
||||
this.$set(
|
||||
this.times,
|
||||
[0],
|
||||
this.$options.filters.unixToDate(data.startTime, "yyyy-MM-dd hh:mm")
|
||||
);
|
||||
this.$set(
|
||||
this.times,
|
||||
[1],
|
||||
this.$options.filters.unixToDate(data.endTime, "yyyy-MM-dd hh:mm")
|
||||
);
|
||||
this.times = [
|
||||
this.$filters.unixToDate(data.startTime, "yyyy-MM-dd hh:mm"),
|
||||
this.$filters.unixToDate(data.endTime, "yyyy-MM-dd hh:mm"),
|
||||
];
|
||||
this.liveStatus = data.status;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 上下移动功能
|
||||
* dir 1为上 0为下
|
||||
*/
|
||||
onMove(code, dir) {
|
||||
let moveComm = (curIndex, nextIndex) => {
|
||||
let arr = this.liveData;
|
||||
const moveComm = (curIndex, nextIndex) => {
|
||||
const arr = this.liveData;
|
||||
arr[curIndex] = arr.splice(nextIndex, 1, arr[curIndex])[0];
|
||||
return arr;
|
||||
};
|
||||
this.liveData.some((val, index) => {
|
||||
if (val.id === code) {
|
||||
if (dir === 1 && index === 0) {
|
||||
this.$message.Warning("已在顶部!");
|
||||
this.$Message.warning("已在顶部!");
|
||||
} else if (dir === 0 && index === this.liveData.length - 1) {
|
||||
this.$message.Warning("已在底部!");
|
||||
this.$Message.warning("已在底部!");
|
||||
} else {
|
||||
let nextIndex = dir === 1 ? index - 1 : index + 1;
|
||||
const nextIndex = dir === 1 ? index - 1 : index + 1;
|
||||
this.liveData = moveComm(index, nextIndex);
|
||||
}
|
||||
return true;
|
||||
@@ -329,13 +220,9 @@ export default {
|
||||
return false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 回调的商品选择数据
|
||||
*/
|
||||
callBackData(way) {
|
||||
console.log(way);
|
||||
this.liveGoodsVisible = false;
|
||||
this.$Spin.show();
|
||||
this.spinShow = true;
|
||||
addLiveGoods({
|
||||
roomId: this.$route.query.roomId,
|
||||
liveGoodsId: way.liveGoodsId,
|
||||
@@ -343,179 +230,53 @@ export default {
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
this.liveData.push(way);
|
||||
this.$Spin.hide();
|
||||
console.log(this.liveData);
|
||||
} else {
|
||||
this.$Spin.hide();
|
||||
}
|
||||
this.spinShow = false;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 上传图片查看图片
|
||||
*/
|
||||
handleView(src) {
|
||||
this.imageVisible = true;
|
||||
this.imageSrc = src;
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除上传的图片
|
||||
*/
|
||||
handleRemove(type) {
|
||||
if (this.liveStatus == "NEW") {
|
||||
this.liveForm[type] = "";
|
||||
} else {
|
||||
this.$Message.error("当前状态禁止修改删除!");
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 直播间背景图上传成功回调
|
||||
*/
|
||||
handleCoverImgSuccess(res) {
|
||||
this.liveForm.coverImg = res.result;
|
||||
},
|
||||
/**
|
||||
* 直播间分享图上传成功回调
|
||||
*/
|
||||
handleShareImgSuccess(res) {
|
||||
console.log(res);
|
||||
this.liveForm.shareImg = res.result;
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享卡片封面上传成功回调
|
||||
*/
|
||||
handleFeedsImgSuccess(res) {
|
||||
this.liveForm.feedsImg = res.result;
|
||||
},
|
||||
|
||||
/**
|
||||
* 直播间背景图
|
||||
*/
|
||||
handleCoverImgSuccess(res) {
|
||||
this.liveForm.coverImg = res.result;
|
||||
},
|
||||
|
||||
tipsDateError() {
|
||||
this.$Message.error({
|
||||
content:
|
||||
"直播开播时间需要在当前时间的10分钟后并且,开始时间不能在6个月后,直播计划结束时间(开播时间和结束时间间隔不得短于30分钟,不得超过24小时)",
|
||||
duration: 5,
|
||||
});
|
||||
this.$Message.error(
|
||||
"直播开播时间需要在当前时间的10分钟后并且,开始时间不能在6个月后,直播计划结束时间(开播时间和结束时间间隔不得短于30分钟,不得超过24小时)"
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择时间后的回调
|
||||
*/
|
||||
handleChangeTime(daterange) {
|
||||
/**
|
||||
* 直播开播时间需要在当前时间的10分钟后
|
||||
* 此处设置默认为15分钟方便调整
|
||||
*/
|
||||
let siteTime = new Date().getTime() / 1000;
|
||||
let selectTime = new Date(daterange[0]).getTime() / 1000;
|
||||
let currentTime = this.$options.filters.unixToDate(siteTime);
|
||||
/**
|
||||
* 开播时间和结束时间间隔不得短于30分钟,不得超过24小时
|
||||
* 判断用户设置的结束时间
|
||||
*/
|
||||
let endTime = new Date(daterange[1]).getTime() / 1000;
|
||||
if (!daterange || daterange.length !== 2) return;
|
||||
const siteTime = new Date().getTime() / 1000;
|
||||
const selectTime = new Date(daterange[0]).getTime() / 1000;
|
||||
const endTime = new Date(daterange[1]).getTime() / 1000;
|
||||
if (selectTime <= siteTime + 15 * 60) {
|
||||
this.tipsDateError();
|
||||
return false;
|
||||
} else if (selectTime + 30 * 60 >= endTime) {
|
||||
// 不能小于30分钟
|
||||
|
||||
this.tipsDateError();
|
||||
return false;
|
||||
} else if (selectTime + 24 * 60 * 60 <= endTime) {
|
||||
// 不能超过24小时
|
||||
|
||||
this.tipsDateError();
|
||||
return false;
|
||||
} else if (
|
||||
// 不能超过6个月
|
||||
siteTime >=
|
||||
new Date().getTime() + 6 * 31 * 24 * 3600 * 1000 + 86400000
|
||||
) {
|
||||
this.tipsDateError();
|
||||
return false;
|
||||
} else {
|
||||
this.$set(this.times, [0], currentTime);
|
||||
this.times[1] = daterange[1];
|
||||
|
||||
// this.times = daterange;
|
||||
this.$set(this.liveForm, "startTime", new Date(daterange[0]).getTime() / 1000);
|
||||
this.$set(this.liveForm, "endTime", new Date(daterange[1]).getTime() / 1000);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 对图片错误进行回调
|
||||
*/
|
||||
handleFormatError(file) {
|
||||
this.$Notice.warning({
|
||||
title: "请上传正确的图片格式!",
|
||||
desc: file.name + " 格式不为 jpg or png.",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 对图片的大小进行处理回调
|
||||
*/
|
||||
handleMaxSize(file) {
|
||||
this.$Notice.warning({
|
||||
title: "图片超过限制大小!",
|
||||
desc: "图片超过规定限制大小,请重新上传",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 限制只能上传一张图片
|
||||
*/
|
||||
handleBeforeUpload(type) {
|
||||
const check = this.liveForm[type].length < 1;
|
||||
if (!check) {
|
||||
this.$Notice.warning({
|
||||
title: "最多上传一张图片",
|
||||
});
|
||||
if (selectTime + 30 * 60 >= endTime || selectTime + 24 * 60 * 60 <= endTime) {
|
||||
this.tipsDateError();
|
||||
return;
|
||||
}
|
||||
return check;
|
||||
this.liveForm.startTime = selectTime;
|
||||
this.liveForm.endTime = endTime;
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加直播间 /broadcast/studio/edit
|
||||
*/
|
||||
createLives() {
|
||||
this.$refs["liveForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
// 需判断当前是否是添加商品
|
||||
if (this.$route.query.id) {
|
||||
this.spinShow = true;
|
||||
this.liveForm.commodityList = JSON.stringify(this.liveForm.commodityList);
|
||||
delete this.liveForm.updateTime;
|
||||
// 将当前直播间修改
|
||||
editLive(this.liveForm).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功!");
|
||||
|
||||
this.$router.push({ path: "/promotion/live" });
|
||||
}
|
||||
this.spinShow = false;
|
||||
});
|
||||
} else {
|
||||
// 此处为创建直播
|
||||
this.spinShow = true;
|
||||
addLive(this.liveForm).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功!");
|
||||
|
||||
this.$router.push({ path: "/live" });
|
||||
}
|
||||
this.spinShow = false;
|
||||
});
|
||||
}
|
||||
this.$refs.liveForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.spinShow = true;
|
||||
if (this.$route.query.id) {
|
||||
this.liveForm.commodityList = JSON.stringify(this.liveForm.commodityList);
|
||||
delete this.liveForm.updateTime;
|
||||
editLive(this.liveForm).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功!");
|
||||
this.$router.push({ path: "/promotion/live" });
|
||||
}
|
||||
this.spinShow = false;
|
||||
});
|
||||
} else {
|
||||
addLive(this.liveForm).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功!");
|
||||
this.$router.push({ path: "/live" });
|
||||
}
|
||||
this.spinShow = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -526,9 +287,6 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.action {
|
||||
display: flex;
|
||||
::v-deep .ivu-btn {
|
||||
margin: 0 5px !important;
|
||||
}
|
||||
}
|
||||
.original-price {
|
||||
margin-left: 10px;
|
||||
@@ -543,7 +301,6 @@ export default {
|
||||
.flex-goods {
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
|
||||
align-items: center;
|
||||
> img {
|
||||
margin-right: 10px;
|
||||
@@ -557,40 +314,13 @@ export default {
|
||||
width: 1000px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.upload-list {
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
margin-right: 4px;
|
||||
}
|
||||
.upload-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.upload-list-cover {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.upload-list:hover .upload-list-cover {
|
||||
display: block;
|
||||
}
|
||||
.upload-list-cover i {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,38 +1,69 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="100" class="search-form">
|
||||
<el-card>
|
||||
<el-tabs v-model="searchForm.status">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in tabs"
|
||||
:key="index"
|
||||
:name="item.status"
|
||||
:label="item.title"
|
||||
/>
|
||||
</el-tabs>
|
||||
|
||||
<Form-item label="直播状态" prop="promotionStatus">
|
||||
<Select v-model="searchForm.status" placeholder="请选择" clearable style="width: 240px">
|
||||
<Option value="NEW">未开始</Option>
|
||||
<Option value="START">直播中</Option>
|
||||
<Option value="END">已结束</Option>
|
||||
<el-table :data="liveData" style="width: 100%">
|
||||
<el-table-column prop="name" label="直播标题" />
|
||||
<el-table-column prop="anchorName" label="主播昵称" />
|
||||
<el-table-column label="直播开始时间">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ $filters.unixToDate(row.startTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="直播结束时间">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ $filters.unixToDate(row.endTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否推荐" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.recommend"
|
||||
inline-prompt
|
||||
active-text="是"
|
||||
inactive-text="否"
|
||||
@change="star(row, $index)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="直播状态">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-if="row.status == 'NEW'" type="primary">未开始</el-tag>
|
||||
<el-tag v-else-if="row.status == 'START'" type="success">直播中</el-tag>
|
||||
<el-tag v-else type="warning">已结束</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<a v-if="row" class="link-text" @click="getLiveDetail(row)">查看</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</Select>
|
||||
</Form-item>
|
||||
|
||||
<Button @click="handleSearch" type="primary" class="search-btn" icon="ios-search">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<div class="btns">
|
||||
<Button @click="createLive()" type="primary">创建直播</Button>
|
||||
<div class="mt_10 page" style="display: flex; justify-content: flex-end; margin: 20px 0">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePageNumber"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
<Tabs v-model="searchForm.status">
|
||||
<!-- 标签栏 -->
|
||||
<TabPane v-for="(item,index) in tabs" :key="index" :name="item.status" :label="item.title">
|
||||
|
||||
</TabPane>
|
||||
|
||||
</Tabs>
|
||||
<Table :columns="liveColumns" :data="liveData"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePageNumber" @on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]"
|
||||
size="small" show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -41,108 +72,18 @@ import { getLiveList } from "@/api/promotion.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 查询数据的总数
|
||||
total: 0,
|
||||
// 查询的form
|
||||
searchForm: {
|
||||
pageSize: 20,
|
||||
pageNumber: 1,
|
||||
status: "NEW",
|
||||
},
|
||||
// 直播tab选项栏
|
||||
tabs: [
|
||||
{
|
||||
title: "直播中",
|
||||
status: "START",
|
||||
},
|
||||
{
|
||||
title: "未开始",
|
||||
status: "NEW",
|
||||
},
|
||||
{
|
||||
title: "已结束",
|
||||
status: "END",
|
||||
},
|
||||
{ title: "直播中", status: "START" },
|
||||
{ title: "未开始", status: "NEW" },
|
||||
{ title: "已结束", status: "END" },
|
||||
],
|
||||
liveColumns: [
|
||||
{
|
||||
title: "直播标题",
|
||||
key: "name",
|
||||
},
|
||||
{
|
||||
title: "主播昵称",
|
||||
key: "anchorName",
|
||||
},
|
||||
{
|
||||
title: "直播开始时间",
|
||||
key: "createTime",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"span",
|
||||
|
||||
this.$options.filters.unixToDate(params.row.startTime)
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "直播结束时间",
|
||||
key: "endTime",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"span",
|
||||
|
||||
this.$options.filters.unixToDate(params.row.endTime)
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "直播状态",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"span",
|
||||
params.row.status == "NEW"
|
||||
? "未开始"
|
||||
: params.row.status == "START"
|
||||
? "直播中"
|
||||
: "已结束"
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
{
|
||||
style: {
|
||||
display: "flex",
|
||||
},
|
||||
},
|
||||
[
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.getLiveDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看/添加商品"
|
||||
),
|
||||
]
|
||||
);
|
||||
},
|
||||
},
|
||||
], //table中显示的title
|
||||
liveData: [], //table中显示的直播数据
|
||||
liveData: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@@ -158,33 +99,17 @@ export default {
|
||||
this.getStoreLives();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 搜索直播间状态
|
||||
*/
|
||||
handleSearch() {
|
||||
async star(val, index) {
|
||||
let switched = this.liveData[index].recommend;
|
||||
await whetherStar({ id: val.id, recommend: switched });
|
||||
this.getStoreLives();
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面数据大小分页回调
|
||||
*/
|
||||
changePageSize(val) {
|
||||
console.log(val)
|
||||
this.searchForm.pageSize = val;
|
||||
changePageSize() {
|
||||
this.getStoreLives();
|
||||
},
|
||||
/**
|
||||
* 分页回调
|
||||
*/
|
||||
changePageNumber(val) {
|
||||
console.log(val)
|
||||
this.searchForm.pageNumber = val;
|
||||
changePageNumber() {
|
||||
this.getStoreLives();
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取店铺直播间列表
|
||||
*/
|
||||
async getStoreLives() {
|
||||
let result = await getLiveList(this.searchForm);
|
||||
if (result.success) {
|
||||
@@ -192,29 +117,17 @@ export default {
|
||||
this.total = result.result.total;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取直播间详情
|
||||
*/
|
||||
getLiveDetail(val) {
|
||||
this.$router.push({
|
||||
path: "/add-live",
|
||||
path: "/live-detail",
|
||||
query: { ...val, liveStatus: this.searchForm.status },
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 创建直播
|
||||
*/
|
||||
createLive() {
|
||||
this.$router.push({ path: "/add-live" });
|
||||
},
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
.btns {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
|
||||
@@ -1,393 +1,244 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="params" inline :label-width="100" class="search-form">
|
||||
<Form-item label="商品名称">
|
||||
<Input type="text" v-model="params.name" placeholder="请输入商品名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form :model="liveForm" ref="liveForm" :rules="liveRulesForm" label-width="120px">
|
||||
<el-form-item label="直播标题" prop="name">
|
||||
<el-input disabled v-model="liveForm.name" style="width:460px"></el-input>
|
||||
<div class="tips">直播间名字,最短3个汉字,最长17个汉字,1个汉字相当于2个字符</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="主播昵称" prop="anchorName">
|
||||
<el-input disabled v-model="liveForm.anchorName" style="width:360px"></el-input>
|
||||
<div class="tips">主播昵称,最短2个汉字,最长15个汉字,1个汉字相当于2个字符</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="直播时间" prop="startTime">
|
||||
<el-date-picker
|
||||
disabled
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
type="datetimerange"
|
||||
v-model="times"
|
||||
@change="handleChangeTime"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placeholder="直播计划开始时间-直播计划结束时间"
|
||||
style="width: 300px"
|
||||
/>
|
||||
<div class="tips">直播开播时间需要在当前时间的10分钟后 并且 开始时间不能在 6 个月后</div>
|
||||
</el-form-item>
|
||||
|
||||
<Button @click="getLiveGoodsMethods('clear')" type="primary" class="search-btn" icon="ios-search">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<h4 v-if="!reviewed">
|
||||
由于直播商品需经过小程序直播平台的审核,你需要在此先提审商品,为了不影响直播间选取商品,请提前1天提审商品;
|
||||
</h4>
|
||||
<el-form-item label="主播微信号" prop="anchorWechat">
|
||||
<el-input disabled v-model="liveForm.anchorWechat" style="width:360px" placeholder="主播微信号"></el-input>
|
||||
<div class="tips">主播微信号,如果未实名认证,需要先前往“小程序直播”小程序进行<a target="_black" href="https://res.wx.qq.com/op_res/9rSix1dhHfK4rR049JL0PHJ7TpOvkuZ3mE0z7Ou_Etvjf-w1J_jVX0rZqeStLfwh">实名验证</a></div>
|
||||
</el-form-item>
|
||||
|
||||
<div>
|
||||
<Tabs v-model="params.auditStatus">
|
||||
<TabPane v-for="(item,index) in liveTabWay" :key="index" :label="item.label" :name="item.type+''">
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<Button v-if="!reviewed" type="primary" style="margin-bottom:10px;" @click="addNewLiveGoods" icon="md-add">选择商品</Button>
|
||||
<Button type="primary" v-if="params.auditStatus == 0" ghost style="margin:0 0 10px 10px" @click="getLiveGoodsMethods('clear')">更新状态</Button>
|
||||
<div style="position:relative">
|
||||
<Spin size="large" fix v-if="tableLoading">
|
||||
</Spin>
|
||||
<Table class="mt_10" disabled-hover :columns="liveGoodsColumns" :data="liveGoodsData">
|
||||
|
||||
<template slot-scope="{ row }" slot="goodsName">
|
||||
<div class="flex-goods">
|
||||
<img class="thumbnail" :src="row.thumbnail || row.goodsImage">
|
||||
{{ row.goodsName || row.name }}
|
||||
<el-form-item label="分享卡片封面" prop="feedsImg">
|
||||
<div class="upload-list" v-if="liveForm.feedsImg">
|
||||
<img :src="liveForm.feedsImg">
|
||||
<div class="upload-list-cover" @click="handleView(liveForm.feedsImg)">
|
||||
<span class="view-icon">查看</span>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="{ row ,index }" class="price" slot="price">
|
||||
<!-- 如果为新增商品显示 -->
|
||||
</div>
|
||||
<div class="tips">
|
||||
直播间分享图,图片规则:建议像素800*640,大小不超过1M;
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<RadioGroup v-if="params.auditStatus == 99" @on-change="changeRadio(row,'priceType')" v-model="row.priceType">
|
||||
<div class="price-item">
|
||||
<Radio :label="1">一口价:</Radio>
|
||||
<InputNumber :min="0.1" v-if="liveGoodsData[index].priceType == 1" style="width:100px" v-model="liveGoodsData[index].price"></InputNumber>
|
||||
</div>
|
||||
<div class="price-item">
|
||||
<Radio :label="2">区间价:</Radio> <span v-if="liveGoodsData[index].priceType == 2">
|
||||
<InputNumber :min="0.1" style="width:100px" v-model="liveGoodsData[index].price" />至
|
||||
<InputNumber :min="0.1" style="width:100px" v-model="liveGoodsData[index].price2" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="price-item">
|
||||
<Radio :label="3">折扣价:</Radio> <span v-if="liveGoodsData[index].priceType == 3">原价<InputNumber :min="0.1" style="width:100px" v-model="liveGoodsData[index].price"></InputNumber>现价
|
||||
<InputNumber :min="0.1" style="width:100px" v-model="liveGoodsData[index].price2" />
|
||||
</span>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
<div v-else>
|
||||
<div v-if="row.priceType == 1"><priceColorScheme :value="row.price" :color="$mainColor" /></div>
|
||||
<div class="flex" v-if="row.priceType == 2"><priceColorScheme :value="row.price" :color="$mainColor" />至<priceColorScheme :value="row.price2" :color="$mainColor" /></div>
|
||||
<div class="flex" v-if="row.priceType == 3"><priceColorScheme :value="row.price2" :color="$mainColor" /><span class="original-price">{{row.price | unitPrice('¥')}}</span></div>
|
||||
<el-form-item label="直播间背景墙" prop="coverImg">
|
||||
<div class="upload-list" v-if="liveForm.coverImg">
|
||||
<img :src="liveForm.coverImg">
|
||||
<div class="upload-list-cover" @click="handleView(liveForm.coverImg)">
|
||||
<span class="view-icon">查看</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tips"> 直播间背景图,图片规则:建议像素1080*1920,大小不超过1M</div>
|
||||
</el-form-item>
|
||||
|
||||
</template>
|
||||
<el-form-item label="直播间分享图" prop="shareImg">
|
||||
<div class="upload-list" v-if="liveForm.shareImg">
|
||||
<img :src="liveForm.shareImg">
|
||||
<div class="upload-list-cover" @click="handleView(liveForm.shareImg)">
|
||||
<span class="view-icon">查看</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tips"> 直播间分享图,图片规则:建议像素800*640,大小不超过1M</div>
|
||||
</el-form-item>
|
||||
|
||||
<template slot-scope="{ row ,index }" slot="action">
|
||||
<a v-if="params.auditStatus == 99" @click="liveGoodsData.splice(index,1)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">删除</a>
|
||||
<span v-if="params.auditStatus == 99 || (params.auditStatus != 99 && !reviewed) || reviewed" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-if="params.auditStatus != 99 && !reviewed" @click="$router.push({path:'/goods-operation-edit',query:{id:row.goodsId}})" style="color:#2d8cf0;cursor:pointer;text-decoration:none">查看</a>
|
||||
<span v-if="reviewed" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-if="reviewed" @click="selectedLiveGoods(row,index)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">{{row.___selected ? '已':''}}选择</a>
|
||||
</template>
|
||||
</Table>
|
||||
<div class="flex">
|
||||
<Page size="small" :total="goodsTotal" @on-change="changePageNumber" class="pageration" @on-page-size-change="changePageSize" :page-size="params.pageSize" show-total show-elevator
|
||||
show-sizer>
|
||||
</Page>
|
||||
<el-form-item label="商品" v-if="$route.query.id">
|
||||
<el-table class="goods-table" border :data="liveData" style="width: 100%">
|
||||
<el-table-column label="商品" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<div v-if="row" class="flex-goods">
|
||||
<el-badge v-if="$index == 0 || $index == 1" is-dot type="danger" />
|
||||
<img class="thumbnail" :src="row.thumbnail || row.goodsImage">
|
||||
{{ row.goodsName || row.name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" min-width="160">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row">
|
||||
<div v-if="row.priceType == 1">{{ $filters.unitPrice(row.price, '¥') }}</div>
|
||||
<div v-if="row.priceType == 2">{{ $filters.unitPrice(row.price, '¥') }}至{{ $filters.unitPrice(row.price2, '¥') }}</div>
|
||||
<div v-if="row.priceType == 3">
|
||||
{{ $filters.unitPrice(row.price, '¥') }}
|
||||
<span class="original-price">{{ $filters.unitPrice(row.price2, '¥') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.quantity }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="tips">
|
||||
直播间商品中前两个商品将自动被选为封面,伴随直播间在直播列表中显示
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<sku-select ref="skuSelect" @selectedGoodsData="selectedGoodsData"></sku-select>
|
||||
<div v-if="params.auditStatus == 99" class="submit">
|
||||
<Button type="primary" :loading="saveGoodsLoading" @click="saveLiveGoods">保存商品</Button>
|
||||
</div>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="createLives()">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="imageVisible" title="查看图片" width="600px">
|
||||
<img :src="imageSrc" v-if="imageVisible" style="width: 100%">
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import skuSelect from "@/views/lili-dialog"; //选择商品组件
|
||||
import { addLiveStoreGoods, getLiveGoods } from "@/api/promotion.js";
|
||||
export default {
|
||||
components: {
|
||||
skuSelect,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
goodsTotal: 0, //商品总数
|
||||
saveGoodsLoading: false, //保存商品加载
|
||||
tableLoading: false, //表格是否加载
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
auditStatus: 2, //商品状态
|
||||
imageVisible: false,
|
||||
imageSrc: "",
|
||||
liveForm: {
|
||||
name: "",
|
||||
anchorName: "",
|
||||
anchorWechat: "",
|
||||
feedsImg: "",
|
||||
coverImg: "",
|
||||
shareImg: "",
|
||||
startTime: "",
|
||||
},
|
||||
// 商品审核状态
|
||||
liveTabWay: [
|
||||
{
|
||||
label: "待提审",
|
||||
type: 0,
|
||||
},
|
||||
{
|
||||
label: "已审核",
|
||||
type: 2,
|
||||
},
|
||||
|
||||
{
|
||||
label: "审核中",
|
||||
type: 1,
|
||||
},
|
||||
|
||||
{
|
||||
label: "审核未通过",
|
||||
type: 3,
|
||||
},
|
||||
],
|
||||
|
||||
// 商品表格columns
|
||||
liveGoodsColumns: [
|
||||
{
|
||||
title: "商品",
|
||||
slot: "goodsName",
|
||||
},
|
||||
{
|
||||
title: "价格",
|
||||
slot: "price",
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
width: 100,
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
// 表格商品详情
|
||||
liveGoodsData: [],
|
||||
// 已选商品
|
||||
selectedGoods: [],
|
||||
times: [],
|
||||
liveData: [],
|
||||
commodityList: "",
|
||||
};
|
||||
},
|
||||
props: {
|
||||
// 是否是已审核,此处为组件模式时使用。去除添加等功能 只保留查询以及新增选择回调数据
|
||||
reviewed: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 初始化信息,此处为组件模式时使用。父级将数据传输到此方法上
|
||||
init: {
|
||||
type: null,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
//此处为组件模式时使用 监听此处为开启则需要删除tab上面的数据只显示已审核
|
||||
reviewed: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.liveTabWay = this.liveTabWay.filter((item) => {
|
||||
return item.label == "已审核";
|
||||
});
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
//此处为组件模式时使用 监听父级给传值
|
||||
init: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.$nextTick(() => {
|
||||
// 将当前父级返回的数据和当前数据进行匹配
|
||||
this.selectedGoods = val;
|
||||
this.liveGoodsData.forEach((item, index) => {
|
||||
val.forEach((callback) => {
|
||||
if (item.id == callback.id) {
|
||||
this.$set(this.liveGoodsData[index], "___selected", true);
|
||||
// this.selectedGoods.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
// 监听如果次数变化说明用户再点击tab
|
||||
"params.auditStatus": {
|
||||
handler(val) {
|
||||
this.liveGoodsData = [];
|
||||
if (val != 99) {
|
||||
this.params.pageNumber = 1;
|
||||
this.getLiveGoodsMethods();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
mounted() {
|
||||
if (this.$route.query.id) {
|
||||
this.getLiveDetail();
|
||||
}
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken"),
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 回调参数补充
|
||||
*/
|
||||
selectedLiveGoods(val, index) {
|
||||
this.$emit("selectedGoods", val);
|
||||
handleView(src) {
|
||||
this.imageVisible = true;
|
||||
this.imageSrc = src;
|
||||
},
|
||||
/**
|
||||
* 解决radio数据不回显问题
|
||||
*/
|
||||
changeRadio(val) {
|
||||
this.$set(this.liveGoodsData[val._index], "priceType", val.priceType);
|
||||
},
|
||||
/**
|
||||
* 页面数据大小分页回调
|
||||
*/
|
||||
changePageSize(val) {
|
||||
this.params.pageSize = val;
|
||||
this.getLiveGoodsMethods("clear");
|
||||
},
|
||||
/**
|
||||
* 分页回调
|
||||
*/
|
||||
changePageNumber(val) {
|
||||
this.params.pageNumber = val;
|
||||
this.getLiveGoodsMethods("clear");
|
||||
},
|
||||
/**
|
||||
* 清除新增的tab
|
||||
*/
|
||||
clearNewLiveTab() {
|
||||
this.liveTabWay.map((item, index) => {
|
||||
return item.type == 99 && this.liveTabWay.splice(index, 1);
|
||||
handleMaxSize(file) {
|
||||
this.$Notice.warning({
|
||||
title: "文件大小过大",
|
||||
desc: "所选文件大小过大, 不得超过 1M.",
|
||||
});
|
||||
},
|
||||
async getLiveDetail() {
|
||||
let result = await getLiveInfo(this.$route.query.id);
|
||||
|
||||
/**
|
||||
* 查询商品
|
||||
*/
|
||||
async getLiveGoodsMethods(type) {
|
||||
this.tableLoading = true;
|
||||
|
||||
let result = await getLiveGoods(this.params);
|
||||
if (result.success) {
|
||||
// 将表格数据清除
|
||||
if (type == "clear") {
|
||||
this.liveGoodsData = [];
|
||||
let data = result.result;
|
||||
for (let key in data) {
|
||||
this.liveForm[key] = data[key];
|
||||
}
|
||||
this.liveGoodsData.push(...result.result.records);
|
||||
this.goodsTotal = result.result.total;
|
||||
|
||||
this.liveData = data.commodityList;
|
||||
this.commodityList = data.commodityList;
|
||||
|
||||
this.times = [
|
||||
this.$filters.unixToDate(data.startTime, "yyyy-MM-dd hh:mm"),
|
||||
this.$filters.unixToDate(data.endTime, "yyyy-MM-dd hh:mm"),
|
||||
];
|
||||
this.liveStatus = data.status;
|
||||
}
|
||||
this.tableLoading = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存直播商品
|
||||
*/
|
||||
async saveLiveGoods() {
|
||||
this.saveGoodsLoading = true;
|
||||
let submit = this.liveGoodsData.map((element) => {
|
||||
|
||||
return {
|
||||
goodsId: element.goodsId, //商品id
|
||||
goodsImage: element.small, //商品图片 最大为 300 * 300
|
||||
name: element.goodsName, //商品昵称
|
||||
price: parseInt(element.price), //商品价格
|
||||
quantity: element.quantity, //库存
|
||||
price2: element.price2 ? parseInt(element.price2) : "", //商品价格
|
||||
priceType: element.priceType, // priceType Number 是 价格类型,1:一口价(只需要传入price,price2不传) 2:价格区间(price字段为左边界,price2字段为右边界,price和price2必传) 3:显示折扣价(price字段为原价,price2字段为现价, price和price2必传)
|
||||
skuId: element.id,
|
||||
url: `pages/product/goods?id=${element.id}&goodsId=${element.goodsId}`, //小程序地址
|
||||
};
|
||||
});
|
||||
|
||||
let result = await addLiveStoreGoods(submit);
|
||||
if (result.success) {
|
||||
this.$Message.success({
|
||||
content: `添加成功!`,
|
||||
});
|
||||
|
||||
this.params.auditStatus = 0;
|
||||
}
|
||||
this.saveGoodsLoading = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 商品选择器回调的商品信息
|
||||
*/
|
||||
selectedGoodsData(goods) {
|
||||
goods.map((item) => {
|
||||
return (item.priceType = 1);
|
||||
});
|
||||
|
||||
this.liveGoodsData.push(...goods);
|
||||
},
|
||||
|
||||
/**
|
||||
* 新增商品
|
||||
*/
|
||||
addNewLiveGoods() {
|
||||
this.clearNewLiveTab();
|
||||
this.liveTabWay.push({
|
||||
type: 99,
|
||||
label: "新增商品",
|
||||
});
|
||||
this.$set(this, "liveGoodsData", []);
|
||||
this.params.auditStatus = 99;
|
||||
this.$refs.skuSelect.open("goods");
|
||||
this.$refs.skuSelect.goodsData = JSON.parse(
|
||||
JSON.stringify(this.liveGoodsData)
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
.search-form {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.flex {
|
||||
.action {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.thumbnail {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
.flex-goods {
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
|
||||
align-items: center;
|
||||
> img {
|
||||
margin-right: 10px;
|
||||
:deep(.el-button) {
|
||||
margin: 0 5px !important;
|
||||
}
|
||||
}
|
||||
.price-item {
|
||||
margin: 15px 5px;
|
||||
> * {
|
||||
margin: 5px;
|
||||
}
|
||||
}
|
||||
.submit {
|
||||
box-shadow: 3px 5px 12px rgba(0, 0, 0, 0.1);
|
||||
height: 60px;
|
||||
background: #fff;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.original-price {
|
||||
margin-left: 10px;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: 10px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #f8f8f8;
|
||||
color: #333;
|
||||
font-size: 12px;
|
||||
line-height: 40px;
|
||||
text-align: left;
|
||||
.thumbnail {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
.flex{
|
||||
.flex-goods {
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
> img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.tips {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.goods-table {
|
||||
width: 1000px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.upload-list {
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
margin-right: 4px;
|
||||
}
|
||||
.upload-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.upload-list-cover {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.upload-list:hover .upload-list-cover {
|
||||
display: block;
|
||||
}
|
||||
.view-icon {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,187 +1,179 @@
|
||||
<template>
|
||||
<div class="new-pintuan">
|
||||
<Card>
|
||||
<Form ref="form" :model="form" :label-width="130" :rules="formValidate">
|
||||
<FormItem label="活动名称" prop="promotionName" :label-width="130">
|
||||
<Input v-model="form.promotionName" clearable style="width: 260px" maxlength="25" />
|
||||
<div style="color: #cccccc">
|
||||
活动名称将显示在对人拼团活动列表中,方便商家管理使用,最多输入25个字符
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="活动时间" prop="rangeTime">
|
||||
<DatePicker type="datetimerange" v-model="form.rangeTime" format="yyyy-MM-dd HH:mm:ss" placeholder="请选择" :options="options" style="width: 260px">
|
||||
</DatePicker>
|
||||
</FormItem>
|
||||
<div class="pintuan-goods">
|
||||
<el-card>
|
||||
<h4>活动详情</h4>
|
||||
<el-table border :data="data" style="width: 100%; margin: 10px 0">
|
||||
<el-table-column prop="promotionName" label="活动名称" min-width="120" />
|
||||
<el-table-column prop="startTime" label="活动开始时间" min-width="120" />
|
||||
<el-table-column prop="endTime" label="活动结束时间" min-width="120" />
|
||||
<el-table-column prop="requiredNum" label="成团人数" min-width="90" />
|
||||
<el-table-column prop="limitNum" label="限购数量" min-width="90" />
|
||||
<el-table-column label="状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="promotionStatusTagType(row.promotionStatus)">
|
||||
{{ promotionStatusText(row.promotionStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<FormItem label="参团人数" prop="requiredNum" :label-width="130">
|
||||
<Input v-model="form.requiredNum" style="width: 260px" max="8">
|
||||
<span slot="append">人</span>
|
||||
</Input>
|
||||
<span style="color: #cccccc">参团人数不少于2人,不得超过10人。</span>
|
||||
</FormItem>
|
||||
<FormItem label="限购数量" prop="limitNum" :label-width="130">
|
||||
<Input v-model="form.limitNum" type="number" style="width: 260px">
|
||||
<span slot="append">件/人</span>
|
||||
</Input>
|
||||
<span style="color: #cccccc">如果设置为0则视为不限制购买数量</span>
|
||||
</FormItem>
|
||||
<FormItem label="虚拟成团" prop="fictitious">
|
||||
<RadioGroup type="button" button-style="solid" v-model="form.fictitious">
|
||||
<Radio title="开启" :label="1">
|
||||
<span>开启</span>
|
||||
</Radio>
|
||||
<Radio title="关闭" :label="0">
|
||||
<span>关闭</span>
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
<br />
|
||||
<span style="color: #cccccc">开启虚拟成团后,24小时人数未满的团,系统将会模拟匿名买家凑满人数,使该团成团;您只需要对已付款参团的真实买家发货;建议合理开启以提高成团率</span>
|
||||
</FormItem>
|
||||
<FormItem label="拼团规则" prop="pintuanRule">
|
||||
<Input v-model="form.pintuanRule" type="textarea" :rows="4" clearable maxlength="255" style="width: 260px" />
|
||||
<br />
|
||||
<span style="color: #cccccc">拼团规则描述不能为空且不能大于255个字,会在WAP拼团详情页面显示</span>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div>
|
||||
<Button type="text" @click="closeCurrentPage">返回</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit">提交</Button>
|
||||
<h4>商品信息</h4>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
class="operation"
|
||||
:data="goodsData"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="商品名称" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text mr_10" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../../assets/qrcode.svg"
|
||||
style="vertical-align: middle"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="qrcode"
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="quantity" label="库存" min-width="80" />
|
||||
<el-table-column label="拼团价格" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="page operation mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { savePintuan, editPintuan, getPintuanDetail } from "@/api/promotion";
|
||||
import { getPintuanGoodsList, getPintuanDetail } from "@/api/promotion.js";
|
||||
import vueQr from "vue-qr";
|
||||
|
||||
export default {
|
||||
components: { vueQr },
|
||||
data() {
|
||||
return {
|
||||
id: this.$route.query.id, // 拼团id
|
||||
form: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
promotionName: "",
|
||||
promotionTitle: "",
|
||||
pintuanRule: "",
|
||||
requiredNum: "",
|
||||
fictitious: 0,
|
||||
limitNum: "",
|
||||
startTime: "",
|
||||
endTime: "",
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
promotionName: [{ required: true, message: "活动名称不能为空" }],
|
||||
requiredNum: [
|
||||
{ required: true, message: "参团人数不能为空" },
|
||||
{
|
||||
pattern: /^([2-9]|10)?$/,
|
||||
message: "参团人数不合法",
|
||||
},
|
||||
],
|
||||
limitNum: [
|
||||
{ required: true, message: "限购数不能为空" },
|
||||
{
|
||||
pattern: /^(0|[1-9]\d?|100)$/,
|
||||
message: "限购数不合法",
|
||||
},
|
||||
],
|
||||
rangeTime: [{ required: true, message: "请选择活动时间" }],
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
options: {
|
||||
// 不可选取时间
|
||||
disabledDate(date) {
|
||||
return date && date.valueOf() < Date.now() - 86400000;
|
||||
},
|
||||
loading: false,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
goodsData: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.id) {
|
||||
this.getDetail();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 关闭当前页面
|
||||
closeCurrentPage() {
|
||||
this.$store.commit("removeTag", "new-pintuan");
|
||||
localStorage.storeOpenedList = JSON.stringify(
|
||||
this.$store.state.app.storeOpenedList
|
||||
);
|
||||
this.$router.go(-1);
|
||||
promotionStatusText(status) {
|
||||
const map = {
|
||||
NEW: "未开始",
|
||||
START: "已开始",
|
||||
END: "已结束",
|
||||
CLOSE: "已关闭",
|
||||
};
|
||||
return map[status] || "未知";
|
||||
},
|
||||
// 提交活动
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
let params = JSON.parse(JSON.stringify(this.form));
|
||||
params.fictitious
|
||||
? (params.fictitious = true)
|
||||
: (params.fictitious = false);
|
||||
params.startTime = this.$options.filters.unixToDate(
|
||||
this.form.rangeTime[0] / 1000
|
||||
);
|
||||
|
||||
params.endTime = this.$options.filters.unixToDate(
|
||||
this.form.rangeTime[1] / 1000
|
||||
);
|
||||
if (params.startTime === "" || params.endTime === "") {
|
||||
this.$Message.error("活动时间不能为空");
|
||||
this.submitLoading = false;
|
||||
return;
|
||||
}
|
||||
if (params.startTime < new Date()) {
|
||||
this.$Message.error("拼团活动开始时间不能小于当前时间");
|
||||
this.submitLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
delete params.rangeTime;
|
||||
if (!this.id) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete params.id;
|
||||
savePintuan(params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("拼团活动发布成功");
|
||||
this.closeCurrentPage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
if (params.promotionGoodsList == "")
|
||||
delete params.promotionGoodsList;
|
||||
editPintuan(params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.closeCurrentPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
promotionStatusTagType(status) {
|
||||
const map = {
|
||||
NEW: "info",
|
||||
START: "success",
|
||||
END: "danger",
|
||||
CLOSE: "danger",
|
||||
};
|
||||
return map[status] || "danger";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getPintuanMsg();
|
||||
},
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
this.searchForm.pintuanId = this.$route.query.id;
|
||||
getPintuanGoodsList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.goodsData = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取详情
|
||||
getDetail() {
|
||||
getPintuanDetail(this.id).then((res) => {
|
||||
if (res.success) {
|
||||
const data = res.result;
|
||||
data.rangeTime = [];
|
||||
data.rangeTime.push(new Date(data.startTime), new Date(data.endTime));
|
||||
this.form = data;
|
||||
// 此处将值转换为 1 true ,0 false 不然ivew radio组件会报错
|
||||
this.form.fictitious ? this.$set(this.form, "fictitious", 1) : this.$set(this.form, "fictitious", 0);
|
||||
|
||||
}
|
||||
getPintuanMsg() {
|
||||
getPintuanDetail(this.$route.query.id).then((res) => {
|
||||
if (res.success) this.data.push(res.result);
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .ivu-form-item {
|
||||
padding: 18px 10px !important;
|
||||
h4 {
|
||||
margin: 20px 0;
|
||||
padding: 0 10px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
border-left: 3px solid red;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mr_10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.hover-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,262 +1,133 @@
|
||||
<template>
|
||||
<div class="pintuan-goods">
|
||||
<Card>
|
||||
<Table style="margin: 10px 0" border :columns="columns" :data="data"></Table>
|
||||
<el-card>
|
||||
<h4>活动详情</h4>
|
||||
<el-table border :data="data" style="width: 100%; margin: 10px 0">
|
||||
<el-table-column prop="promotionName" label="活动名称" min-width="120" />
|
||||
<el-table-column prop="startTime" label="活动开始时间" min-width="120" />
|
||||
<el-table-column prop="endTime" label="活动结束时间" min-width="120" />
|
||||
<el-table-column prop="requiredNum" label="成团人数" min-width="90" />
|
||||
<el-table-column prop="limitNum" label="限购数量" min-width="90" />
|
||||
<el-table-column label="状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="promotionStatusTagType(row.promotionStatus)">
|
||||
{{ promotionStatusText(row.promotionStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Row class="operation" v-if="status == 'manager'">
|
||||
<Button type="primary" @click="openSkuList">选择商品</Button>
|
||||
<Button @click="delAll">批量删除</Button>
|
||||
<Button @click="getDataList" icon="md-refresh">刷新</Button>
|
||||
<Button type="dashed" @click="openTip = !openTip">{{
|
||||
openTip ? "关闭提示" : "开启提示"
|
||||
}}</Button>
|
||||
</Row>
|
||||
<Row v-show="openTip" v-if="status == 'manager'">
|
||||
<Alert show-icon>
|
||||
已选择 <span>{{ selectCount }}</span> 项
|
||||
<a class="select-clear" @click="clearSelectAll">清空</a>
|
||||
</Alert>
|
||||
</Row>
|
||||
<h3 class="act-goods">活动商品</h3>
|
||||
<Table
|
||||
class="mt_10"
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="goodsColumns"
|
||||
:data="goodsData"
|
||||
<h4>商品信息</h4>
|
||||
<el-table
|
||||
ref="table"
|
||||
@on-selection-change="changeSelect"
|
||||
v-loading="loading"
|
||||
border
|
||||
class="operation"
|
||||
:data="goodsData"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template slot-scope="{ row, index }" slot="price">
|
||||
<Input
|
||||
v-model="row.price"
|
||||
:disabled="status === 'view'"
|
||||
@input="goodsData[index].price = row.price"
|
||||
/>
|
||||
</template>
|
||||
<template slot-scope="{ index }" slot="action">
|
||||
<a
|
||||
v-if="status === 'manager'"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="delGoods(index)"
|
||||
>删除</a>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="page operation">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[10, 20, 50]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
<Row class="operation">
|
||||
<Button @click="closeCurrentPage">返回</Button>
|
||||
<Button
|
||||
v-if="status == 'manager'"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="save"
|
||||
>保存</Button
|
||||
>
|
||||
</Row>
|
||||
</Card>
|
||||
<el-table-column label="商品名称" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text mr_10" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../../assets/qrcode.svg"
|
||||
style="vertical-align: middle"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="qrcode"
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="quantity" label="库存" min-width="80" />
|
||||
<el-table-column label="拼团价格" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<sku-select
|
||||
ref="skuSelect"
|
||||
:goodsData="goodsData"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></sku-select>
|
||||
<div class="page operation mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPintuanGoodsList, getPintuanDetail, editPintuan } from "@/api/promotion.js";
|
||||
import skuSelect from "@/views/lili-dialog";
|
||||
import vueQr from "vue-qr";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
skuSelect,
|
||||
},
|
||||
components: { vueQr },
|
||||
data() {
|
||||
return {
|
||||
openTip: true, // 显示提示
|
||||
loading: false, // 表单加载状态
|
||||
loading: false,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
status: this.$route.query.status, // 查看还是修改
|
||||
columns: [
|
||||
// 活动详情表头
|
||||
{
|
||||
title: "活动名称",
|
||||
key: "promotionName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "活动开始时间",
|
||||
key: "startTime",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "活动结束时间",
|
||||
key: "endTime",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "promotionStatus",
|
||||
minWidth: 100,
|
||||
render: (h, params) => {
|
||||
let text = "未知",
|
||||
color = "";
|
||||
if (params.row.promotionStatus == "NEW") {
|
||||
text = "未开始";
|
||||
color = "default";
|
||||
} else if (params.row.promotionStatus == "START") {
|
||||
text = "已开始";
|
||||
color = "green";
|
||||
} else if (params.row.promotionStatus == "END") {
|
||||
text = "已结束";
|
||||
color = "blue";
|
||||
} else if (params.row.promotionStatus == "CLOSE") {
|
||||
text = "已关闭";
|
||||
color = "red";
|
||||
}
|
||||
return h("div", [h("Tag", { props: { color: color } }, text)]);
|
||||
},
|
||||
},
|
||||
],
|
||||
goodsColumns: [
|
||||
// 活动商品表头
|
||||
{ type: "selection", width: 60, align: "center" },
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
minWidth: 40,
|
||||
},
|
||||
{
|
||||
title: "拼团价格",
|
||||
key: "price",
|
||||
slot: "price",
|
||||
minWidth: 50,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
minWidth: 50,
|
||||
align: "center",
|
||||
},
|
||||
],
|
||||
goodsData: [], // 商品列表
|
||||
data: [],
|
||||
total: 0,
|
||||
goodsData: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 关闭当前页面
|
||||
closeCurrentPage() {
|
||||
this.$store.commit("removeTag", "pintuan-goods");
|
||||
localStorage.storeOpenedList = JSON.stringify(
|
||||
this.$store.state.app.storeOpenedList
|
||||
);
|
||||
this.$router.go(-1);
|
||||
promotionStatusText(status) {
|
||||
const map = {
|
||||
NEW: "未开始",
|
||||
START: "已开始",
|
||||
END: "已结束",
|
||||
CLOSE: "已关闭",
|
||||
};
|
||||
return map[status] || "未知";
|
||||
},
|
||||
// 保存商品
|
||||
save() {
|
||||
if (this.goodsData.length == 0) {
|
||||
this.$Modal.warning({ title: "提示", content: "请选择活动商品" });
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < this.goodsData.length; i++) {
|
||||
let data = this.goodsData[i];
|
||||
if (!data.price) {
|
||||
this.$Modal.warning({
|
||||
title: "提示",
|
||||
content: `请填写【${data.goodsName}】的价格`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.goodsData.forEach((item) => {
|
||||
item.promotionId = this.data[0].id;
|
||||
item.startTime = this.data[0].startTime;
|
||||
item.endTime = this.data[0].endTime;
|
||||
});
|
||||
this.data[0].promotionGoodsList = this.goodsData;
|
||||
this.submitLoading = true;
|
||||
editPintuan(this.data[0]).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改拼团商品成功");
|
||||
this.closeCurrentPage();
|
||||
}
|
||||
});
|
||||
promotionStatusTagType(status) {
|
||||
const map = {
|
||||
NEW: "info",
|
||||
START: "success",
|
||||
END: "danger",
|
||||
CLOSE: "danger",
|
||||
};
|
||||
return map[status] || "danger";
|
||||
},
|
||||
init() {
|
||||
// 初始化数据
|
||||
this.getDataList();
|
||||
this.getPintuanMsg();
|
||||
},
|
||||
|
||||
changePage(v) {
|
||||
// 分页 改变页数
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
|
||||
changePageSize(v) {
|
||||
// 分页 改变每页数
|
||||
this.searchForm.pageSize = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
|
||||
handleSearch() {
|
||||
// 搜索
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
|
||||
handleReset() {
|
||||
// 重置
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.promotionName = "";
|
||||
this.selectDate = null;
|
||||
this.getDataList();
|
||||
},
|
||||
|
||||
clearSelectAll() {
|
||||
// 清空所有已选项
|
||||
this.$refs.table.selectAll(false);
|
||||
},
|
||||
changeSelect(e) {
|
||||
// 获取选择数据
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
},
|
||||
|
||||
getDataList() {
|
||||
// 获取商品列表
|
||||
this.loading = true;
|
||||
this.searchForm.pintuanId = this.$route.query.id;
|
||||
|
||||
getPintuanGoodsList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
@@ -266,87 +137,43 @@ export default {
|
||||
});
|
||||
},
|
||||
getPintuanMsg() {
|
||||
// 获取拼团详情
|
||||
getPintuanDetail(this.$route.query.id).then((res) => {
|
||||
if (res.success) this.data.push(res.result);
|
||||
});
|
||||
},
|
||||
delGoods(index) {
|
||||
// 删除商品
|
||||
this.goodsData.splice(index, 1);
|
||||
this.selectCount = 0;
|
||||
},
|
||||
delAll() {
|
||||
// 批量删除商品
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要删除的数据");
|
||||
return;
|
||||
}
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除所选的 " + this.selectCount + " 条数据?",
|
||||
onOk: () => {
|
||||
let ids = [];
|
||||
this.selectList.forEach(function (e) {
|
||||
ids.push(e.skuId);
|
||||
});
|
||||
this.goodsData = this.goodsData.filter((item) => {
|
||||
return !ids.includes(item.skuId);
|
||||
});
|
||||
this.selectCount = 0;
|
||||
},
|
||||
});
|
||||
},
|
||||
selectedGoodsData(item) {
|
||||
// 选择商品
|
||||
console.log(item);
|
||||
let list = [];
|
||||
item.forEach((e) => {
|
||||
list.push({
|
||||
goodsName: e.goodsName,
|
||||
price: e.price,
|
||||
originalPrice: e.price,
|
||||
quantity: e.quantity,
|
||||
storeId: e.storeId,
|
||||
sellerName: e.sellerName,
|
||||
thumbnail: e.thumbnail,
|
||||
skuId: e.id,
|
||||
categoryPath: e.categoryPath,
|
||||
goodsId: e.goodsId,
|
||||
goodsType: e.goodsType,
|
||||
});
|
||||
});
|
||||
this.goodsData = list;
|
||||
},
|
||||
openSkuList() {
|
||||
// 显示商品选择器
|
||||
this.$refs.skuSelect.open("goods");
|
||||
let data = JSON.parse(JSON.stringify(this.goodsData));
|
||||
data.forEach((e) => {
|
||||
e.id = e.skuId;
|
||||
});
|
||||
this.$refs.skuSelect.goodsData = data;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.operation {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.act-goods {
|
||||
h4 {
|
||||
margin: 20px 0;
|
||||
font-size: 15px;
|
||||
&::before {
|
||||
content: "|";
|
||||
color: $theme_color;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
padding: 0 10px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
border-left: 3px solid red;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mr_10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.hover-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,90 +1,102 @@
|
||||
<template>
|
||||
<div class="pintuan">
|
||||
<Card>
|
||||
<Row>
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="活动名称" prop="promotionName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.promotionName"
|
||||
placeholder="请输入活动名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="活动状态" prop="promotionStatus">
|
||||
<Select
|
||||
v-model="searchForm.promotionStatus"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="NEW">未开始</Option>
|
||||
<Option value="START">已开始/上架</Option>
|
||||
<Option value="END">已结束/下架</Option>
|
||||
<Option value="CLOSE">紧急关闭/作废</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="活动时间">
|
||||
<DatePicker
|
||||
v-model="selectDate"
|
||||
type="daterange"
|
||||
clearable
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
type="primary"
|
||||
class="search-btn"
|
||||
icon="ios-search"
|
||||
>搜索</Button
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="活动名称" prop="promotionName">
|
||||
<el-input
|
||||
v-model="searchForm.promotionName"
|
||||
placeholder="请输入活动名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动状态" prop="promotionStatus">
|
||||
<el-select
|
||||
v-model="searchForm.promotionStatus"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="newAct" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table">
|
||||
<template slot-scope="{ row }" slot="action">
|
||||
<div class="row">
|
||||
<a v-if="row.promotionStatus == 'NEW'" @click="edit(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">编辑</a>
|
||||
<span v-if="row.promotionStatus == 'NEW'" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-if="row.promotionStatus == 'NEW'" @click="manage(row, 'manager')" style="color:#2d8cf0;cursor:pointer;text-decoration:none">管理</a>
|
||||
<span v-if="row.promotionStatus !== 'NEW' && row.promotionStatus !== 'CLOSE'" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-if="row.promotionStatus !== 'NEW' && row.promotionStatus !== 'CLOSE'" @click="manage(row, 'view')" style="color:#2d8cf0;cursor:pointer;text-decoration:none">查看</a>
|
||||
<span v-if="row.promotionStatus == 'CLOSE'" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-if="row.promotionStatus == 'CLOSE'" @click="open(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">开启</a>
|
||||
<span v-if="row.promotionStatus == 'START'" style="margin:0 8px;color:#dcdee2">|</span>
|
||||
<a v-if="row.promotionStatus == 'START'" @click="close(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">关闭</a>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber + 1"
|
||||
<el-option label="未开始" value="NEW" />
|
||||
<el-option label="已开始/上架" value="START" />
|
||||
<el-option label="已结束/下架" value="END" />
|
||||
<el-option label="紧急关闭/作废" value="CLOSE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="daterange"
|
||||
clearable
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="promotionName"
|
||||
label="活动名称"
|
||||
min-width="150"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="状态" width="110">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="promotionStatusTagType(row.promotionStatus)">
|
||||
{{ promotionStatusText(row.promotionStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storeName" label="所属店铺" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="startTime" label="活动开始时间" width="180" />
|
||||
<el-table-column prop="endTime" label="活动结束时间" width="180" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="view(row)">查看</a>
|
||||
<template v-if="row.promotionStatus === 'START' || row.promotionStatus === 'NEW'">
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="close(row)">关闭</a>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[10, 20, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -94,210 +106,86 @@ export default {
|
||||
name: "pintuan",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
selectDate: [],
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 0, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "startTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
promotionName: "",
|
||||
promotionStatus: "",
|
||||
},
|
||||
selectDate: null, // 选择的时间
|
||||
columns: [
|
||||
{
|
||||
title: "活动名称",
|
||||
key: "promotionName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "活动开始时间",
|
||||
key: "startTime",
|
||||
},
|
||||
{
|
||||
title: "活动结束时间",
|
||||
key: "endTime",
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "promotionStatus",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
let text = "未知",
|
||||
color = "default";
|
||||
if (params.row.promotionStatus == "NEW") {
|
||||
text = "未开始";
|
||||
color = "default";
|
||||
} else if (params.row.promotionStatus == "START") {
|
||||
text = "已开始";
|
||||
color = "green";
|
||||
} else if (params.row.promotionStatus == "END") {
|
||||
text = "已结束";
|
||||
color = "blue";
|
||||
} else if (params.row.promotionStatus == "CLOSE") {
|
||||
text = "已关闭";
|
||||
color = "red";
|
||||
}
|
||||
return h("div", [h("Tag", { props: { color: color } }, text)]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
align: "center",
|
||||
width: 250,
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
promotionStatusText(status) {
|
||||
const map = {
|
||||
NEW: "未开始",
|
||||
START: "已开始",
|
||||
END: "已结束",
|
||||
CLOSE: "已关闭",
|
||||
};
|
||||
return map[status] || "未知";
|
||||
},
|
||||
promotionStatusTagType(status) {
|
||||
const map = {
|
||||
NEW: "info",
|
||||
START: "success",
|
||||
END: "danger",
|
||||
CLOSE: "danger",
|
||||
};
|
||||
return map[status] || "danger";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v - 1;
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 0;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 0, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "startTime",
|
||||
order: "desc", // 默认排序方式
|
||||
};
|
||||
this.selectDate = "";
|
||||
|
||||
this.getDataList();
|
||||
},
|
||||
// 时间段分别赋值
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
}
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
if (this.selectDate && this.selectDate[0] && this.selectDate[1]) {
|
||||
this.searchForm.startTime = this.selectDate[0].getTime();
|
||||
this.searchForm.endTime = this.selectDate[1].getTime();
|
||||
this.searchForm.startTime = new Date(this.selectDate[0]).getTime();
|
||||
this.searchForm.endTime = new Date(this.selectDate[1]).getTime();
|
||||
} else {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
}
|
||||
getPintuanList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
getPintuanList(this.searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 新建拼团
|
||||
newAct() {
|
||||
this.$router.push({ name: "pintuan-edit" });
|
||||
view(v) {
|
||||
this.$router.push({ name: "pintuan-goods", query: { id: v.id } });
|
||||
},
|
||||
// 编辑拼团
|
||||
edit(v) {
|
||||
this.$router.push({ name: "pintuan-edit", query: { id: v.id } });
|
||||
},
|
||||
// 管理拼团商品
|
||||
manage(v, status) {
|
||||
this.$options.filters.customRouterPush({name: "pintuan-goods", query: { id: v.id, status: status }} )
|
||||
|
||||
},
|
||||
// 手动开启拼团活动
|
||||
open(v) {
|
||||
let sTime = new Date();
|
||||
sTime.setMinutes(sTime.getMinutes() + 10);
|
||||
let eTime = new Date(new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000 - 1);
|
||||
this.openStartTime = sTime.getTime();
|
||||
this.openEndTime = eTime.getTime();
|
||||
this.$Modal.confirm({
|
||||
title: "确认开启(默认为当前时间的十分钟之后)",
|
||||
content: "您确认要开启此拼团活动?",
|
||||
onOk: () => {
|
||||
let params = {
|
||||
startTime: this.openStartTime,
|
||||
endTime: this.openEndTime,
|
||||
};
|
||||
editPintuanStatus(v.id, params).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("开启活动成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
render: (h) => {
|
||||
return h("div", [
|
||||
h("DatePicker", {
|
||||
props: {
|
||||
type: "datetimerange",
|
||||
placeholder: "请选择开始时间和结束时间",
|
||||
value: [sTime, eTime],
|
||||
},
|
||||
style: {
|
||||
width: "350px",
|
||||
},
|
||||
on: {
|
||||
input: (val) => {
|
||||
if (val[0]) {
|
||||
this.openStartTime = val[0].getTime();
|
||||
}
|
||||
if (val[1]) {
|
||||
this.openEndTime = val[1].getTime();
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
]);
|
||||
},
|
||||
});
|
||||
},
|
||||
// 关闭拼团活动
|
||||
close(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认关闭",
|
||||
content: "您确认要关闭此拼团活动?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
editPintuanStatus(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("关闭活动成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
// 删除拼团活动
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除此拼团活动?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
deletePintuan(v.id).then((res) => {
|
||||
updatePintuanStatus(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
@@ -311,17 +199,11 @@ export default {
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false;
|
||||
next();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import "@/styles/table-common.scss";
|
||||
.row Button {
|
||||
margin-right: 4px;
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,298 +1,147 @@
|
||||
<template>
|
||||
<div class="seckill-goods">
|
||||
<Card>
|
||||
<Table border :columns="columns" :data="data">
|
||||
<template slot-scope="{ row }" slot="applyEndTime">
|
||||
{{ unixDate(row.applyEndTime) }}
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="hours">
|
||||
<Tag v-for="item in unixHours(row.hours)" :key="item">{{ item }}</Tag>
|
||||
</template>
|
||||
</Table>
|
||||
<el-card>
|
||||
<el-table border :data="data" style="width: 100%">
|
||||
<el-table-column prop="promotionName" label="活动名称" min-width="120" />
|
||||
<el-table-column prop="startTime" label="活动开始时间" min-width="160" />
|
||||
<el-table-column label="报名截止时间" min-width="160">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ unixDate(row.applyEndTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时间场次" min-width="160">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-for="item in unixHours(row.hours)" :key="item" class="hour-tag">{{ item }}</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="活动状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="seckillStatusTagType(row.promotionStatus)">
|
||||
{{ seckillStatusText(row.promotionStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Row class="operation">
|
||||
<template v-if="promotionStatus == 'NEW'">
|
||||
<Button type="primary" @click="openSkuList">选择商品</Button>
|
||||
<!-- <Button @click="delAll">批量删除</Button> -->
|
||||
</template>
|
||||
</Row>
|
||||
<Row class="operation">
|
||||
<Tabs type="card" v-model="tabCurrent">
|
||||
<TabPane
|
||||
v-for="(tab, tabIndex) in goodsList"
|
||||
:key="tabIndex"
|
||||
:label="tab.hour"
|
||||
:name="tabIndex + ''"
|
||||
>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="goodsColumns"
|
||||
v-if="tabIndex == tabCurrent"
|
||||
:data="tab.list"
|
||||
:ref="'table' + tabIndex"
|
||||
@on-selection-change="changeSelect"
|
||||
>
|
||||
<template slot-scope="{ row }" slot="originalPrice">
|
||||
<div>{{ row.originalPrice | unitPrice("¥") }}</div>
|
||||
</template>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
class="operation"
|
||||
:data="goodsList"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="商品价格" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.originalPrice, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" width="90">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.quantity }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="活动价格" width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storeName" label="商家名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="活动场次" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row">{{ row.timeLine + ":00" }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<a v-if="row" class="link-text" @click="delGoods($index, row)">删除</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<template slot-scope="{ row, index }" slot="quantity">
|
||||
<InputNumber
|
||||
:min="0"
|
||||
v-model="row.quantity"
|
||||
:disabled="row.promotionApplyStatus == 'PASS'"
|
||||
@input="goodsList[tabIndex].list[index].quantity = row.quantity"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template slot-scope="{ row, index }" slot="price">
|
||||
<InputNumber
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
v-model="row.price"
|
||||
:disabled="row.promotionApplyStatus == 'PASS'"
|
||||
@input="goodsList[tabIndex].list[index].price = row.price"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template slot-scope="{ row }" slot="promotionApplyStatus">
|
||||
<Badge
|
||||
status="success"
|
||||
v-if="row.promotionApplyStatus == 'PASS'"
|
||||
:text="promotionApplyStatus(row.promotionApplyStatus)"
|
||||
/>
|
||||
<Badge
|
||||
status="blue"
|
||||
v-if="row.promotionApplyStatus == 'APPLY'"
|
||||
:text="promotionApplyStatus(row.promotionApplyStatus)"
|
||||
/>
|
||||
<Badge
|
||||
status="error"
|
||||
v-if="row.promotionApplyStatus == 'REFUSE'"
|
||||
:text="promotionApplyStatus(row.promotionApplyStatus)"
|
||||
/>
|
||||
<span
|
||||
v-if="row.promotionApplyStatus == 'REFUSE'"
|
||||
@click="showReason(row.failReason)"
|
||||
class="reason"
|
||||
>(拒绝原因)</span
|
||||
>
|
||||
<Badge
|
||||
status="error"
|
||||
v-if="row.promotionApplyStatus == ''"
|
||||
:text="promotionApplyStatus(row.promotionApplyStatus)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template slot-scope="{ row }" slot="QRCode">
|
||||
<img
|
||||
v-if="row.QRCode"
|
||||
:src="row.QRCode || '../../../assets/lili.png'"
|
||||
width="50px"
|
||||
height="50px"
|
||||
alt=""
|
||||
/>
|
||||
</template>
|
||||
<template slot-scope="{ row, index }" slot="action">
|
||||
<a
|
||||
v-if="promotionStatus === 'NEW'"
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="delGoods(index, row)"
|
||||
>删除</a>
|
||||
</template>
|
||||
</Table>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Row>
|
||||
|
||||
<Row class="operation">
|
||||
<Button @click="closeCurrentPage">返回</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
v-if="promotionStatus === 'NEW'"
|
||||
@click="save"
|
||||
>提交
|
||||
</Button>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<sku-select ref="skuSelect" @selectedGoodsData="selectedGoodsData"></sku-select>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
seckillGoodsList,
|
||||
seckillDetail,
|
||||
setSeckillGoods,
|
||||
delSeckillGoods,
|
||||
} from "@/api/promotion.js";
|
||||
import skuSelect from "@/views/lili-dialog";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
skuSelect,
|
||||
},
|
||||
watch: {
|
||||
tabCurrent(val) {
|
||||
this.tabIndex = val;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabCurrent: 0,
|
||||
promotionStatus: "", // 活动状态
|
||||
loading: false, // 表单加载状态
|
||||
promotionStatus: "",
|
||||
loading: false,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 0, // 当前页数
|
||||
pageSize: 1000, // 页面大小
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
tabIndex: 0, // 选择商品的下标
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
data: [{}], // 表单数据
|
||||
columns: [
|
||||
{
|
||||
title: "活动名称",
|
||||
key: "promotionName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "活动开始时间",
|
||||
key: "startTime",
|
||||
},
|
||||
{
|
||||
title: "报名截止时间",
|
||||
slot: "applyEndTime",
|
||||
},
|
||||
{
|
||||
title: "时间场次",
|
||||
slot: "hours",
|
||||
},
|
||||
],
|
||||
goodsColumns: [
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "商品价格",
|
||||
slot: "originalPrice",
|
||||
minWidth: 50,
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
slot: "quantity",
|
||||
minWidth: 40,
|
||||
},
|
||||
{
|
||||
title: "活动价格",
|
||||
slot: "price",
|
||||
minWidth: 50,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
slot: "promotionApplyStatus",
|
||||
minWidth: 30,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
minWidth: 50,
|
||||
},
|
||||
],
|
||||
goodsList: [], // 商品列表
|
||||
defaultGoodsList: [], //默认查询秒杀的商品
|
||||
total: 0,
|
||||
data: [],
|
||||
goodsList: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 关闭当前页面
|
||||
closeCurrentPage() {
|
||||
this.$store.commit("removeTag", "seckill-goods");
|
||||
localStorage.storeOpenedList = JSON.stringify(
|
||||
this.$store.state.app.storeOpenedList
|
||||
);
|
||||
this.$router.go(-1);
|
||||
},
|
||||
// 提交秒杀商品
|
||||
save() {
|
||||
let list = JSON.parse(JSON.stringify(this.goodsList));
|
||||
let params = {
|
||||
seckillId: this.$route.query.id,
|
||||
applyVos: [],
|
||||
seckillStatusText(status) {
|
||||
const map = {
|
||||
NEW: "新建",
|
||||
START: "开始",
|
||||
END: "结束",
|
||||
CLOSE: "废弃",
|
||||
};
|
||||
|
||||
list.forEach((e, index) => {
|
||||
e.list.forEach((i) => {
|
||||
// if(e.id) delete e.id
|
||||
params.applyVos.push(i);
|
||||
});
|
||||
});
|
||||
this.submitLoading = true;
|
||||
|
||||
console.log(list);
|
||||
|
||||
setSeckillGoods(params).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("提交活动商品成功");
|
||||
this.closeCurrentPage();
|
||||
}
|
||||
});
|
||||
return map[status] || status || "-";
|
||||
},
|
||||
seckillStatusTagType(status) {
|
||||
const map = {
|
||||
NEW: "danger",
|
||||
START: "success",
|
||||
END: "danger",
|
||||
CLOSE: "danger",
|
||||
};
|
||||
return map[status] || "danger";
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getSeckillMsg();
|
||||
},
|
||||
// 清除选中状态
|
||||
clearSelectAll() {
|
||||
this.$refs.table.selectAll(false);
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取选择数据
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
|
||||
getDataList() {
|
||||
// 获取商品详情
|
||||
this.loading = true;
|
||||
this.searchForm.seckillId = this.$route.query.id;
|
||||
// 处理过的时间 为‘1:00’
|
||||
let hours = this.unixHours(this.data[0].hours);
|
||||
hours.forEach((e) => {
|
||||
this.goodsList.push({
|
||||
hour: e,
|
||||
list: [],
|
||||
});
|
||||
});
|
||||
seckillGoodsList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success && res.result) {
|
||||
let data = res.result.records;
|
||||
// 未处理时间 为'1'
|
||||
let noFilterhours = this.data[0].hours.split(",");
|
||||
if (data.length) {
|
||||
noFilterhours.forEach((e, index) => {
|
||||
data.forEach((i) => {
|
||||
if (i.timeLine == e) {
|
||||
this.goodsList[index].list.push(i);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.defaultGoodsList = this.goodsList[this.tabIndex].list;
|
||||
}
|
||||
this.goodsList = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getSeckillMsg() {
|
||||
// 获取活动详情
|
||||
seckillDetail(this.$route.query.id).then((res) => {
|
||||
if (res.success && res.result) {
|
||||
this.data = [];
|
||||
@@ -303,116 +152,57 @@ export default {
|
||||
});
|
||||
},
|
||||
delGoods(index, row) {
|
||||
// 删除商品
|
||||
if (row.promotionApplyStatus === "PASS") {
|
||||
const params = {
|
||||
seckillId: row.seckillId,
|
||||
id: row.id,
|
||||
};
|
||||
delSeckillGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
this.goodsList[this.tabIndex].list.splice(index, 1);
|
||||
this.$Message.success("删除成功!");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.goodsList[this.tabIndex].list.splice(index, 1);
|
||||
this.$Message.success("删除成功!");
|
||||
}
|
||||
},
|
||||
selectedGoodsData(callback) {
|
||||
let way = [];
|
||||
let data = JSON.parse(JSON.stringify(callback));
|
||||
|
||||
data.forEach((e) => {
|
||||
way.push({
|
||||
goodsName: e.goodsName,
|
||||
price: e.price,
|
||||
originalPrice: e.price,
|
||||
promotionApplyStatus: e.promotionApplyStatus || "",
|
||||
quantity: e.quantity,
|
||||
seckillId: this.$route.query.id,
|
||||
storeId: e.storeId,
|
||||
storeName: e.storeName,
|
||||
skuId: e.id,
|
||||
timeLine: this.data[0].hours.split(",")[this.tabIndex],
|
||||
});
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除该商品吗?删除后不可恢复",
|
||||
onOk: () => {
|
||||
const params = {
|
||||
seckillId: row.seckillId,
|
||||
id: row.id,
|
||||
};
|
||||
delSeckillGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
this.goodsList.splice(index, 1);
|
||||
this.$Message.success("删除成功!");
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
this.$set(this.goodsList[this.tabIndex], "list", [
|
||||
...way,
|
||||
// ...this.defaultGoodsList,
|
||||
]);
|
||||
// this.$nextTick(() => {
|
||||
// this.$forceUpdate();
|
||||
// });
|
||||
},
|
||||
openSkuList() {
|
||||
// 显示商品选择器
|
||||
|
||||
this.$refs.skuSelect.open("goods");
|
||||
let data = this.goodsList[this.tabIndex].list;
|
||||
data.forEach((e) => {
|
||||
e.id = e.skuId;
|
||||
});
|
||||
this.$refs.skuSelect.goodsData = data;
|
||||
},
|
||||
unixDate(time) {
|
||||
// 处理报名截止时间
|
||||
return this.$options.filters.unixToDate(new Date(time) / 1000);
|
||||
return this.$filters.unixToDate(new Date(time) / 1000);
|
||||
},
|
||||
unixHours(item) {
|
||||
if (item) {
|
||||
// 处理小时场次
|
||||
let hourArr = item.split(",");
|
||||
for (let i = 0; i < hourArr.length; i++) {
|
||||
hourArr[i] += ":00";
|
||||
}
|
||||
return hourArr;
|
||||
const hourArr = item.split(",");
|
||||
for (let i = 0; i < hourArr.length; i++) {
|
||||
hourArr[i] += ":00";
|
||||
}
|
||||
return [];
|
||||
},
|
||||
// 格式化申请状态
|
||||
promotionApplyStatus(key) {
|
||||
switch (key) {
|
||||
case "APPLY":
|
||||
return "申请";
|
||||
case "PASS":
|
||||
return "通过";
|
||||
case "REFUSE":
|
||||
return "拒绝";
|
||||
default:
|
||||
return "未申请";
|
||||
}
|
||||
},
|
||||
// 展示审核拒绝原因
|
||||
showReason(reason) {
|
||||
this.$Modal.info({
|
||||
title: "拒绝原因",
|
||||
content: reason,
|
||||
});
|
||||
return hourArr;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
// 如果是从详情页返回列表页,修改列表页keepAlive为true,确保不刷新页面
|
||||
beforeRouteLeave(to, from, next) {
|
||||
if (to.name === "seckill") {
|
||||
to.meta.keepAlive = true;
|
||||
}
|
||||
next();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.operation {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.reason {
|
||||
.hour-tag {
|
||||
margin-right: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
color: #2d8cf0;
|
||||
font-size: 12px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
133
seller/src/views/promotion/seckill/seckill-setup.vue
Normal file
133
seller/src/views/promotion/seckill/seckill-setup.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<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>
|
||||
@@ -1,207 +1,269 @@
|
||||
<template>
|
||||
<div class="seckill">
|
||||
<Card>
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="活动名称" prop="goodsName">
|
||||
<Input type="text" v-model="searchForm.promotionName" placeholder="请输入活动名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="活动状态" prop="promotionStatus">
|
||||
<Select v-model="searchForm.promotionStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<Option value="NEW">未开始</Option>
|
||||
<Option value="START">已开始/上架</Option>
|
||||
<Option value="END">已结束/下架</Option>
|
||||
<Option value="CLOSE">紧急关闭/作废</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="活动时间">
|
||||
<DatePicker v-model="selectDate" type="daterange" clearable placeholder="选择起始时间" style="width: 240px">
|
||||
</DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="ml_10">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10">
|
||||
<template slot-scope="{ row }" slot="applyEndTime">
|
||||
{{ unixDate(row.applyEndTime) }}
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="hours">
|
||||
<Tag v-for="item in unixHours(row.hours)" :key="item">{{
|
||||
item
|
||||
}}</Tag>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="action">
|
||||
<a v-if="row.promotionStatus === 'NEW'" @click="manage(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">管理</a>
|
||||
<a v-else @click="manage(row)" style="color:#2d8cf0;cursor:pointer;text-decoration:none">查看</a>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small" show-total show-elevator
|
||||
show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<div class="search seckill">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="活动名称" prop="promotionName">
|
||||
<el-input
|
||||
v-model="searchForm.promotionName"
|
||||
placeholder="请输入活动名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动状态" prop="promotionStatus">
|
||||
<el-select
|
||||
v-model="searchForm.promotionStatus"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option label="未开始" value="NEW" />
|
||||
<el-option label="已开始/上架" value="START" />
|
||||
<el-option label="已结束/下架" value="END" />
|
||||
<el-option label="紧急关闭/作废" value="CLOSE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="daterange"
|
||||
clearable
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-tabs v-model="activeTab" class="mt_10">
|
||||
<el-tab-pane label="秒杀活动列表" name="list">
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="promotionName"
|
||||
label="活动名称"
|
||||
min-width="140"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column prop="startTime" label="开始时间" width="180" />
|
||||
<el-table-column prop="applyEndTime" label="申请截止时间" width="180" />
|
||||
<el-table-column label="活动状态" width="110">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="promotionStatusTagType(row.promotionStatus)">
|
||||
{{ promotionStatusText(row.promotionStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="seckillRule"
|
||||
label="申请规则"
|
||||
min-width="120"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a
|
||||
v-if="row.promotionStatus === 'CLOSE' || row.promotionStatus === 'NEW'"
|
||||
class="link-text"
|
||||
@click="edit(row)"
|
||||
>
|
||||
编辑
|
||||
</a>
|
||||
<a v-else class="link-text" @click="manage(row)">查看</a>
|
||||
<span v-if="row.promotionStatus" class="op-split">|</span>
|
||||
<a
|
||||
v-if="row.promotionStatus == 'NEW'"
|
||||
class="link-text"
|
||||
@click="manage(row)"
|
||||
>
|
||||
管理
|
||||
</a>
|
||||
<span v-if="row.promotionStatus == 'NEW'" class="op-split">|</span>
|
||||
<a
|
||||
v-if="row.promotionStatus == 'START' || row.promotionStatus == 'NEW'"
|
||||
class="link-text"
|
||||
@click="off(row)"
|
||||
>
|
||||
关闭
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="秒杀活动设置" name="setup" lazy>
|
||||
<setupSeckill />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { seckillList } from "@/api/promotion";
|
||||
import setupSeckill from "@/views/promotion/seckill/seckill-setup";
|
||||
|
||||
export default {
|
||||
name: "seckill",
|
||||
components: {},
|
||||
data () {
|
||||
components: {
|
||||
setupSeckill,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: "list",
|
||||
selectDate: [],
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "startTime",
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "活动名称",
|
||||
key: "promotionName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "活动开始时间",
|
||||
key: "startTime",
|
||||
},
|
||||
{
|
||||
title: "报名截止时间",
|
||||
slot: "applyEndTime",
|
||||
},
|
||||
{
|
||||
title: "时间场次",
|
||||
slot: "hours",
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "promotionStatus",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
let text = "未知",
|
||||
color = "default";
|
||||
if (params.row.promotionStatus == "NEW") {
|
||||
text = "未开始";
|
||||
color = "geekblue";
|
||||
} else if (params.row.promotionStatus == "START") {
|
||||
text = "已开始";
|
||||
color = "green";
|
||||
} else if (params.row.promotionStatus == "END") {
|
||||
text = "已结束";
|
||||
color = "volcano";
|
||||
} else if (params.row.promotionStatus == "CLOSE") {
|
||||
text = "已关闭";
|
||||
color = "red";
|
||||
}
|
||||
return h("div", [
|
||||
h(
|
||||
"Tag",
|
||||
{
|
||||
props: {
|
||||
color: color,
|
||||
},
|
||||
},
|
||||
text
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
align: "center",
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init () {
|
||||
promotionStatusText(status) {
|
||||
const map = {
|
||||
NEW: "未开始",
|
||||
START: "已开始",
|
||||
END: "已结束",
|
||||
CLOSE: "已关闭",
|
||||
};
|
||||
return map[status] || "未知";
|
||||
},
|
||||
promotionStatusTagType(status) {
|
||||
const map = {
|
||||
NEW: "info",
|
||||
START: "success",
|
||||
END: "danger",
|
||||
CLOSE: "danger",
|
||||
};
|
||||
return map[status] || "danger";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage (v) {
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize (v) {
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch () {
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset () {
|
||||
this.searchForm = {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "startTime",
|
||||
order: "desc", // 默认排序方式
|
||||
};
|
||||
this.selectDate = "";
|
||||
this.getDataList();
|
||||
edit(v) {
|
||||
this.$router.push({ name: "manager-seckill-add", query: { id: v.id } });
|
||||
},
|
||||
// 管理
|
||||
manage (row) {
|
||||
this.$router.push({ name: "seckill-goods", query: { id: row.id } });
|
||||
manage(v) {
|
||||
this.$router.push({ name: "seckill-goods", query: { id: v.id } });
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList () {
|
||||
off(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
content: "您确定要下架该活动吗?",
|
||||
onOk: () => {
|
||||
updateSeckillStatus(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("下架成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
expire(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
content: "您确定要作废该活动吗?",
|
||||
onOk: () => {
|
||||
delSeckill(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("作废成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
if (this.selectDate && this.selectDate[0] && this.selectDate[1]) {
|
||||
this.searchForm.startTime = this.selectDate[0].getTime();
|
||||
this.searchForm.endTime = this.selectDate[1].getTime();
|
||||
this.searchForm.startTime = new Date(this.selectDate[0]).getTime();
|
||||
this.searchForm.endTime = new Date(this.selectDate[1]).getTime();
|
||||
} else {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
}
|
||||
// 带多条件搜索参数获取表单数据
|
||||
seckillList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
unixDate (time) {
|
||||
// 处理报名截止时间
|
||||
return this.$options.filters.unixToDate(new Date(time) / 1000);
|
||||
},
|
||||
unixHours (item) {
|
||||
// 处理小时场次
|
||||
let hourArr = item.split(",");
|
||||
for (let i = 0; i < hourArr.length; i++) {
|
||||
hourArr[i] += ":00";
|
||||
}
|
||||
return hourArr;
|
||||
getSeckillList(this.searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave (to, from, next) {
|
||||
from.meta.keepAlive = false
|
||||
next()
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,230 +1,180 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="开始时间" prop="startDay">
|
||||
<DatePicker
|
||||
type="date"
|
||||
v-model="searchForm.startDate"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Form-item label="结束时间" prop="endDate">
|
||||
<DatePicker
|
||||
type="date"
|
||||
v-model="searchForm.endDate"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
di
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
class="mt_10"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="开始时间" prop="startDate">
|
||||
<el-date-picker
|
||||
v-model="searchForm.startDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endDate">
|
||||
<el-date-picker
|
||||
v-model="searchForm.endDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
<el-button class="search-btn" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sn" label="账单号" min-width="250" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="生成时间" min-width="120" />
|
||||
<el-table-column label="结算时间段" width="200">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.startTime }}~{{ row.endTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结算金额" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.billPrice" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="billStatusTagType(row.billStatus)">
|
||||
{{ billStatusText(row.billStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a v-if="row" class="link-text" @click="detail(row)">查看</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Shop from "@/api/shops";
|
||||
import * as API_Shop from "@/api/shops";
|
||||
|
||||
export default {
|
||||
name: "accountStatementBill",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "账单号",
|
||||
key: "sn",
|
||||
minWidth: 250,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: "生成时间",
|
||||
key: "createTime",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算时间段",
|
||||
key: "startTime",
|
||||
width: 200,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h('div', params.row.startTime +"~"+params.row.endTime)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "结算金额",
|
||||
key: "billPrice",
|
||||
minWidth: 100,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.billPrice,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
title: "状态",
|
||||
key: "billStatus",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.billStatus == "OUT") {
|
||||
return h("Tag", {props: {color: "blue",},},"已出账");
|
||||
} else if (params.row.billStatus == "CHECK") {
|
||||
return h("Tag", {props: {color: "geekblue",},},"已对账");
|
||||
} else if (params.row.billStatus == "EXAMINE") {
|
||||
return h("Tag", {props: {color: "purple",},},"已审核");
|
||||
} else {
|
||||
return h("Tag", {props: {color: "green",},},"已付款");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: 'right',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
export default {
|
||||
name: "accountStatementBill",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
billStatusText(v) {
|
||||
const map = { OUT: "已出账", CHECK: "已对账", EXAMINE: "已审核", COMPLETE: "已付款" };
|
||||
return map[v] || "已付款";
|
||||
},
|
||||
billStatusTagType(v) {
|
||||
const map = { OUT: "primary", CHECK: "", EXAMINE: "warning", COMPLETE: "success" };
|
||||
return map[v] || "success";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
handleReset() {
|
||||
this.searchForm = {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
};
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {}
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
this.searchForm.billStatus = "OUT"
|
||||
API_Shop.getBillPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
this.searchForm.billStatus = "OUT";
|
||||
API_Shop.getBillPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
},
|
||||
// 查看详情
|
||||
detail(v) {
|
||||
let id = v.id;
|
||||
this.$router.push({
|
||||
name: "bill-detail",
|
||||
query: { id: id },
|
||||
});
|
||||
|
||||
},
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
detail(v) {
|
||||
this.$router.push({
|
||||
name: "bill-detail",
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false
|
||||
next()
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false;
|
||||
next();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
::v-deep .ivu-col{
|
||||
min-height: 100vh;
|
||||
}
|
||||
@import "@/styles/table-common.scss";
|
||||
.link-text {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,231 +1,170 @@
|
||||
<template>
|
||||
<div class="store-bill">
|
||||
<Card>
|
||||
<Form ref="searchForm"
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70" class="search-form" @keydown.enter.native="handleSearch"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="开始时间" prop="startDay">
|
||||
<DatePicker
|
||||
type="date"
|
||||
<el-form-item label="开始时间" prop="startDate">
|
||||
<el-date-picker
|
||||
v-model="searchForm.startDate"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Form-item label="结束时间" prop="endDate">
|
||||
<DatePicker
|
||||
type="date"
|
||||
v-model="searchForm.endDate"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
di
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Form-item label="状态" prop="orderStatus">
|
||||
<Select v-model="searchForm.billStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<Option value="OUT">已出账</Option>
|
||||
<Option value="CHECK">已对账</Option>
|
||||
<Option value="COMPLETE">已完成</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
|
||||
<Button @click="handleReset" class="search-btn">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endDate">
|
||||
<el-date-picker
|
||||
v-model="searchForm.endDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="billStatus">
|
||||
<el-select v-model="searchForm.billStatus" placeholder="请选择" clearable style="width: 240px">
|
||||
<el-option label="已出账" value="OUT" />
|
||||
<el-option label="已对账" value="CHECK" />
|
||||
<el-option label="已完成" value="COMPLETE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
<el-button class="search-btn" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table v-loading="loading" border :data="data" ref="table" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="sn" label="账单号" min-width="250" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="生成时间" min-width="120" />
|
||||
<el-table-column label="结算时间段" width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.startTime }}~{{ row.endTime }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结算金额" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme :value="row.billPrice" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.billStatus === 'OUT'" type="primary">已出账</el-tag>
|
||||
<el-tag v-else-if="row.billStatus === 'CHECK'" type="info">已对账</el-tag>
|
||||
<el-tag v-else-if="row.billStatus === 'EXAMINE'" type="warning">已审核</el-tag>
|
||||
<el-tag v-else type="success">已付款</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" fixed="right" width="100">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="detail(row)">查看</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[10, 20, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Shop from "@/api/shops";
|
||||
import * as API_Shop from "@/api/shops";
|
||||
|
||||
export default {
|
||||
name: "storeBill",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 10, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "账单号",
|
||||
key: "sn",
|
||||
minWidth: 250,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: "生成时间",
|
||||
key: "createTime",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算时间段",
|
||||
key: "startTime",
|
||||
width: 200,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h('div', params.row.startTime +"~"+params.row.endTime)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "结算金额",
|
||||
key: "billPrice",
|
||||
minWidth: 100,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.billPrice,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
title: "状态",
|
||||
key: "billStatus",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.billStatus == "OUT") {
|
||||
return h("Tag", {props: {color: "blue",},},"已出账");
|
||||
} else if (params.row.billStatus == "CHECK") {
|
||||
return h("Tag", {props: {color: "geekblue",},},"已对账");
|
||||
} else if (params.row.billStatus == "EXAMINE") {
|
||||
return h("Tag", {props: {color: "purple",},},"已审核");
|
||||
} else {
|
||||
return h("Tag", {props: {color: "green",},},"已付款");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: 'right',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
export default {
|
||||
name: "storeBill",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
handleReset() {
|
||||
this.searchForm = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
};
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 重置
|
||||
handleReset() {
|
||||
this.searchForm = {}
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 10;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Shop.getBillPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Shop.getBillPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
},
|
||||
// 跳转结算详情
|
||||
detail(v) {
|
||||
let id = v.id;
|
||||
this.$options.filters.customRouterPush({
|
||||
name: "bill-detail",
|
||||
query: { id: id },
|
||||
})
|
||||
},
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted () {
|
||||
this.init();
|
||||
detail(v) {
|
||||
this.$filters.customRouterPush({
|
||||
name: "bill-detail",
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
// 页面缓存处理,从该页面离开时,修改KeepAlive为false,保证进入该页面是刷新
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false
|
||||
next()
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
beforeRouteLeave(to, from, next) {
|
||||
from.meta.keepAlive = false;
|
||||
next();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// 建议引入通用样式 可删除下面样式代码
|
||||
@import "@/styles/table-common.scss";
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,83 +1,84 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<!-- <Card class="category">
|
||||
<div
|
||||
:class="{ active: i == selectedIndex }"
|
||||
class="category-item"
|
||||
v-for="(typeItem, i) in pageTypes"
|
||||
:key="typeItem.type"
|
||||
>
|
||||
<div @click="clickType(typeItem.type, i)">{{ typeItem.title }}</div>
|
||||
<div class="search">
|
||||
<el-card shadow="never">
|
||||
<el-tabs v-model="searchForm.pageType" class="page-type-tabs" @tab-change="handleTabChange">
|
||||
<el-tab-pane
|
||||
v-for="typeItem in pageTypes"
|
||||
:key="typeItem.type"
|
||||
:name="typeItem.type"
|
||||
:label="typeItem.title"
|
||||
/>
|
||||
</el-tabs>
|
||||
<div class="operation mb_10">
|
||||
<el-button type="primary" @click="createTemp">添加页面</el-button>
|
||||
</div>
|
||||
</Card> -->
|
||||
<Card class="content">
|
||||
<Button type="primary" @click="createTemp">添加页面</Button>
|
||||
<div class="list">
|
||||
<Spin size="large" fix v-if="loading"></Spin>
|
||||
<div class="item item-title">
|
||||
<div>页面名称</div>
|
||||
<div class="item-config">
|
||||
<div>状态</div>
|
||||
<div>操作</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item" v-for="(item, index) in list" :key="index">
|
||||
<div>{{ item.name || "暂无模板昵称" }}</div>
|
||||
<div class="item-config">
|
||||
<i-switch
|
||||
v-model="item.pageShow"
|
||||
@on-change="releaseTemplate(item.id)"
|
||||
>
|
||||
<span slot="open">开</span>
|
||||
<span slot="close">关</span>
|
||||
</i-switch>
|
||||
<a
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="Template(item)"
|
||||
>编辑</a>
|
||||
<span style="margin: 0 8px; color: #dcdee2">|</span>
|
||||
<a
|
||||
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
|
||||
@click="decorate(item)"
|
||||
>装修</a>
|
||||
<span style="margin: 0 8px; color: #dcdee2">|</span>
|
||||
<Poptip confirm title="删除此模板?" @on-ok="delTemplate(item.id)">
|
||||
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none">删除</a>
|
||||
</Poptip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="no-more" v-if="list.length == 0">暂无更多模板</div>
|
||||
<el-table v-loading="loading" :data="list" style="width: 100%">
|
||||
<el-table-column prop="name" label="页面名称" min-width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.name || "暂无模板昵称" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="searchForm.pageType !== 'SPECIAL'"
|
||||
label="状态"
|
||||
width="120"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.pageShow"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
@change="releaseTemplate(row.id)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="Template(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="decorate(row)">装修</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="confirmDel(row.id)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:total="total"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
background
|
||||
@current-change="changePageNum"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
<Page
|
||||
show-total
|
||||
:total="total"
|
||||
show-sizer
|
||||
:page-size-opts="[10, 20, 50]"
|
||||
show-elevator
|
||||
style="float: right; overflow: hidden"
|
||||
@on-change="changePageNum"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size="searchForm.pageSize"
|
||||
/>
|
||||
</Card>
|
||||
<Modal
|
||||
</el-card>
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="模板设置"
|
||||
draggable
|
||||
width="600"
|
||||
:z-index="100"
|
||||
:loading="loading"
|
||||
:mask-closable="false"
|
||||
@on-ok="newTemplate"
|
||||
@on-cancel="showModal = false"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<Form ref="form" :model="formData" :label-width="80">
|
||||
<FormItem label="模板名称" prop="name">
|
||||
<Input v-model="formData.name" placeholder="请输入模板名称" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Modal>
|
||||
<el-form ref="form" :model="formData" label-width="80px">
|
||||
<el-form-item label="模板名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入模板名称" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showModal = false">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="newTemplate">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -87,49 +88,26 @@ export default {
|
||||
name: "floorList",
|
||||
data() {
|
||||
return {
|
||||
showModal: false, // 添加modal的显示
|
||||
selectedIndex: 0, // 首页还是专题选择的index
|
||||
showModal: false,
|
||||
total: 0,
|
||||
formData: {
|
||||
// 新建模态框的数据
|
||||
status: false, // 模板是否开启
|
||||
name: "", // 模板名称
|
||||
status: false,
|
||||
name: "",
|
||||
},
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
pageType: "INDEX",
|
||||
pageClientType: "PC",
|
||||
},
|
||||
columns: [
|
||||
// 列表展示的column
|
||||
{
|
||||
title: "页面名称",
|
||||
key: "name",
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
},
|
||||
],
|
||||
|
||||
loading: false, // 加载状态
|
||||
loading: false,
|
||||
pageTypes: [
|
||||
// 那种类别的模板
|
||||
{
|
||||
type: "INDEX",
|
||||
title: "首页",
|
||||
},
|
||||
// {
|
||||
// type: "SPECIAL",
|
||||
// title: "专题",
|
||||
// },
|
||||
{ type: "INDEX", title: "首页" },
|
||||
{ type: "SPECIAL", title: "专题" },
|
||||
],
|
||||
list: [], // 模板列表
|
||||
list: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -137,13 +115,13 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
newTemplate() {
|
||||
// 添加,编辑模板
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
const data = this.formData;
|
||||
data.status ? (data.pageShow = "OPEN") : (data.pageShow = "CLOSE");
|
||||
delete data.status;
|
||||
(data.pageType = "STORE"), (data.pageClientType = "PC");
|
||||
(data.pageType = this.searchForm.pageType),
|
||||
(data.pageClientType = "PC");
|
||||
if (data.id) {
|
||||
API_floor.updateHome(data.id, data).then((res) => {
|
||||
this.$Message.success("编辑模板成功");
|
||||
@@ -163,49 +141,47 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
handleTabChange(type) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageType = type;
|
||||
this.getTemplateList();
|
||||
},
|
||||
|
||||
createTemp() {
|
||||
// 新建表单
|
||||
this.$refs.form.resetFields();
|
||||
this.$refs.form?.resetFields();
|
||||
this.formData = { status: false, name: "" };
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
Template(item) {
|
||||
// 编辑表单
|
||||
item.status = item.pageShow;
|
||||
this.formData = item;
|
||||
this.formData = { ...item };
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
decorate(val) {
|
||||
// 装修
|
||||
const data = { id: val.id, pageShow: val.pageShow, pageType: this.searchForm.pageType };
|
||||
|
||||
this.$router.push({
|
||||
name: "renovation",
|
||||
query: { id: val.id, pageShow: val.pageShow },
|
||||
query: data,
|
||||
});
|
||||
},
|
||||
|
||||
// 分页 修改页码
|
||||
changePageNum(val) {
|
||||
this.searchForm.pageNumber = val;
|
||||
this.getTemplateList();
|
||||
},
|
||||
// 分页 修改页数
|
||||
changePageSize(val) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = val;
|
||||
this.getTemplateList();
|
||||
},
|
||||
getTemplateList() {
|
||||
//模板列表
|
||||
// let params = {
|
||||
// pageNumber: 1,
|
||||
// pageSize: 999,
|
||||
// pageType: "INDEX",
|
||||
// pageClientType: "PC",
|
||||
// };
|
||||
this.loading = true;
|
||||
API_floor.getHomeList(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
// this.total
|
||||
this.total = res.result.total;
|
||||
this.list = res.result.records;
|
||||
this.list.forEach((e) => {
|
||||
@@ -220,7 +196,6 @@ export default {
|
||||
},
|
||||
|
||||
releaseTemplate(id) {
|
||||
//发布模板
|
||||
API_floor.releasePageHome(id).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("发布模板成功");
|
||||
@@ -228,7 +203,13 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除模板
|
||||
confirmDel(id) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
content: "删除此模板?",
|
||||
onOk: () => this.delTemplate(id),
|
||||
});
|
||||
},
|
||||
delTemplate(id) {
|
||||
API_floor.removePageHome(id).then((res) => {
|
||||
if (res.success) {
|
||||
@@ -242,62 +223,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.category-item {
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
.active {
|
||||
background: #ededed;
|
||||
}
|
||||
.item-title {
|
||||
background: #d7e7f5 !important;
|
||||
height: 54px;
|
||||
}
|
||||
.no-more {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.wrapper {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
}
|
||||
.category {
|
||||
flex: 2;
|
||||
}
|
||||
.content {
|
||||
flex: 8;
|
||||
}
|
||||
* {
|
||||
margin: 5px;
|
||||
}
|
||||
.list {
|
||||
min-height: 600px;
|
||||
position: relative;
|
||||
}
|
||||
.item:nth-of-type(2) {
|
||||
margin: 0 5px;
|
||||
}
|
||||
.item {
|
||||
width: 100% !important;
|
||||
padding: 0 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
> .item-config {
|
||||
width: 250px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
div:nth-child(2) {
|
||||
margin-right: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.item:nth-of-type(2n + 1) {
|
||||
background: #f5f7fa;
|
||||
.page-type-tabs {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -51,44 +51,41 @@
|
||||
<li class="hz-u-square hz-u-square-br" data-pointer="dealBR"></li>
|
||||
</ul>
|
||||
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="编辑热区"
|
||||
draggable
|
||||
scrollable
|
||||
:mask="false"
|
||||
ok-text="保存"
|
||||
@on-ok="saveZone"
|
||||
@on-cancel="cancelZone"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
@close="cancelZone"
|
||||
>
|
||||
<div>
|
||||
<div class="hz-edit-img">
|
||||
<img class="show-image" :src="zoneForm.img" alt />
|
||||
</div>
|
||||
|
||||
<Form :model="zoneForm" :label-width="80">
|
||||
<!-- <FormItem label="图片链接:">
|
||||
<Input v-model="zoneForm.img"></Input>
|
||||
<Button size="small" type="primary" @click="handleSelectImg"
|
||||
>选择图片</Button
|
||||
<el-form :model="zoneForm" label-width="80px">
|
||||
<!-- <el-form-item label="图片链接:">
|
||||
<el-input v-model="zoneForm.img"></el-input>
|
||||
<el-button size="small" type="primary" @click="handleSelectImg"
|
||||
>选择图片</el-button
|
||||
>
|
||||
:v-model="zoneForm.type === 'goods' ? zoneForm.goodsName : zoneForm.link"
|
||||
</FormItem> -->
|
||||
<FormItem label="跳转链接:">
|
||||
<Input type="textarea" v-if="zoneForm.type === 'other' && zoneForm.title === '外部链接'" v-model="zoneForm.link" ></Input>
|
||||
<Button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</Button
|
||||
</el-form-item> -->
|
||||
<el-form-item label="跳转链接:">
|
||||
<el-input type="textarea" v-if="zoneForm.type === 'other' && zoneForm.title === '外部链接'" v-model="zoneForm.link" ></el-input>
|
||||
<el-button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</el-button
|
||||
>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<el-dialog width="1200px" v-model="picModelFlag" :show-footer="false">
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage"/>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
@@ -175,7 +172,7 @@ export default {
|
||||
},
|
||||
// 已选链接
|
||||
selectedLink(val) {
|
||||
this.zoneForm.link = this.$options.filters.formatLinkType(val);
|
||||
this.zoneForm.link = this.$filters.formatLinkType(val);
|
||||
this.settingZone(val);
|
||||
this.changeInfo(this.zoneForm);
|
||||
},
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
<template>
|
||||
<Modal
|
||||
:styles="{ top: '120px' }"
|
||||
width="800"
|
||||
@on-cancel="clickClose"
|
||||
@on-ok="clickOK"
|
||||
<el-dialog
|
||||
v-model="flag"
|
||||
:mask-closable="false"
|
||||
title="绘制热区"
|
||||
scrollable
|
||||
width="800px"
|
||||
top="8vh"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
@close="clickClose"
|
||||
>
|
||||
<template v-if="flag">
|
||||
<hotzone
|
||||
ref="hotzone"
|
||||
@change="changeHotzone"
|
||||
:zonesInit="res.zoneInfo"
|
||||
:image="res.img"
|
||||
></hotzone>
|
||||
@change="changeHotzone"
|
||||
/>
|
||||
</template>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="clickClose">取消</el-button>
|
||||
<el-button type="primary" @click="clickOK">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import hotzone from "./components/Hotzone.vue";
|
||||
@@ -28,28 +32,24 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
flag: false, // modal显隐
|
||||
flag: false,
|
||||
};
|
||||
},
|
||||
props: ["res"],
|
||||
mounted() {},
|
||||
methods: {
|
||||
changeHotzone(info) {
|
||||
this.$emit("changeZone", info);
|
||||
},
|
||||
// 关闭弹窗
|
||||
clickClose() {
|
||||
this.flag = false;
|
||||
this.$emit("closeFlag", false);
|
||||
},
|
||||
// 点击确认
|
||||
clickOK() {
|
||||
this.clickClose();
|
||||
},
|
||||
// 打开组件方法
|
||||
open(type, mutiple) {
|
||||
open() {
|
||||
this.flag = true;
|
||||
},
|
||||
// 关闭组件
|
||||
close() {
|
||||
this.flag = false;
|
||||
},
|
||||
@@ -57,13 +57,8 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
::v-deep .ivu-modal {
|
||||
:deep(.el-dialog__body) {
|
||||
overflow: hidden;
|
||||
height: 650px !important;
|
||||
}
|
||||
::v-deep .ivu-modal-body {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
<template>
|
||||
<div class="model-form">
|
||||
<div class="model-content">
|
||||
<!-- 头部广告,登录信息,不需要拖拽 -->
|
||||
<div
|
||||
class="top-fixed-advert"
|
||||
:style="{ backgroundColor: topAdvert.bgColor }"
|
||||
>
|
||||
<!-- <img :src="topAdvert.img" width="1200" height="80" alt="" /> -->
|
||||
<img :src="topAdvert.img" width="1200" height="80" alt="" />
|
||||
<div class="setup-box">
|
||||
<Button size="small" @click.stop="handleModel('topAdvert')"
|
||||
>编辑</Button
|
||||
>
|
||||
<el-button size="small" @click.stop="handleModel('topAdvert')">编辑</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-con">
|
||||
@@ -20,20 +17,24 @@
|
||||
<li>请登录</li>
|
||||
<li>我的订单</li>
|
||||
<li>我的足迹</li>
|
||||
<li><Icon size="18" type="ios-cart-outline"></Icon>购物车</li>
|
||||
<li>
|
||||
<el-icon :size="18"><ShoppingCart /></el-icon>
|
||||
购物车
|
||||
</li>
|
||||
<li>店铺入驻</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="search-con">
|
||||
<img :src="require('@/assets/logo.png')" class="logo" alt="" />
|
||||
<div class="search">
|
||||
<i-input size="large" placeholder="输入你想查找的商品">
|
||||
<Button class="soubenStore" slot="append">搜本店</Button>
|
||||
<Button slot="append">搜索</Button>
|
||||
</i-input>
|
||||
<el-input size="large" placeholder="输入你想查找的商品">
|
||||
<template #append>
|
||||
<el-button>搜索</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="nav-con">
|
||||
<div class="nav-con" v-if="$route.query.pageType !== 'SPECIAL'">
|
||||
<div class="all-categories">全部商品分类</div>
|
||||
<ul class="nav-item">
|
||||
<li v-for="(item, index) in navList.list" :key="index">
|
||||
@@ -41,12 +42,9 @@
|
||||
</li>
|
||||
</ul>
|
||||
<div class="setup-box">
|
||||
<Button size="small" @click.stop="handleModel('quickNav')"
|
||||
>编辑</Button
|
||||
>
|
||||
<el-button size="small" @click.stop="handleModel('quickNav')">编辑</el-button>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- 装修主体 -->
|
||||
</div>
|
||||
<div>
|
||||
<draggable
|
||||
class="model-form-list"
|
||||
@@ -55,149 +53,129 @@
|
||||
@end="handleMoveEnd"
|
||||
@add="handleModelAdd"
|
||||
>
|
||||
<template v-for="(element, index) in data.list">
|
||||
<template v-for="(element, index) in data.list" :key="element.key || index">
|
||||
<model-form-item
|
||||
v-if="element && element.key"
|
||||
:key="element.key"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:data="data"
|
||||
></model-form-item>
|
||||
/>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="顶部广告"
|
||||
draggable
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<!-- 顶部广告 -->
|
||||
<div class="modal-top-advert">
|
||||
<div>
|
||||
<img
|
||||
class="show-image"
|
||||
width="600"
|
||||
height="40"
|
||||
:src="topAdvert.img"
|
||||
alt
|
||||
<img class="show-image" width="600" height="40" :src="topAdvert.img" alt />
|
||||
</div>
|
||||
<div class="tips">建议尺寸:<span>{{ topAdvert.size }}</span></div>
|
||||
<div>
|
||||
图片链接:<el-input
|
||||
class="outsideUrl"
|
||||
v-model="topAdvert.url"
|
||||
:disabled="!!topAdvert.type && topAdvert.type !== 'link'"
|
||||
placeholder="https://"
|
||||
/>
|
||||
</div>
|
||||
<div class="tips">
|
||||
建议尺寸:<span>{{ topAdvert.size }}</span>
|
||||
<el-button size="small" type="primary" @click="handleSelectLink">选择链接</el-button>
|
||||
</div>
|
||||
<div>
|
||||
图片链接:<span>{{ topAdvert.url }}</span
|
||||
><Button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</Button
|
||||
>
|
||||
选择图片:<el-button size="small" type="primary" @click="handleSelectImg">选择图片</el-button>
|
||||
</div>
|
||||
<div>
|
||||
选择图片:<Button size="small" type="primary" @click="handleSelectImg"
|
||||
>选择图片</Button
|
||||
>
|
||||
</div>
|
||||
<div>选择背景色:<ColorPicker v-model="topAdvert.bgColor" /></div>
|
||||
<div>选择背景色:<el-color-picker v-model="topAdvert.bgColor" /></div>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="showModalNav"
|
||||
title="快捷导航"
|
||||
draggable
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<!-- 分类tab栏 -->
|
||||
<div class="modal-tab-bar">
|
||||
<Button type="primary" size="small" @click="handleAddNav"
|
||||
>添加分类</Button
|
||||
>
|
||||
<el-button type="primary" size="small" @click="handleAddNav">添加分类</el-button>
|
||||
<table cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="250">分类名称</th>
|
||||
<th width="250">链接地址</th>
|
||||
<!-- <th width="150">排序</th> -->
|
||||
<th width="250">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in navList.list" :key="index">
|
||||
<td><Input v-model="item.name" /></td>
|
||||
<td><Input v-model="item.url" disabled /></td>
|
||||
<!-- <td><Input v-model="item.sort"/></td> -->
|
||||
<td><el-input v-model="item.name" /></td>
|
||||
<td>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleSelectLink(item, index)"
|
||||
>选择链接</Button
|
||||
>
|
||||
<Button type="error" size="small" @click="handleDelNav(index)"
|
||||
>删除</Button
|
||||
>
|
||||
<el-input
|
||||
v-model="item.url"
|
||||
:disabled="!item.title || item.title !== '外部链接'"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<el-button type="primary" size="small" @click="handleSelectLink(item, index)">选择链接</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDelNav(index)">删除</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Modal>
|
||||
<!-- 选择商品。链接 -->
|
||||
</el-dialog>
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage"/>
|
||||
</Modal>
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { ShoppingCart } from "@element-plus/icons-vue";
|
||||
import Draggable from "vuedraggable";
|
||||
import ModelFormItem from "./modelFormItem.vue";
|
||||
// import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import ossManage from "@/views/shop/ossManage";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
export default {
|
||||
name: "modelForm",
|
||||
components: {
|
||||
Draggable,
|
||||
ModelFormItem,
|
||||
ossManage,
|
||||
ShoppingCart,
|
||||
},
|
||||
props: ["data"],
|
||||
data() {
|
||||
return {
|
||||
picModelFlag: false, // 选择图片模态框
|
||||
showModal: false, // 顶部广告模态框
|
||||
showModalNav: false, // 分类nav模态框
|
||||
selectedNav: null, //当前已选nav
|
||||
// 模拟搜索框下方数据
|
||||
promotionTags: [
|
||||
"买2免1",
|
||||
"领200神券",
|
||||
"199减100",
|
||||
"母婴5折抢",
|
||||
"充100送20",
|
||||
], // 热词数据
|
||||
picModelFlag: false,
|
||||
showModal: false,
|
||||
showModalNav: false,
|
||||
selectedNav: null,
|
||||
promotionTags: ["买2免1", "领200神券", "199减100", "母婴5折抢", "充100送20"],
|
||||
topAdvert: {
|
||||
// 头部广告图数据
|
||||
type: "topAdvert",
|
||||
img: "",
|
||||
url: "",
|
||||
bgColor: "#de000d",
|
||||
size: "1200*80",
|
||||
},
|
||||
currentIndex: 0,
|
||||
navList: {
|
||||
// 分类nav数据
|
||||
type: "navBar",
|
||||
list: [
|
||||
{ name: "秒杀", url: "" },
|
||||
{ name: "闪购", url: "" },
|
||||
{ name: "优惠券", url: "" },
|
||||
{ name: "拍卖", url: "" },
|
||||
{ name: "服装城", url: "" },
|
||||
{ name: "秒杀", url: "", title: "" },
|
||||
{ name: "闪购", url: "", title: "" },
|
||||
{ name: "优惠券", url: "", title: "" },
|
||||
{ name: "拍卖", url: "", title: "" },
|
||||
{ name: "服装城", url: "", title: "" },
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -213,33 +191,32 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleSelectLink(item, index) {
|
||||
// 调起选择链接弹窗
|
||||
if (item) this.selectedNav = item;
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.currentIndex = index;
|
||||
},
|
||||
// 已选链接
|
||||
selectedLink(val) {
|
||||
console.log(val);
|
||||
if (this.showModalNav) {
|
||||
this.selectedNav.url = this.$options.filters.formatLinkType(val);
|
||||
this.selectedNav.url = this.$filters.formatLinkType(val);
|
||||
this.selectedNav.type = val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
} else {
|
||||
this.topAdvert.url = this.$options.filters.formatLinkType(val);
|
||||
this.topAdvert.url = this.$filters.formatLinkType(val);
|
||||
this.topAdvert.type = val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
}
|
||||
this.navList.list[this.currentIndex].title = val.title;
|
||||
},
|
||||
handleDelNav(index) {
|
||||
// 删除导航
|
||||
this.navList.list.splice(index, 1);
|
||||
},
|
||||
handleAddNav() {
|
||||
// 添加导航
|
||||
this.navList.list.push({ name: "", url: "" });
|
||||
console.log(this.navList.list);
|
||||
this.navList.list.push({ name: "", url: "", title: "" });
|
||||
this.$nextTick(() => {
|
||||
this.selectedNav.title = val.title;
|
||||
});
|
||||
},
|
||||
// 拖动结束回调
|
||||
handleMoveEnd({ newIndex, oldIndex }) {
|
||||
console.log("index", newIndex, oldIndex);
|
||||
},
|
||||
// 修改顶部广告
|
||||
handleModel(type) {
|
||||
if (type == "topAdvert") {
|
||||
this.showModal = true;
|
||||
@@ -247,35 +224,27 @@ export default {
|
||||
this.showModalNav = true;
|
||||
}
|
||||
},
|
||||
// 选择图片
|
||||
handleSelectImg() {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
},
|
||||
callbackSelected(item) {
|
||||
// 选择图片回调
|
||||
this.picModelFlag = false;
|
||||
this.topAdvert.img = item.url;
|
||||
},
|
||||
handleModelAdd(evt) {
|
||||
// 拖拽,添加模块
|
||||
const newIndex = evt.newIndex;
|
||||
|
||||
// 为拖拽到容器的元素添加唯一 key
|
||||
this.data.list[newIndex] = JSON.parse(
|
||||
JSON.stringify(this.data.list[newIndex])
|
||||
);
|
||||
const key =
|
||||
Date.parse(new Date()) + "_" + Math.ceil(Math.random() * 99999);
|
||||
this.$set(this.data.list, newIndex, {
|
||||
this.data.list[newIndex] = JSON.parse(JSON.stringify(this.data.list[newIndex]));
|
||||
const key = Date.parse(new Date()) + "_" + Math.ceil(Math.random() * 99999);
|
||||
this.data.list[newIndex] = {
|
||||
...this.data.list[newIndex],
|
||||
options: {
|
||||
...this.data.list[newIndex].options,
|
||||
},
|
||||
key,
|
||||
// 绑定键值
|
||||
model: this.data.list[newIndex].type + "_" + key,
|
||||
});
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -294,7 +263,6 @@ export default {
|
||||
.model-form-list {
|
||||
min-height: 500px;
|
||||
}
|
||||
/** 顶部广告,头部,搜索框 start */
|
||||
.top-fixed-advert {
|
||||
display: flex;
|
||||
width: 1500px;
|
||||
@@ -336,7 +304,6 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 搜索框 */
|
||||
.search-con {
|
||||
padding-top: 15px;
|
||||
margin: 0px auto;
|
||||
@@ -353,34 +320,27 @@ export default {
|
||||
.search {
|
||||
width: 460px;
|
||||
margin: 0 auto;
|
||||
::v-deep .ivu-input.ivu-input-large {
|
||||
:deep(.el-input--large .el-input__wrapper) {
|
||||
border: 2px solid $theme_color;
|
||||
font-size: 12px;
|
||||
height: 34px;
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
box-shadow: none;
|
||||
}
|
||||
::v-deep .ivu-input-group-append {
|
||||
:deep(.el-input-group__append) {
|
||||
border: 1px solid $theme_color;
|
||||
border-left: none;
|
||||
height: 30px;
|
||||
background-color: $theme_color;
|
||||
color: #ffffff;
|
||||
button {
|
||||
.el-button {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.soubenStore {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
background-color: #f90;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 商品分类 */
|
||||
.nav-con {
|
||||
width: 1200px;
|
||||
height: 40px;
|
||||
@@ -416,7 +376,6 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 顶部广告,头部,搜索框 end */
|
||||
|
||||
.top-fixed-advert,
|
||||
.nav-con {
|
||||
@@ -427,14 +386,8 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 装修模态框 内部样式start */
|
||||
.modal-top-advert {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
> * {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
align-items: start;
|
||||
padding: 0 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
/>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button
|
||||
<el-button
|
||||
size="small"
|
||||
@click.stop="handleSelectModel(element.options.list[0])"
|
||||
>编辑</Button
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,8 +43,8 @@
|
||||
<img :src="item.img" width="230" height="190" alt="" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</Button
|
||||
<el-button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,6 +56,10 @@
|
||||
<template v-if="element.type == 'seckill'">
|
||||
<seckill :data="element"></seckill>
|
||||
</template>
|
||||
<!-- 限时秒杀 待完善 -->
|
||||
<template v-if="element.type == 'seckill-only-album'">
|
||||
<seckill-only-album :data="element"></seckill-only-album>
|
||||
</template>
|
||||
<!-- 折扣广告 -->
|
||||
<template v-if="element.type == 'discountAdvert'">
|
||||
<div
|
||||
@@ -74,8 +78,8 @@
|
||||
<img :src="item.img" width="190" height="210" alt="" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</Button
|
||||
<el-button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -90,8 +94,8 @@
|
||||
<img :src="item.img" width="240" height="105" alt="" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</Button
|
||||
<el-button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,6 +115,26 @@
|
||||
<template v-if="element.type == 'firstAdvert'">
|
||||
<first-page-advert :data="element"></first-page-advert>
|
||||
</template>
|
||||
<!-- 商品模块 -->
|
||||
<template v-if="element.type == 'goodsType'">
|
||||
<goodsType :data="element" class="mb_20 width_1200_auto"></goodsType>
|
||||
</template>
|
||||
<!-- 商品模块2 -->
|
||||
<template v-if="element.type == 'onlyGoodsModel'">
|
||||
<onlyGoodsModel :data="element" class="mb_20 width_1200_auto"></onlyGoodsModel>
|
||||
</template>
|
||||
<!-- 混合模块 -->
|
||||
<template v-if="element.type == 'mixModel'">
|
||||
<mixModel :data="element" class="mb_20 width_1200_auto"></mixModel>
|
||||
</template>
|
||||
<!-- 为你推荐 -->
|
||||
<template v-if="element.type == 'forYour'">
|
||||
<forYour :data="element" class="mb_20 width_1200_auto"></forYour>
|
||||
</template>
|
||||
<!-- 一行三列 -->
|
||||
<template v-if="element.type == 'oneRowThreeColumns'">
|
||||
<oneRowThreeColumns :data="element" class="mb_20 width_1200_auto"></oneRowThreeColumns>
|
||||
</template>
|
||||
<!-- 横幅广告 -->
|
||||
<template v-if="element.type == 'bannerAdvert'">
|
||||
<div class="horizontal-advert setup-content">
|
||||
@@ -126,10 +150,10 @@
|
||||
</div>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button
|
||||
<el-button
|
||||
size="small"
|
||||
@click.stop="handleSelectModel(element.options)"
|
||||
>编辑</Button
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,15 +163,15 @@
|
||||
<not-enough :data="element"></not-enough>
|
||||
</template>
|
||||
<div class="del-btn">
|
||||
<Button size="small" type="error" @click="handleModelDelete">删除</Button>
|
||||
<el-button size="small" type="danger" @click="handleModelDelete">删除</el-button>
|
||||
</div>
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
draggable
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<div class="modal-top-advert">
|
||||
<div>
|
||||
@@ -198,41 +222,55 @@
|
||||
建议尺寸:<span>{{ selected.size }}</span>
|
||||
</div>
|
||||
<div>
|
||||
图片链接:<span>{{ selected.url }}</span>
|
||||
<Button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</Button
|
||||
图片链接:<el-input
|
||||
class="outsideUrl"
|
||||
v-model="selected.url"
|
||||
:disabled="!!selected.type && selected.type !== 'link'"
|
||||
placeholder="https://"
|
||||
/>
|
||||
<el-button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</el-button
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
选择图片:<Button size="small" type="primary" @click="handleSelectImg">选择图片</Button>
|
||||
选择图片:<el-button size="small" type="primary" @click="handleSelectImg"
|
||||
>选择图片</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
|
||||
></liliDialog>
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage"/>
|
||||
</Modal>
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModelCarousel from "./modelList/carousel.vue";
|
||||
import ModelCarousel1 from './modelList/carousel1.vue';
|
||||
import ModelCarousel2 from './modelList/carousel2.vue';
|
||||
import ModelCarousel1 from "./modelList/carousel1.vue";
|
||||
import ModelCarousel2 from "./modelList/carousel2.vue";
|
||||
import FirstPageAdvert from "./modelList/firstPageAdvert.vue";
|
||||
import NewGoodsSort from "./modelList/newGoodsSort.vue";
|
||||
import Recommend from "./modelList/recommend.vue";
|
||||
import NotEnough from "./modelList/notEnough.vue";
|
||||
import Seckill from "./modelList/seckill.vue";
|
||||
// import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import ossManage from "@/views/shop/ossManages";
|
||||
import goodsType from "./modelList/goodsAndType.vue";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
|
||||
import mixModel from "./modelList/mixModel.vue";
|
||||
import forYour from "./modelList/forYour.vue";
|
||||
import onlyGoodsModel from "./modelList/onlyGoodsModel.vue";
|
||||
|
||||
import oneRowThreeColumns from "./modelList/oneRowThreeColumns.vue";
|
||||
import seckillOnlyAlbum from "./modelList/seckill-only-album.vue";
|
||||
export default {
|
||||
name: "modelFormItem",
|
||||
props: ["element", "select", "index", "data"],
|
||||
@@ -245,7 +283,13 @@ export default {
|
||||
FirstPageAdvert,
|
||||
NotEnough,
|
||||
Seckill,
|
||||
goodsType,
|
||||
ossManage,
|
||||
oneRowThreeColumns,
|
||||
"seckill-only-album":seckillOnlyAlbum,
|
||||
onlyGoodsModel,
|
||||
mixModel,
|
||||
forYour
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -278,9 +322,11 @@ export default {
|
||||
},
|
||||
// 确定选择链接
|
||||
selectedLink(val) {
|
||||
this.selected.url = this.$options.filters.formatLinkType(val);
|
||||
this.selected.url = this.$filters.formatLinkType(val);
|
||||
this.selected.type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
},
|
||||
|
||||
|
||||
handleSelectImg() {
|
||||
// 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
@@ -433,7 +479,7 @@ export default {
|
||||
height: inherit;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
.ivu-icon {
|
||||
.el-icon {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
@@ -457,14 +503,14 @@ export default {
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
.ivu-icon {
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
&:hover {
|
||||
background-color: $theme_color;
|
||||
color: #fff;
|
||||
.ivu-icon {
|
||||
.el-icon {
|
||||
transform: rotateZ(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,55 +5,60 @@
|
||||
<div class="nav-side">分类占位区</div>
|
||||
<div class="nav-content setup-content">
|
||||
<!-- 轮播图 -->
|
||||
<Carousel autoplay>
|
||||
<CarouselItem v-for="(item, index) in data.options.list" :key="index">
|
||||
<el-carousel autoplay height="340px">
|
||||
<el-carousel-item v-for="(item, index) in data.options.list" :key="index">
|
||||
<div style="overflow: hidden">
|
||||
<img :src="item.img" width="790" height="340" />
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</Carousel>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
|
||||
<el-button size="small" @click.stop="handleSelectModel">编辑</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<div class="person-msg">
|
||||
<img :src="userInfo.face" v-if="userInfo.face" alt />
|
||||
<Avatar icon="ios-person" class="mb_10" v-else size="80" />
|
||||
<div>Hi,{{ userInfo.nickName || "欢迎来到管理后台" | secrecyMobile }}</div>
|
||||
<el-avatar class="mb_10" v-else :size="80" />
|
||||
<div>
|
||||
Hi,{{ userInfo.nickName || "欢迎来到管理后台" }}
|
||||
</div>
|
||||
<div v-if="userInfo.id">
|
||||
<Button type="error" shape="circle">会员中心</Button>
|
||||
<el-button type="danger" circle>会员中心</el-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<Button type="error" shape="circle">请登录</Button>
|
||||
<el-button type="danger" circle>请登录</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shop-msg">
|
||||
<div>
|
||||
<span>常见问题</span>
|
||||
<ul class="article-list">
|
||||
<li class="ellipsis" :alt="article.title" v-for="(article, index) in articleList" :key="index" @click="goArticle(article.id)">
|
||||
{{article.title}}
|
||||
<li
|
||||
class="ellipsis"
|
||||
:alt="article.title"
|
||||
v-for="(article, index) in articleList"
|
||||
:key="index"
|
||||
>
|
||||
{{ article.title }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="快捷导航"
|
||||
draggable
|
||||
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
|
||||
|
||||
>
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-tab-bar">
|
||||
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
|
||||
<el-button type="primary" size="small" @click="handleAdd">添加轮播</el-button>
|
||||
|
||||
<span class="ml_10">图片尺寸:{{ data.size }}</span>
|
||||
<div style="color: #999" class="fz_12">点击缩略图替换图片</div>
|
||||
@@ -78,87 +83,91 @@
|
||||
alt=""
|
||||
/>
|
||||
</td>
|
||||
<td><Input v-model="item.url" disabled /></td>
|
||||
<!-- <td><Input v-model="item.sort"/></td> -->
|
||||
<td>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleSelectImg(item)"
|
||||
>选择图片</Button
|
||||
>
|
||||
<Button
|
||||
type="info"
|
||||
<el-input
|
||||
class="outsideUrl"
|
||||
v-model="item.url"
|
||||
:disabled="!!item.type && item.type !== 'link'"
|
||||
/>
|
||||
</td>
|
||||
<!-- <td><el-input v-model="item.sort"/></td> -->
|
||||
<td>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleSelectLink(item)"
|
||||
>选择链接</Button
|
||||
@click="handleSelectImg(item)"
|
||||
>选择图片</el-button
|
||||
>
|
||||
<Button
|
||||
type="error"
|
||||
ghost
|
||||
<el-button type="info" size="small" @click="handleSelectLink(item)"
|
||||
>选择链接</el-button
|
||||
>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
size="small"
|
||||
@click="handleDel(index)"
|
||||
>删除</Button
|
||||
>删除</el-button
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
|
||||
></liliDialog>
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import ossManage from "@/views/shop/ossManages";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
export default {
|
||||
name: "modelCarousel",
|
||||
props: ["data"],
|
||||
components: {
|
||||
ossManage
|
||||
ossManage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showModal: false, // modal显隐
|
||||
selected: null, // 已选数据
|
||||
picModelFlag: false, // 选择图片modal
|
||||
userInfo:{},
|
||||
articleList:[
|
||||
{title:'促销计算规则'},
|
||||
{title:'商家申请开店'},
|
||||
{title:'商家账号注册'},
|
||||
{title:'促销计算规则'}
|
||||
]
|
||||
userInfo: {},
|
||||
articleList: [
|
||||
{ title: "促销计算规则" },
|
||||
{ title: "商家申请开店" },
|
||||
{ title: "商家账号注册" },
|
||||
{ title: "促销计算规则" },
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleSelectModel () {
|
||||
handleSelectModel() {
|
||||
// 编辑模块
|
||||
this.showModal = true;
|
||||
},
|
||||
// 添加轮播图
|
||||
handleAdd () {
|
||||
this.data.options.list.push({ img: "", url: "" });
|
||||
handleAdd() {
|
||||
this.data.options.list.push({ img: "", url: "", type: "" });
|
||||
this.$forceUpdate();
|
||||
},
|
||||
handleSelectLink (item) {
|
||||
handleSelectLink(item) {
|
||||
// 选择链接
|
||||
this.$refs.liliDialog.open('link')
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.selected = item;
|
||||
},
|
||||
callbackSelected (item) { // 选择图片回调
|
||||
callbackSelected(item) {
|
||||
// 选择图片回调
|
||||
this.picModelFlag = false;
|
||||
this.selected.img = item.url;
|
||||
},
|
||||
@@ -166,10 +175,11 @@ export default {
|
||||
// 删除图片
|
||||
this.data.options.list.splice(index, 1);
|
||||
},
|
||||
selectedLink(val) { // 选择链接回调
|
||||
console.log(val);
|
||||
this.selected.url = this.$options.filters.formatLinkType(val);
|
||||
console.log(this.selected.url);
|
||||
selectedLink(val) {
|
||||
// 选择链接回调
|
||||
this.selected.url = this.$filters.formatLinkType(val);
|
||||
this.selected.type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
},
|
||||
// 选择图片
|
||||
handleSelectImg(item) {
|
||||
@@ -241,7 +251,7 @@ export default {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ivu-btn-default {
|
||||
.el-btn-default {
|
||||
color: $theme_color;
|
||||
border-color: $theme_color;
|
||||
}
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
<template>
|
||||
<div class="model-carousel1" :style="{background: bgColor}">
|
||||
<div class="model-carousel1" :style="{ background: bgColor }">
|
||||
<div class="nav-body clearfix">
|
||||
<!-- 侧边导航 -->
|
||||
<div class="nav-side">分类占位区</div>
|
||||
<div class="nav-content setup-content">
|
||||
<!-- 轮播图 -->
|
||||
<Carousel autoplay @on-change="autoChange">
|
||||
<CarouselItem v-for="(item, index) in data.options.list" :key="index" >
|
||||
<el-carousel autoplay @change="autoChange">
|
||||
<el-carousel-item v-for="(item, index) in data.options.list" :key="index">
|
||||
<div style="overflow: hidden">
|
||||
<img :src="item.img" width="1200" height="470" />
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</Carousel>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
|
||||
<el-button size="small" @click.stop="handleSelectModel">编辑</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="快捷导航"
|
||||
draggable
|
||||
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
|
||||
|
||||
>
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-tab-bar">
|
||||
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
|
||||
<el-button type="primary" size="small" @click="handleAdd">添加轮播</el-button>
|
||||
|
||||
<span class="ml_10">图片尺寸:{{ data.size }}</span>
|
||||
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片、点击颜色选择器选择背景色</span>
|
||||
<span style="color: red" class="fz_12 ml_10"
|
||||
>点击缩略图替换图片、点击颜色选择器选择背景色</span
|
||||
>
|
||||
<table cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -54,82 +54,81 @@
|
||||
alt=""
|
||||
/>
|
||||
</td>
|
||||
<td><Input v-model="item.url" disabled /></td>
|
||||
<td>
|
||||
<Button
|
||||
type="info"
|
||||
size="small"
|
||||
@click="handleSelectLink(item)"
|
||||
>选择链接</Button
|
||||
<el-input
|
||||
class="outsideUrl"
|
||||
v-model="item.url"
|
||||
:disabled="!!item.type && item.type !== 'link'"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<el-button type="info" size="small" @click="handleSelectLink(item)"
|
||||
>选择链接</el-button
|
||||
>
|
||||
<ColorPicker size="small" v-model="item.bgColor" />
|
||||
<el-color-picker size="small" v-model="item.bgColor" />
|
||||
|
||||
<Button
|
||||
type="error"
|
||||
ghost
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
size="small"
|
||||
@click="handleDel(index)"
|
||||
>删除</Button
|
||||
>删除</el-button
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
|
||||
></liliDialog>
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage @callback="callbackSelected" :is-component="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import ossManage from "@/views/shop/ossManages";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
export default {
|
||||
name: "modelCarousel",
|
||||
props: ["data"],
|
||||
components: {
|
||||
ossManage
|
||||
ossManage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showModal: false, // modal显隐
|
||||
selected: null, // 已选数据
|
||||
picModelFlag: false, // 选择图片modal
|
||||
bgColor:'#fff' // 轮播背景色
|
||||
bgColor: "#fff", // 轮播背景色
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
this.bgColor = this.data.options.list[0].bgColor
|
||||
mounted() {
|
||||
this.bgColor = this.data.options.list[0].bgColor;
|
||||
},
|
||||
methods: {
|
||||
handleSelectModel () {
|
||||
handleSelectModel() {
|
||||
// 编辑模块
|
||||
this.showModal = true;
|
||||
},
|
||||
// 自动切换时改变背景色
|
||||
autoChange (oVal,val) {
|
||||
this.bgColor = this.data.options.list[val].bgColor
|
||||
autoChange(oVal, val) {
|
||||
this.bgColor = this.data.options.list[val].bgColor;
|
||||
},
|
||||
// 添加轮播图片和链接
|
||||
handleAdd () {
|
||||
this.data.options.list.push({ img: "", url: "", bgColor: '#fff' });
|
||||
handleAdd() {
|
||||
this.data.options.list.push({ img: "", url: "", bgColor: "#fff" });
|
||||
this.$forceUpdate();
|
||||
},
|
||||
// 打开选择链接modal
|
||||
handleSelectLink (item) {
|
||||
this.$refs.liliDialog.open('link')
|
||||
handleSelectLink(item) {
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.selected = item;
|
||||
},
|
||||
callbackSelected (item) { // 选择图片回调
|
||||
callbackSelected(item) {
|
||||
// 选择图片回调
|
||||
this.picModelFlag = false;
|
||||
this.selected.img = item.url;
|
||||
},
|
||||
@@ -137,15 +136,18 @@ export default {
|
||||
handleDel(index) {
|
||||
this.data.options.list.splice(index, 1);
|
||||
},
|
||||
selectedLink(val) { // 选择链接回调
|
||||
this.selected.url = this.$options.filters.formatLinkType(val);
|
||||
selectedLink(val) {
|
||||
// 选择链接回调
|
||||
this.selected.url = this.$filters.formatLinkType(val);
|
||||
this.selected.type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
},
|
||||
// 打开选择图片modal
|
||||
handleSelectImg(item) {
|
||||
this.selected = item;
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -164,14 +166,13 @@ export default {
|
||||
width: 1200px;
|
||||
height: 470px;
|
||||
margin: 0px auto;
|
||||
|
||||
}
|
||||
.nav-side {
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
padding: 0px;
|
||||
color: #fff;
|
||||
background-color:rgba(0,0,0,.5);
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
line-height: 470px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
|
||||
@@ -5,23 +5,26 @@
|
||||
<div class="nav-side">分类占位区</div>
|
||||
<div class="nav-content setup-content">
|
||||
<!-- 轮播图 -->
|
||||
<Carousel autoplay>
|
||||
<CarouselItem v-for="(item, index) in data.options.list" :key="index">
|
||||
<el-carousel autoplay height="340px">
|
||||
<el-carousel-item v-for="(item, index) in data.options.list" :key="index">
|
||||
<div style="overflow: hidden">
|
||||
<img :src="item.img" width="590" height="470" />
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</Carousel>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
|
||||
<el-button size="small" @click.stop="handleSelectModel">编辑</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-content1 setup-content">
|
||||
<!-- 轮播图 -->
|
||||
<Carousel autoplay :autoplay-speed="5000">
|
||||
<CarouselItem v-for="(item, index) in data.options.listRight" :key="index">
|
||||
<el-carousel autoplay :autoplay-speed="5000">
|
||||
<el-carousel-item
|
||||
v-for="(item, index) in data.options.listRight"
|
||||
:key="index"
|
||||
>
|
||||
<div class="mb_10">
|
||||
<img :src="item[0].img" width="190" height="150" />
|
||||
</div>
|
||||
@@ -31,49 +34,56 @@
|
||||
<div>
|
||||
<img :src="item[2].img" width="190" height="150" />
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</Carousel>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
|
||||
<el-button size="small" @click.stop="handleSelectModel">编辑</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<div class="person-msg">
|
||||
<img :src="userInfo.face" v-if="userInfo.face" alt />
|
||||
<Avatar icon="ios-person" class="mb_10" v-else size="80" />
|
||||
<div>Hi,{{ userInfo.nickName || "欢迎来到管理后台" | secrecyMobile }}</div>
|
||||
<el-avatar class="mb_10" v-else :size="80" />
|
||||
<div>
|
||||
Hi,{{ userInfo.nickName || "欢迎来到管理后台" }}
|
||||
</div>
|
||||
<div v-if="userInfo.id">
|
||||
<Button type="error" shape="circle">会员中心</Button>
|
||||
<el-button type="danger" circle>会员中心</el-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<Button type="error" shape="circle">请登录</Button>
|
||||
<el-button type="danger" circle>请登录</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shop-msg">
|
||||
<div>
|
||||
<span>常见问题</span>
|
||||
<ul class="article-list">
|
||||
<li class="ellipsis" :alt="article.title" v-for="(article, index) in articleList" :key="index" @click="goArticle(article.id)">
|
||||
{{article.title}}
|
||||
<li
|
||||
class="ellipsis"
|
||||
:alt="article.title"
|
||||
v-for="(article, index) in articleList"
|
||||
:key="index"
|
||||
>
|
||||
{{ article.title }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>)
|
||||
</div>
|
||||
</div>
|
||||
<!-- 左侧轮播装修 -->
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="快捷导航"
|
||||
draggable
|
||||
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
>
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-tab-bar">
|
||||
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
|
||||
<el-button type="primary" size="small" @click="handleAdd">添加轮播</el-button>
|
||||
|
||||
<span class="ml_10">图片尺寸:{{ data.size }}</span>
|
||||
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片</span>
|
||||
@@ -97,42 +107,57 @@
|
||||
alt=""
|
||||
/>
|
||||
</td>
|
||||
<td><Input v-model="item.url" disabled /></td>
|
||||
<td>
|
||||
<Button
|
||||
type="info"
|
||||
size="small"
|
||||
@click="handleSelectLink(item)"
|
||||
>选择链接</Button>
|
||||
<Button
|
||||
type="error"
|
||||
ghost
|
||||
<el-input
|
||||
class="outsideUrl"
|
||||
v-model="item.url"
|
||||
:disabled="!!item.type && item.type !== 'link'"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<el-button type="info" size="small" @click="handleSelectLink(item)"
|
||||
>选择链接</el-button
|
||||
>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
size="small"
|
||||
@click="handleDel(index)"
|
||||
>删除</Button
|
||||
>删除</el-button
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 右侧轮播装修 -->
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="右侧装修"
|
||||
draggable
|
||||
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
>
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-tab-bar">
|
||||
<Button type="primary" size="small" @click="handleAddGroup">添加组</Button>
|
||||
<el-button type="primary" size="small" @click="handleAddGroup"
|
||||
>添加组</el-button
|
||||
>
|
||||
|
||||
<span class="ml_10">图片尺寸:{{ data.size }}</span>
|
||||
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片</span>
|
||||
<Tabs type="card" closable @on-tab-remove="handleTabRemove" class="mt_10">
|
||||
<TabPane :label="'图片组'+(gIndex+1)" v-for="(group, gIndex) in data.options.listRight" :key="gIndex">
|
||||
<el-tabs
|
||||
type="card"
|
||||
closable
|
||||
@tab-remove="handleTabRemove"
|
||||
class="mt_10"
|
||||
>
|
||||
<el-tab-pane
|
||||
:label="'图片组' + (gIndex + 1)"
|
||||
v-for="(group, gIndex) in data.options.listRight"
|
||||
:key="gIndex"
|
||||
>
|
||||
<table cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -153,85 +178,89 @@
|
||||
alt=""
|
||||
/>
|
||||
</td>
|
||||
<td><Input v-model="item.url" disabled /></td>
|
||||
<td>
|
||||
<Button
|
||||
<el-input
|
||||
class="outsideUrl"
|
||||
v-model="item.url"
|
||||
:disabled="!!item.type && item.type !== 'link'"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<el-button
|
||||
type="info"
|
||||
size="small"
|
||||
@click="handleSelectLink(item)"
|
||||
>选择链接</Button>
|
||||
>选择链接</el-button
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
></liliDialog>
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage @callback="callbackSelected" :is-component="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import ossManage from "@/views/shop/ossManage";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
export default {
|
||||
name: "modelCarousel",
|
||||
props: ["data"],
|
||||
components: {
|
||||
ossManage
|
||||
ossManage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showModal: false, // modal显隐
|
||||
selected: null, // 已选数据
|
||||
picModelFlag: false, // 选择图片modal
|
||||
userInfo:{},
|
||||
articleList:[
|
||||
{title:'促销计算规则'},
|
||||
{title:'商家申请开店'},
|
||||
{title:'商家账号注册'},
|
||||
{title:'促销计算规则'}
|
||||
]
|
||||
userInfo: {},
|
||||
articleList: [
|
||||
{ title: "促销计算规则" },
|
||||
{ title: "商家申请开店" },
|
||||
{ title: "商家账号注册" },
|
||||
{ title: "促销计算规则" },
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleSelectModel () {
|
||||
handleSelectModel() {
|
||||
// 编辑模块
|
||||
this.showModal = true;
|
||||
},
|
||||
// 添加轮播
|
||||
handleAdd () {
|
||||
handleAdd() {
|
||||
this.data.options.list.push({ img: "", url: "" });
|
||||
this.$forceUpdate();
|
||||
},
|
||||
// 添加图片组
|
||||
handleAddGroup () {
|
||||
handleAddGroup() {
|
||||
this.data.options.listRight.push([
|
||||
{img:'',url:''},
|
||||
{img:'',url:''},
|
||||
{img:'',url:''}
|
||||
])
|
||||
{ img: "", url: "" },
|
||||
{ img: "", url: "" },
|
||||
{ img: "", url: "" },
|
||||
]);
|
||||
},
|
||||
// 删除图片组
|
||||
handleTabRemove (index) {
|
||||
this.data.options.listRight.splice(index, 1)
|
||||
handleTabRemove(index) {
|
||||
this.data.options.listRight.splice(index, 1);
|
||||
},
|
||||
// 打开图片链接
|
||||
handleSelectLink (item) {
|
||||
this.$refs.liliDialog.open('link')
|
||||
handleSelectLink(item) {
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.selected = item;
|
||||
},
|
||||
callbackSelected (item) { // 选择图片回调
|
||||
callbackSelected(item) {
|
||||
// 选择图片回调
|
||||
this.picModelFlag = false;
|
||||
this.selected.img = item.url;
|
||||
},
|
||||
@@ -239,10 +268,11 @@ export default {
|
||||
handleDel(index) {
|
||||
this.data.options.list.splice(index, 1);
|
||||
},
|
||||
selectedLink(val) { // 选择链接回调
|
||||
console.log(val);
|
||||
this.selected.url = this.$options.filters.formatLinkType(val);
|
||||
console.log(this.selected.url);
|
||||
selectedLink(val) {
|
||||
// 选择链接回调
|
||||
this.selected.url = this.$filters.formatLinkType(val);
|
||||
this.selected.type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
},
|
||||
// 打开选择图片modal
|
||||
handleSelectImg(item) {
|
||||
@@ -293,7 +323,8 @@ export default {
|
||||
}
|
||||
|
||||
/*导航内容*/
|
||||
.nav-content,.nav-content1 {
|
||||
.nav-content,
|
||||
.nav-content1 {
|
||||
width: 590px;
|
||||
height: 470px;
|
||||
overflow: hidden;
|
||||
@@ -301,7 +332,7 @@ export default {
|
||||
position: relative;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.nav-content1{
|
||||
.nav-content1 {
|
||||
width: 190px;
|
||||
}
|
||||
.nav-right {
|
||||
@@ -319,7 +350,7 @@ export default {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ivu-btn-default {
|
||||
.el-btn-default {
|
||||
color: $theme_color;
|
||||
border-color: $theme_color;
|
||||
}
|
||||
|
||||
@@ -1,163 +1,199 @@
|
||||
<template>
|
||||
<div class="first-page-advert">
|
||||
<div class="item setup-content" :style="{backgroundImage:`linear-gradient(to right, ${item.fromColor}, ${item.toColor})`}" v-for="(item, index) in options.list" :key="index">
|
||||
<div>
|
||||
<span class="line top-line"></span>
|
||||
<p>{{item.name}}</p>
|
||||
<span class="line btm-line"></span>
|
||||
<p>{{item.describe}}</p>
|
||||
</div>
|
||||
<img :src="item.img" width="170" height="170" alt="">
|
||||
<div class="setup-box">
|
||||
<div><Button size="small" @click.stop="handleSelectModel(item)">编辑</Button></div>
|
||||
</div>
|
||||
<div class="first-page-advert">
|
||||
<div
|
||||
class="item setup-content"
|
||||
:style="{
|
||||
backgroundImage: `linear-gradient(to right, ${item.fromColor}, ${item.toColor})`,
|
||||
}"
|
||||
v-for="(item, index) in options.list"
|
||||
:key="index"
|
||||
>
|
||||
<div>
|
||||
<span class="line top-line"></span>
|
||||
<p>{{ item.name }}</p>
|
||||
<span class="line btm-line"></span>
|
||||
<p>{{ item.describe }}</p>
|
||||
</div>
|
||||
<img :src="item.img" width="170" height="170" alt="" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
<Modal
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
draggable
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
|
||||
|
||||
>
|
||||
<div class="modal-top-advert">
|
||||
<div>
|
||||
<img class="show-image" width="170" height="170" :src="selected.img" alt />
|
||||
</div>
|
||||
<div>
|
||||
<span>图片主标题:</span><Input v-model="selected.name" />
|
||||
</div>
|
||||
<div>
|
||||
<span>图片描述:</span><Input v-model="selected.describe" />
|
||||
</div>
|
||||
<div class="tips">
|
||||
建议尺寸:<span>{{ selected.size }}</span>
|
||||
</div>
|
||||
<div>
|
||||
图片链接:<span>{{ selected.url }}</span> <Button size="small" type="primary" @click="handleSelectLink">选择链接</Button>
|
||||
</div>
|
||||
<div>
|
||||
<span>渐变背景色:</span><Input v-model="selected.fromColor" /> <ColorPicker v-if="selected.fromColor" v-model="selected.fromColor" />
|
||||
</div>
|
||||
<div>
|
||||
<span>渐变背景色:</span><Input v-model="selected.toColor" /> <ColorPicker v-if="selected.toColor" v-model="selected.toColor" />
|
||||
</div>
|
||||
<div :style="{backgroundImage:`linear-gradient(to right, ${selected.fromColor}, ${selected.toColor})`}" class="exhibition"></div>
|
||||
<div>
|
||||
选择图片:<Button size="small" type="primary" @click="handleSelectImg">选择图片</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
|
||||
></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
|
||||
width="800"
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-top-advert">
|
||||
<div>
|
||||
<img
|
||||
class="show-image"
|
||||
width="170"
|
||||
height="170"
|
||||
:src="selected.img"
|
||||
alt
|
||||
/>
|
||||
</div>
|
||||
<div><span>图片主标题:</span><el-input v-model="selected.name" /></div>
|
||||
<div><span>图片描述:</span><el-input v-model="selected.describe" /></div>
|
||||
<div class="tips">
|
||||
建议尺寸:<span>{{ selected.size }}</span>
|
||||
</div>
|
||||
<div>
|
||||
图片链接:<el-input
|
||||
class="outsideUrl"
|
||||
v-model="selected.url"
|
||||
:disabled="!!selected.type && selected.type !== 'link'"
|
||||
placeholder="https://"
|
||||
/>
|
||||
<el-button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</el-button
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<span>渐变背景色:</span><el-input v-model="selected.fromColor" />
|
||||
<el-color-picker v-if="selected.fromColor" v-model="selected.fromColor" />
|
||||
</div>
|
||||
<div>
|
||||
<span>渐变背景色:</span><el-input v-model="selected.toColor" />
|
||||
<el-color-picker v-if="selected.toColor" v-model="selected.toColor" />
|
||||
</div>
|
||||
<div
|
||||
:style="{
|
||||
backgroundImage: `linear-gradient(to right, ${selected.fromColor}, ${selected.toColor})`,
|
||||
}"
|
||||
class="exhibition"
|
||||
></div>
|
||||
<div>
|
||||
选择图片:<el-button size="small" type="primary" @click="handleSelectImg"
|
||||
>选择图片</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import ossManage from "@/views/shop/ossManage";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
export default {
|
||||
props:{
|
||||
data: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
components: {ossManage},
|
||||
data() {
|
||||
return {
|
||||
options: this.data.options, // 当前类型数据
|
||||
showModal: false, // modal显隐
|
||||
selected: {}, // 已选数据
|
||||
picModelFlag: false // 图片选择器
|
||||
}
|
||||
},
|
||||
components: { ossManage },
|
||||
data() {
|
||||
return {
|
||||
options: this.data.options, // 当前类型数据
|
||||
showModal: false, // modal显隐
|
||||
selected: {}, // 已选数据
|
||||
picModelFlag: false, // 图片选择器
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 打开装修modal
|
||||
handleSelectModel(item, type) {
|
||||
this.selected = item;
|
||||
this.showModal = true;
|
||||
},
|
||||
methods:{
|
||||
// 打开装修modal
|
||||
handleSelectModel (item,type) {
|
||||
this.selected = item;
|
||||
this.showModal = true
|
||||
},
|
||||
handleSelectLink(item,index) { // 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open('link')
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink(val) {
|
||||
this.selected.url = this.$options.filters.formatLinkType(val);;
|
||||
},
|
||||
handleSelectImg(){ // 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
},
|
||||
// 选择图片回调
|
||||
callbackSelected (val) {
|
||||
this.picModelFlag = false;
|
||||
this.selected.img = val.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleSelectLink(item, index) {
|
||||
// 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open("link");
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink(val) {
|
||||
this.selected.url = this.$filters.formatLinkType(val);
|
||||
this.selected.type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
},
|
||||
handleSelectImg() {
|
||||
// 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
},
|
||||
// 选择图片回调
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
this.selected.img = val.url;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import './setup-box.scss';
|
||||
.first-page-advert{
|
||||
@import "./setup-box.scss";
|
||||
.first-page-advert {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
// margin-top: -10px;
|
||||
.item {
|
||||
width: 393px;
|
||||
height: 170px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
// margin-top: -10px;
|
||||
.item{
|
||||
width: 393px;
|
||||
height: 170px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
img{margin-left: 20px;}
|
||||
|
||||
&:nth-of-type(1),&:nth-of-type(2),&:nth-of-type(3){margin-top: 0;}
|
||||
|
||||
p:nth-of-type(1){
|
||||
margin: 3px 0;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
}
|
||||
p:nth-of-type(2){
|
||||
margin-top: 3px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
}
|
||||
.line{
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 2px;
|
||||
background: url('../../../assets/festival_icon.png');
|
||||
z-index: 1;
|
||||
}
|
||||
.top-line{
|
||||
width: 78px;
|
||||
background-position: -1px -3px;
|
||||
}
|
||||
.btm-line{
|
||||
background-position: 0 -11px;
|
||||
width: 154px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
img {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
&:nth-of-type(1),
|
||||
&:nth-of-type(2),
|
||||
&:nth-of-type(3) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
p:nth-of-type(1) {
|
||||
margin: 3px 0;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
}
|
||||
p:nth-of-type(2) {
|
||||
margin-top: 3px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.line {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 2px;
|
||||
background: url(../../../assets/festival_icon.png);
|
||||
z-index: 1;
|
||||
}
|
||||
.top-line {
|
||||
width: 78px;
|
||||
background-position: -1px -3px;
|
||||
}
|
||||
.btm-line {
|
||||
background-position: 0 -11px;
|
||||
width: 154px;
|
||||
}
|
||||
}
|
||||
.modal-top-advert{
|
||||
align-items: start;
|
||||
padding: 0 30px;
|
||||
.exhibition{
|
||||
width: 300px;
|
||||
height: 50px;
|
||||
}
|
||||
.modal-top-advert {
|
||||
align-items: start;
|
||||
padding: 0 30px;
|
||||
.exhibition {
|
||||
width: 300px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
445
seller/src/views/shop/modelList/forYour.vue
Normal file
445
seller/src/views/shop/modelList/forYour.vue
Normal file
@@ -0,0 +1,445 @@
|
||||
<template>
|
||||
<div class="model" v-if="data">
|
||||
<div class="for-your">{{ data.options.title }}</div>
|
||||
|
||||
<div class="flex card">
|
||||
<div class="left">
|
||||
<img :src="data.options.data.image.src" alt="" />
|
||||
</div>
|
||||
<div class="right flex">
|
||||
<!-- 商品区 -->
|
||||
<div class="goods-list">
|
||||
<div
|
||||
class="goods-item"
|
||||
:key="index"
|
||||
v-for="(item, index) in data.options.data.list"
|
||||
>
|
||||
<div>
|
||||
<div class="goods-name">{{ item.title }}</div>
|
||||
<div class="goods-desc">{{ item.desc }}</div>
|
||||
</div>
|
||||
<img class="goods-img" :src="item.img" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 热卖区 -->
|
||||
<div class="hot-list">
|
||||
<div class="hot-title">{{ data.options.data.hot.title }}</div>
|
||||
<div
|
||||
class="hot-item flex flex-a-c"
|
||||
v-for="(item, index) in data.options.data.hot.list"
|
||||
:key="index"
|
||||
>
|
||||
<img :src="item.img" alt="" />
|
||||
<div class="hot-goods">
|
||||
<div class="hot-goods-title">{{ item.title }}</div>
|
||||
<div>
|
||||
<div class="hot-price">¥{{ $filters.unitPrice(item.price) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button size="small" @click.stop="handleSelectModel()">编辑 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
|
||||
width="800"
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div>
|
||||
<div class="modal-tab-bar">
|
||||
<div>
|
||||
主标题:
|
||||
<el-input style="width: 200px" v-model="data.options.title" />
|
||||
</div>
|
||||
<el-divider content-position="left">左侧商品部分</el-divider>
|
||||
<div class="flex">
|
||||
<div>图片 :</div>
|
||||
<div>
|
||||
<img class="image" :src="data.options.data.image.src" alt="" />
|
||||
<div>
|
||||
<div>推荐尺寸:{{ data.options.data.image.size }}</div>
|
||||
<div class="link-src">
|
||||
链接地址:
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="data.options.data.image.url"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleSelectImg('image')"
|
||||
>选择图片
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectLink('image')"
|
||||
>选择链接
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-divider content-position="left">中间商品部分</el-divider>
|
||||
<div class="flex column-list">
|
||||
<div
|
||||
v-for="(item, index) in data.options.data.list"
|
||||
:key="index"
|
||||
class="draggable"
|
||||
>
|
||||
<div class="flex">
|
||||
<img :src="item.img" class="column-img" />
|
||||
<div class="column-goods-list">
|
||||
<div><el-input v-model="item.title" /></div>
|
||||
<div><el-input v-model="item.desc" /></div>
|
||||
<div><el-input disabled v-model="item.url" /></div>
|
||||
<div>{{ item.size }}</div>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectLink('list', index)"
|
||||
>选择链接
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectImg('list', index)"
|
||||
>选择图片
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider content-position="left">右侧商品部分</el-divider>
|
||||
<div class="flex">
|
||||
<div>右侧标题 :</div>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="data.options.data.hot.title"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex column-list">
|
||||
<div
|
||||
v-for="(item, index) in data.options.data.hot.list"
|
||||
:key="index"
|
||||
class="draggable"
|
||||
>
|
||||
<div class="flex">
|
||||
<img :src="item.img" class="column-img" />
|
||||
<div class="column-goods-list">
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectGoods('hot', index)"
|
||||
>选择商品
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></liliDialog>
|
||||
|
||||
<!-- 选择图片 -->
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage.vue";
|
||||
|
||||
export default {
|
||||
name: "forYour",
|
||||
data() {
|
||||
return {
|
||||
showModal: false,
|
||||
|
||||
picModelFlag: false,
|
||||
selectedData: "", //选中的数据
|
||||
goodsIndex: 0, // 商品索引
|
||||
align: "",
|
||||
defaultCallbackImageType: "",
|
||||
current: "",
|
||||
};
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ossManage,
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
handleSelectImg(type, index) {
|
||||
this.defaultCallbackImageType = type;
|
||||
this.goodsIndex = index;
|
||||
// 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
},
|
||||
|
||||
handleSelectGoods(val, index) {
|
||||
this.$refs.liliDialog.open("goods");
|
||||
this.$refs.liliDialog.singleGoods();
|
||||
this.selectedData = val;
|
||||
this.goodsIndex = index;
|
||||
},
|
||||
handleSelectLink(val, index) {
|
||||
// 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.selectedData = val;
|
||||
|
||||
this.goodsIndex = index;
|
||||
},
|
||||
// 回显图片
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
if (this.defaultCallbackImageType == "image") {
|
||||
this.data.options.data.image.src = val.url;
|
||||
} else {
|
||||
this.data.options.data[this.defaultCallbackImageType][
|
||||
this.goodsIndex
|
||||
].img = val.url;
|
||||
}
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData(val) {
|
||||
this.data.options.data.hot.list[this.goodsIndex].img = val[0].thumbnail;
|
||||
this.data.options.data.hot.list[this.goodsIndex].title = val[0].goodsName;
|
||||
this.data.options.data.hot.list[this.goodsIndex].price = val[0].price;
|
||||
this.data.options.data.hot.list[this.goodsIndex].url =
|
||||
this.$filters.formatLinkType(val[0]);
|
||||
|
||||
console.log(val, this.selectedData, this.goodsIndex);
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink(val) {
|
||||
console.log(val,this.selectedData)
|
||||
if (this.selectedData == "image") {
|
||||
this.data.options.data.image.url =
|
||||
this.$filters.formatLinkType(val);
|
||||
} else {
|
||||
console.log(this.data.options.data.list,this.goodsIndex)
|
||||
this.data.options.data.list[
|
||||
this.goodsIndex
|
||||
].url = this.$filters.formatLinkType(val);
|
||||
}
|
||||
},
|
||||
/*
|
||||
* 点击不同模块进行编辑
|
||||
* 判断也很简单,就是第一个第二个模块进行判断
|
||||
*
|
||||
* */
|
||||
handleSelectModel() {
|
||||
this.showModal = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./setup-box.scss";
|
||||
.goods-list {
|
||||
display: flex;
|
||||
width: 558px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.goods-item {
|
||||
width: 278px;
|
||||
height: 277px;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
border-right: 1.4px solid #e2e2e2;
|
||||
&:nth-of-type(3) {
|
||||
border-top: 1.4px solid #e2e2e2;
|
||||
}
|
||||
&:nth-of-type(4) {
|
||||
border-top: 1.4px solid #e2e2e2;
|
||||
}
|
||||
}
|
||||
.active {
|
||||
color: #f31947;
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
margin-top: 23px;
|
||||
font-size: 25px;
|
||||
font-weight: normal;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: #333333;
|
||||
}
|
||||
.goods-img {
|
||||
width: 190px;
|
||||
height: 156px;
|
||||
border-radius: 10px;
|
||||
margin-top: 19px;
|
||||
}
|
||||
.goods-desc {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 17px;
|
||||
text-align: center;
|
||||
margin-top: 11px;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: #333333;
|
||||
}
|
||||
.for-your {
|
||||
font-size: 35px;
|
||||
font-weight: normal;
|
||||
line-height: 42px;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
margin-bottom: 32px;
|
||||
|
||||
color: #333333;
|
||||
}
|
||||
.column-goods-list {
|
||||
> div {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
.link-src {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.card,
|
||||
.right-card {
|
||||
opacity: 1;
|
||||
background: #ffffff;
|
||||
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
.setup-box {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column-img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.column-list {
|
||||
flex-wrap: wrap;
|
||||
|
||||
> div {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.modal-tab-bar {
|
||||
> .flex {
|
||||
align-items: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.draggable {
|
||||
margin: 10px 0;
|
||||
> .flex {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.left {
|
||||
width: 346px;
|
||||
height: 554px;
|
||||
border-radius: 9.8px 0px 0px 9.8px;
|
||||
> img {
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
width: 839px;
|
||||
height: 554px;
|
||||
border-radius: 0px 9.8px 9.8px 0px;
|
||||
}
|
||||
.hot-list {
|
||||
width: 279px;
|
||||
}
|
||||
.hot-title {
|
||||
margin-left: 25px;
|
||||
line-height: 63px;
|
||||
font-size: 17px;
|
||||
font-weight: normal;
|
||||
|
||||
letter-spacing: 0px;
|
||||
color: #333333;
|
||||
height: 63px;
|
||||
}
|
||||
.hot-item {
|
||||
box-sizing: border-box;
|
||||
border-top: 1.4px solid #e2e2e2;
|
||||
height: 122px;
|
||||
padding-left: 14px;
|
||||
align-items: center;
|
||||
> img {
|
||||
width: 76.3px;
|
||||
height: 77.7px;
|
||||
}
|
||||
}
|
||||
.hot-goods {
|
||||
margin-left: 14px;
|
||||
}
|
||||
.hot-goods-title {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
line-height: 16px;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: #333333;
|
||||
}
|
||||
.hot-price {
|
||||
margin-top: 10.3px;
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
line-height: 29px;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: #f31947;
|
||||
}
|
||||
</style>
|
||||
365
seller/src/views/shop/modelList/goodsAndType.vue
Normal file
365
seller/src/views/shop/modelList/goodsAndType.vue
Normal file
@@ -0,0 +1,365 @@
|
||||
<template>
|
||||
<div class="goods-type-wrapper">
|
||||
<div class="flex goods-type-line">
|
||||
<div class="goods-type-title">{{ data.options.title }}</div>
|
||||
<div class="flex goods-type-labels">
|
||||
<div
|
||||
@click="tabCurrentlyIndex = index"
|
||||
:class="{ active: tabCurrentlyIndex === index }"
|
||||
class="goods-type-item"
|
||||
v-for="(item, index) in data.options.labels"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品部分 -->
|
||||
<div class="goods-list flex">
|
||||
<div
|
||||
class="goods-list-item"
|
||||
v-for="(item, index) in data.options.list.filter((subset) => {
|
||||
return subset.___index == tabCurrentlyIndex;
|
||||
})"
|
||||
:key="index"
|
||||
>
|
||||
<div class="goods-img">
|
||||
<img :src="item.img" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="goods-name wes-2">{{ item.title }}</div>
|
||||
<div class="goods-desc">{{ item.desc }}</div>
|
||||
</div>
|
||||
<div class="goods-price">
|
||||
{{ $filters.unitPrice(item.price, "¥") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button
|
||||
size="small"
|
||||
@click.stop="handleSelectModel(data.options.list)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
|
||||
width="800"
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-tab-bar">
|
||||
<div class="tab-bar">
|
||||
标题
|
||||
<el-input style="width: 300px" v-model="data.options.title" />
|
||||
</div>
|
||||
<div class="tab-bar" v-if="data.options.labels[tabCurrentlyIndex]">
|
||||
标签
|
||||
<el-input
|
||||
style="width: 300px"
|
||||
v-model="data.options.labels[tabCurrentlyIndex].label"
|
||||
/>
|
||||
</div>
|
||||
<el-button @click="handleTabsAdd" size="small" class="mb_10">增加</el-button>
|
||||
<el-tabs
|
||||
type="card"
|
||||
v-model="tabIndex"
|
||||
@tab-click="handleClickTab"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="(tab,tabIndex) in data.options.labels"
|
||||
:key="tabIndex"
|
||||
:label="tab.label"
|
||||
:name="tab.___index + ''"
|
||||
>
|
||||
<div class="flex flex-a-c">
|
||||
<el-button class="del-btn" type="primary" @click="handleContextMenuDelete(tab,tabIndex)">删除当前标签</el-button>
|
||||
<el-button class="add-goods" @click="addCurrentGoods">
|
||||
添加商品
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(item, index) in data.options.list.filter((subset) => {
|
||||
return subset.___index == tabCurrentlyIndex;
|
||||
})"
|
||||
:key="index"
|
||||
class="draggable"
|
||||
>
|
||||
<div class="flex">
|
||||
<img :src="item.img" class="column-img" />
|
||||
<div class="flex column-goods-config">
|
||||
<div class="column-config">
|
||||
<div>
|
||||
标题:
|
||||
<el-input v-model="item.title" />
|
||||
</div>
|
||||
<div>
|
||||
描述:
|
||||
<el-input v-model="item.desc" />
|
||||
</div>
|
||||
</div>
|
||||
<el-button @click="delGoods(item)">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></liliDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "goods",
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabIndex:0,
|
||||
current: 0,
|
||||
showModal: false,
|
||||
selected: {}, // 已选数据
|
||||
picModelFlag: false,
|
||||
tabCurrentlyIndex: 0, // 选项卡索引
|
||||
};
|
||||
},
|
||||
mounted(){
|
||||
this.tabIndex = this.data.options.labels[0].___index
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 算出最大的index 然后索引叠加
|
||||
*/
|
||||
handleTabsAdd() {
|
||||
let findAllIndex = this.data.options.labels.map((item) => {
|
||||
return item.___index;
|
||||
});
|
||||
let max = Math.max.apply(null, findAllIndex);
|
||||
|
||||
this.data.options.labels.push({
|
||||
label: "标签" + (max + 1),
|
||||
___index: max + 1,
|
||||
});
|
||||
},
|
||||
// 删除标签
|
||||
handleContextMenuDelete(item,index) {
|
||||
// 删除标签下关联的商品
|
||||
this.data.options.list.forEach((lab,currently)=>{
|
||||
if(lab.___index == item.___index){
|
||||
this.data.options.list.splice(currently,1)
|
||||
}
|
||||
})
|
||||
// 删除当前标签
|
||||
this.data.options.labels.splice(index,1)
|
||||
},
|
||||
// 删除商品
|
||||
delGoods(val) {
|
||||
this.data.options.list.forEach((item, i) => {
|
||||
if (
|
||||
item.title == val.title &&
|
||||
item.___index == this.tabCurrentlyIndex
|
||||
) {
|
||||
this.data.options.list.splice(i, 1);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 切换选项卡
|
||||
handleClickTab(name) {
|
||||
console.log(name)
|
||||
this.tabCurrentlyIndex = name;
|
||||
},
|
||||
// 添加当前选项卡中的商品
|
||||
addCurrentGoods() {
|
||||
|
||||
this.$refs.liliDialog.clearGoodsSelected();
|
||||
this.$refs.liliDialog.open("goods");
|
||||
},
|
||||
// 编辑模块
|
||||
handleSelectModel(item) {
|
||||
console.log(item);
|
||||
this.selected = item;
|
||||
this.showModal = true;
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData(val) {
|
||||
if (val.length) {
|
||||
val.forEach((item) => {
|
||||
const pushGoodsDetail = {
|
||||
img: item.thumbnail,
|
||||
price: item.price,
|
||||
title: item.goodsName,
|
||||
desc: "",
|
||||
url: `/goodsDetail?skuId=${item.id}&goodsId=${item.goodsId}`,
|
||||
___index: this.tabCurrentlyIndex,
|
||||
};
|
||||
this.data.options.list.push(pushGoodsDetail);
|
||||
});
|
||||
}
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink(val) {
|
||||
this.selected[this.current].url =
|
||||
this.$filters.formatLinkType(val);
|
||||
this.selected[this.current].type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
|
||||
console.log(this.selected[this.current]);
|
||||
},
|
||||
handleSelectLink(index) {
|
||||
// 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.current = index;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./setup-box.scss";
|
||||
.goods-type-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.del-btn{
|
||||
margin-left:10px;
|
||||
}
|
||||
.tab-bar {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.draggable {
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #ededed;
|
||||
transition: 0.35s;
|
||||
|
||||
&:hover {
|
||||
background-color: #ededed;
|
||||
}
|
||||
}
|
||||
.column-config {
|
||||
margin-left: 10px;
|
||||
> * {
|
||||
margin: 4px;
|
||||
}
|
||||
}
|
||||
.column-img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.add-goods {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.goods-list {
|
||||
position: relative;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
&:hover {
|
||||
> .setup-box {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
.column-goods-config {
|
||||
flex: 2;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.goods-list-item {
|
||||
margin-bottom: 14.3px;
|
||||
width: 287px;
|
||||
height: 343.7px;
|
||||
border-radius: 9.8px;
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
background: #ffffff;
|
||||
transition: 0.35s;
|
||||
box-shadow: 0px 1px 13px 0px #e5e5e5;
|
||||
&:hover {
|
||||
box-shadow: 0px 1px 14px 0px #c5c5c5;
|
||||
}
|
||||
}
|
||||
.goods-img {
|
||||
text-align: center;
|
||||
> img {
|
||||
width: auto;
|
||||
max-height: 183px;
|
||||
}
|
||||
}
|
||||
.goods-name {
|
||||
font-size: 18px;
|
||||
font-weight: normal;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
width: 200px;
|
||||
margin: 0 auto 12.4px auto;
|
||||
color: #333333;
|
||||
-webkit-text-stroke: #979797 0.7px; /* 浏览器可能不支持 */
|
||||
}
|
||||
.goods-desc {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 17px;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
margin-bottom: 12.4px;
|
||||
color: #666666;
|
||||
|
||||
-webkit-text-stroke: #979797 0.7px; /* 浏览器可能不支持 */
|
||||
}
|
||||
.goods-price {
|
||||
font-size: 25.2px;
|
||||
font-weight: normal;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: #f31947;
|
||||
-webkit-text-stroke: #979797 0.7px; /* 浏览器可能不支持 */
|
||||
}
|
||||
.goods-type-line {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.goods-type-title {
|
||||
font-size: 31px;
|
||||
font-weight: normal;
|
||||
line-height: 37px;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: #333333;
|
||||
}
|
||||
.active {
|
||||
color: #f31947;
|
||||
}
|
||||
.goods-type-labels {
|
||||
font-size: 21px;
|
||||
font-weight: normal;
|
||||
line-height: 25px;
|
||||
letter-spacing: 0px;
|
||||
}
|
||||
.goods-type-item {
|
||||
margin-left: 28px;
|
||||
}
|
||||
</style>
|
||||
326
seller/src/views/shop/modelList/mixModel.vue
Normal file
326
seller/src/views/shop/modelList/mixModel.vue
Normal file
@@ -0,0 +1,326 @@
|
||||
<template>
|
||||
<div class="mix-model">
|
||||
<!-- 左侧 -->
|
||||
<div class="left-card">
|
||||
<left :data="data" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button size="small" @click.stop="handleSelectModel('left')"
|
||||
>编辑
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧 -->
|
||||
<div class="right-card">
|
||||
<right :data="data" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button size="small" @click.stop="handleSelectModel('right')"
|
||||
>编辑
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
|
||||
width="800"
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div v-if="current">
|
||||
<div class="modal-tab-bar">
|
||||
<div>
|
||||
当前模块 :
|
||||
<el-button-group>
|
||||
<el-button :type="current.model == 'goods' ? 'primary' : 'default'"
|
||||
>商品</el-button
|
||||
>
|
||||
<el-button :type="current.model == 'brand' ? 'primary' : 'default'"
|
||||
>品牌</el-button
|
||||
>
|
||||
</el-button-group>
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<div>图片 :</div>
|
||||
<div>
|
||||
<img class="image" :src="current.data.image.src" alt="" />
|
||||
<div>
|
||||
<div>推荐尺寸:{{ current.data.image.size }}</div>
|
||||
<div class="link-src">
|
||||
链接地址:
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="current.data.image.url"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleSelectImg('default')"
|
||||
>选择图片
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectLink('image')"
|
||||
>选择链接
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex" v-if="current.model == 'goods'">
|
||||
<div>标签 :</div>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
type="text"
|
||||
v-model="current.data.badge.label"
|
||||
/>
|
||||
<el-input
|
||||
style="width: 100px; margin-left: 10px"
|
||||
disabled
|
||||
type="text"
|
||||
v-model="current.data.badge.url"
|
||||
/>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectLink('badge')"
|
||||
>选择链接
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="flex column-list">
|
||||
<div
|
||||
v-for="(item, index) in current.data.list"
|
||||
:key="index"
|
||||
class="draggable"
|
||||
>
|
||||
<div class="flex">
|
||||
<img :src="item.img" class="column-img" />
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
v-if="current.model == 'goods'"
|
||||
@click="handleSelectGoods('list', index)"
|
||||
>选择商品
|
||||
</el-button>
|
||||
<div>
|
||||
<div v-if="current.model == 'brand'" style="margin-bottom: 10px">
|
||||
<el-input disabled v-model="item.url" />
|
||||
</div>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
v-if="current.model == 'brand'"
|
||||
@click="handleSelectLink('list', index)"
|
||||
>
|
||||
选择链接
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
v-if="current.model == 'brand'"
|
||||
@click="handleSelectImg('list', index)"
|
||||
>选择图片
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></liliDialog>
|
||||
|
||||
<!-- 选择图片 -->
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import left from "./mixs/mix-goods";
|
||||
import right from "./mixs/mix-brand";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage.vue";
|
||||
|
||||
export default {
|
||||
name: "mixModel",
|
||||
data() {
|
||||
return {
|
||||
showModal: false,
|
||||
current: "", //当前选择的模块
|
||||
picModelFlag: false,
|
||||
selectedData: "", //选中的数据
|
||||
goodsIndex: 0, // 商品索引
|
||||
align: "",
|
||||
defaultCallbackImageType: "",
|
||||
};
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
left,
|
||||
right,
|
||||
ossManage,
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
handleSelectImg(type, index) {
|
||||
this.defaultCallbackImageType = type;
|
||||
this.goodsIndex = index;
|
||||
// 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
},
|
||||
|
||||
handleSelectGoods(val, index) {
|
||||
this.$refs.liliDialog.open("goods");
|
||||
this.$refs.liliDialog.singleGoods();
|
||||
this.selectedData = val;
|
||||
this.goodsIndex = index;
|
||||
},
|
||||
handleSelectLink(val, index) {
|
||||
// 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.selectedData = val;
|
||||
this.goodsIndex = index;
|
||||
},
|
||||
// 回显图片
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
if (this.defaultCallbackImageType == "default") {
|
||||
console.log(this.current.data.image);
|
||||
this.current.data.image.src = val.url;
|
||||
} else {
|
||||
console.log(this.goodsIndex, this.data.options[this.align].data.list);
|
||||
this.data.options[this.align].data.list[this.goodsIndex].img = val.url;
|
||||
|
||||
// this.data.options[this.align].data[this.selectedData][this.goodsIndex].url = val.img
|
||||
}
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData(val) {
|
||||
console.log(val);
|
||||
this.$nextTick(() => {
|
||||
this.data.options[this.align].data.list[this.goodsIndex].img =
|
||||
val[0].thumbnail;
|
||||
this.data.options[this.align].data.list[this.goodsIndex].title =
|
||||
val[0].goodsName;
|
||||
this.data.options[this.align].data.list[this.goodsIndex].price =
|
||||
val[0].price;
|
||||
this.data.options[this.align].data.list[this.goodsIndex].url =
|
||||
val[0].url;
|
||||
});
|
||||
console.log(this.data.options[this.align].data.list[this.goodsIndex]);
|
||||
this.$forceUpdate();
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink(val) {
|
||||
if (this.selectedData != "list") {
|
||||
this.data.options[this.align].data[this.selectedData].url = this.$filters.formatLinkType(val);
|
||||
console.log(this.data.options[this.align].data[this.selectedData])
|
||||
}
|
||||
if (this.selectedData == "list") {
|
||||
this.data.options[this.align].data[this.selectedData][this.goodsIndex]
|
||||
.url = this.$filters.formatLinkType(val);
|
||||
}
|
||||
},
|
||||
/*
|
||||
* 点击不同模块进行编辑
|
||||
* 判断也很简单,就是第一个第二个模块进行判断
|
||||
*
|
||||
* */
|
||||
handleSelectModel(align) {
|
||||
this.align = align;
|
||||
this.current = this.data.options[align];
|
||||
console.log(this.data.options[align]);
|
||||
this.showModal = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./setup-box.scss";
|
||||
|
||||
.link-src {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.mix-model {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.left-card,
|
||||
.right-card {
|
||||
width: 584px;
|
||||
height: 344px;
|
||||
border-radius: 10px;
|
||||
opacity: 1;
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 1px 13px 0px #e5e5e5;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
.setup-box {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column-img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.column-list {
|
||||
flex-wrap: wrap;
|
||||
|
||||
> div {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.modal-tab-bar {
|
||||
> .flex {
|
||||
align-items: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.draggable {
|
||||
> .flex {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
133
seller/src/views/shop/modelList/mixs/mix-brand.vue
Normal file
133
seller/src/views/shop/modelList/mixs/mix-brand.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="flex" v-if="data.options.right.model == 'brand'">
|
||||
<div class="left-side" >
|
||||
<img :src="data.options.right.data.image.src" alt="">
|
||||
</div>
|
||||
<div>
|
||||
<div class="badge-box flex">
|
||||
<div class="round">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="flex goods-list">
|
||||
<div class="goods-item flex" :key="index" v-for="(item,index) in data.options.right.data.list">
|
||||
<div class="goods-thumbnail">
|
||||
<img :src="item.img" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ArrowRight } from "@element-plus/icons-vue";
|
||||
export default {
|
||||
name: "mix-goods",
|
||||
components: { ArrowRight },
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.goods-detail{
|
||||
|
||||
}
|
||||
.goods-detail-title{
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
color: #333333;
|
||||
}
|
||||
.goods-detail-price{
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 17px;
|
||||
letter-spacing: 0px;
|
||||
color: #F31947;
|
||||
margin-top: 8px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.goods-thumbnail{
|
||||
margin-left: 7px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
>img{
|
||||
width:90px;
|
||||
height: 90px;
|
||||
}
|
||||
}
|
||||
.badge-box{
|
||||
margin-top: 33px;
|
||||
justify-content:right;
|
||||
>.round{
|
||||
width: 17.5px;
|
||||
height: 17.5px;
|
||||
opacity: 1;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 17.5px;
|
||||
border: 0.7px solid #333333;
|
||||
margin-right: 17.5px;
|
||||
}
|
||||
}
|
||||
.goods-list{
|
||||
flex-wrap: wrap;
|
||||
justify-content:space-between;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.goods-item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width:50%;
|
||||
height: 85px;
|
||||
border-radius: 9.8px;
|
||||
opacity: 1;
|
||||
transition: .35s;
|
||||
background: #FFFFFF;
|
||||
margin-bottom:9px;
|
||||
|
||||
|
||||
}
|
||||
.left-side {
|
||||
>img{
|
||||
width: 254px;
|
||||
height: 344px;
|
||||
border-radius: 9.8px 0px 0px 9.8px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.badge {
|
||||
width: 50px;
|
||||
height: 27px;
|
||||
line-height:27px;
|
||||
border-radius: 13.3px 0px 0px 13.3px;
|
||||
opacity: 1;
|
||||
background: #F31947;
|
||||
font-size: 12.6px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
color: #FFFFFF;
|
||||
margin-top: 26px;
|
||||
margin-bottom:17px;
|
||||
}
|
||||
</style>
|
||||
124
seller/src/views/shop/modelList/mixs/mix-goods.vue
Normal file
124
seller/src/views/shop/modelList/mixs/mix-goods.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="flex" v-if="data.options.left.model == 'goods'">
|
||||
<div class="left-side" >
|
||||
<img :src="data.options.left.data.image.src" alt="">
|
||||
</div>
|
||||
<div>
|
||||
<div class="badge-box flex">
|
||||
<div class="badge">
|
||||
{{data.options.left.data.badge.label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex goods-list">
|
||||
<div class="goods-item flex" :key="index" v-for="(item,index) in data.options.left.data.list">
|
||||
<div class="goods-thumbnail">
|
||||
<img :src="item.img" alt="">
|
||||
</div>
|
||||
<div class="goods-detail">
|
||||
<div class="goods-detail-title">{{item.title}}</div>
|
||||
<div class="goods-detail-price">{{ $filters.unitPrice(item.price, '¥') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "mix-goods",
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.goods-detail{
|
||||
|
||||
}
|
||||
.goods-detail-title{
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
color: #333333;
|
||||
}
|
||||
.goods-detail-price{
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 17px;
|
||||
letter-spacing: 0px;
|
||||
color: #F31947;
|
||||
margin-top: 8px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.goods-thumbnail{
|
||||
margin-left: 7px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
>img{
|
||||
width:90px;
|
||||
height: 90px;
|
||||
}
|
||||
}
|
||||
.badge-box{
|
||||
|
||||
justify-content:right;
|
||||
}
|
||||
.goods-list{
|
||||
flex-wrap: wrap;
|
||||
justify-content:space-between;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.goods-item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 173.6px;
|
||||
height: 119px;
|
||||
border-radius: 9.8px;
|
||||
opacity: 1;
|
||||
transition: .35s;
|
||||
background: #FFFFFF;
|
||||
margin-bottom:9px;
|
||||
&:hover{
|
||||
box-shadow: 0px 1px 6px 0px #E5E5E5;
|
||||
}
|
||||
|
||||
}
|
||||
.left-side {
|
||||
>img{
|
||||
border-radius: 10px 0px 0px 10px;
|
||||
display: block;
|
||||
width: 196.7px;
|
||||
height: 343.7px;
|
||||
}
|
||||
}
|
||||
.badge {
|
||||
width: 50px;
|
||||
height: 27px;
|
||||
line-height:27px;
|
||||
border-radius: 13.3px 0px 0px 13.3px;
|
||||
opacity: 1;
|
||||
background: #F31947;
|
||||
font-size: 12.6px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
color: #FFFFFF;
|
||||
margin-top: 26px;
|
||||
margin-bottom:17px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,340 +1,447 @@
|
||||
<template>
|
||||
<div class="new-goods">
|
||||
|
||||
<div class="left">
|
||||
<div class="top-header setup-content" :style="{background:options.left.bgColor}">
|
||||
<span>{{options.left.title}}</span>
|
||||
<span>{{options.left.secondTitle}} ></span>
|
||||
<div class="setup-box">
|
||||
<div><Button size="small" @click.stop="handleSelectModel(options.left,true)">编辑</Button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="con-item setup-content" v-for="(item, index) in options.left.list" :key="index">
|
||||
<div>
|
||||
<p>{{item.name}}</p>
|
||||
<p class="describe">{{item.describe}}</p>
|
||||
</div>
|
||||
<img :src="item.img" alt="">
|
||||
<div class="setup-box">
|
||||
<div><Button size="small" @click.stop="handleSelectModel(item)">编辑</Button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="middle">
|
||||
<div class="top-header setup-content" :style="{background:options.middle.bgColor}">
|
||||
<span>{{options.middle.title}}</span>
|
||||
<span>{{options.middle.secondTitle}} ></span>
|
||||
<div class="setup-box">
|
||||
<div><Button size="small" @click.stop="handleSelectModel(options.middle,true)">编辑</Button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="con-item setup-content" v-for="(item, index) in options.middle.list" :key="index">
|
||||
<div>
|
||||
<p>{{item.name}}</p>
|
||||
<p class="describe">{{item.describe}}</p>
|
||||
</div>
|
||||
<img :src="item.img" alt="">
|
||||
<div class="setup-box">
|
||||
<div><Button size="small" @click.stop="handleSelectModel(item)">编辑</Button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<div class="top-header setup-content" :style="{background:options.right.bgColor}">
|
||||
<span>{{options.right.title}}</span>
|
||||
<span>{{options.right.secondTitle}} ></span>
|
||||
<div class="setup-box">
|
||||
<div><Button size="small" @click.stop="handleSelectModel(options.right,true)">编辑</Button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="setup-content" v-for="(item, index) in options.right.list" :key="index">
|
||||
<img :src="item.img" alt="">
|
||||
<p>{{item.name}}</p>
|
||||
<p>{{item.price | unitPrice('¥')}}</p>
|
||||
<div class="jiaobiao" :class="'jiaobiao'+(index+1)">{{index+1}}</div>
|
||||
<div class="setup-box">
|
||||
<div><Button size="small" @click.stop="handleSelectGoods(item)">编辑</Button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 装修内容 -->
|
||||
<Modal
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
draggable
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
|
||||
|
||||
<div class="new-goods">
|
||||
<div class="left">
|
||||
<div
|
||||
class="top-header setup-content"
|
||||
:style="{ background: options.left.bgColor }"
|
||||
>
|
||||
<span>{{ options.left.title }}</span>
|
||||
<span>{{ options.left.secondTitle }} ></span>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button
|
||||
size="small"
|
||||
@click.stop="handleSelectModel(options.left, true)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<div class="modal-top-advert">
|
||||
<div>
|
||||
<img class="show-image" width="160" height="160" v-if="selected.size && selected.size.indexOf('160*160')>=0" :src="selected.img" alt />
|
||||
<img class="show-image" width="80" height="80" v-if="selected.size && selected.size.indexOf('90*90')>=0" :src="selected.img" alt />
|
||||
</div>
|
||||
<div>
|
||||
<span>图片主标题:</span><Input v-model="selected.name" />
|
||||
</div>
|
||||
<div>
|
||||
<span>图片描述:</span><Input v-model="selected.describe" />
|
||||
</div>
|
||||
<div class="tips">
|
||||
建议尺寸:<span>{{ selected.size }}</span>
|
||||
</div>
|
||||
<div>
|
||||
图片链接:<span>{{ selected.url }}</span> <Button size="small" type="primary" @click="handleSelectLink">选择链接</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button size="small" type="primary" @click="handleSelectImg">选择图片</Button>
|
||||
|
||||
<Button size="small" type="primary" @click="handleSelectGoods('')">选择商品</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div
|
||||
class="con-item setup-content"
|
||||
v-for="(item, index) in options.left.list"
|
||||
:key="index"
|
||||
>
|
||||
<div>
|
||||
<p>{{ item.name }}</p>
|
||||
<p class="describe">{{ item.describe }}</p>
|
||||
</div>
|
||||
<img :src="item.img" alt="" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
<!-- 装修标题 -->
|
||||
<Modal
|
||||
v-model="showModal1"
|
||||
title="装修"
|
||||
draggable
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
|
||||
|
||||
>
|
||||
<div class="modal-top-advert">
|
||||
<div>
|
||||
<span>主标题:</span><Input v-model="selected.title" />
|
||||
</div>
|
||||
<div>
|
||||
<span>副标题:</span><Input v-model="selected.secondTitle" />
|
||||
</div>
|
||||
<div>
|
||||
<span>副标题链接:{{selected.url}}</span><Button size="small" class="ml_10" type="primary" @click="handleSelectLink">选择链接</Button>
|
||||
</div>
|
||||
<div>
|
||||
<span>背景色:</span><ColorPicker v-if="selected.bgColor" v-model="selected.bgColor" />
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="middle">
|
||||
<div
|
||||
class="top-header setup-content"
|
||||
:style="{ background: options.middle.bgColor }"
|
||||
>
|
||||
<span>{{ options.middle.title }}</span>
|
||||
<span>{{ options.middle.secondTitle }} ></span>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button
|
||||
size="small"
|
||||
@click.stop="handleSelectModel(options.middle, true)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div
|
||||
class="con-item setup-content"
|
||||
v-for="(item, index) in options.middle.list"
|
||||
:key="index"
|
||||
>
|
||||
<div>
|
||||
<p>{{ item.name }}</p>
|
||||
<p class="describe">{{ item.describe }}</p>
|
||||
</div>
|
||||
<img :src="item.img" alt="" />
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button size="small" @click.stop="handleSelectModel(item)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<div
|
||||
class="top-header setup-content"
|
||||
:style="{ background: options.right.bgColor }"
|
||||
>
|
||||
<span>{{ options.right.title }}</span>
|
||||
<span>{{ options.right.secondTitle }} ></span>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button
|
||||
size="small"
|
||||
@click.stop="handleSelectModel(options.right, true)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div
|
||||
class="setup-content"
|
||||
v-for="(item, index) in options.right.list"
|
||||
:key="index"
|
||||
>
|
||||
<img :src="item.img" alt="" />
|
||||
<p>{{ item.name }}</p>
|
||||
<p>{{ $filters.unitPrice(item.price, "¥") }}</p>
|
||||
<div class="jiaobiao" :class="'jiaobiao' + (index + 1)">
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button size="small" @click.stop="handleSelectGoods(item)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 装修内容 -->
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
|
||||
width="800"
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-top-advert">
|
||||
<div>
|
||||
<img
|
||||
class="show-image"
|
||||
width="160"
|
||||
height="160"
|
||||
v-if="selected.size && selected.size.indexOf('160*160') >= 0"
|
||||
:src="selected.img"
|
||||
alt
|
||||
/>
|
||||
<img
|
||||
class="show-image"
|
||||
width="80"
|
||||
height="80"
|
||||
v-if="selected.size && selected.size.indexOf('90*90') >= 0"
|
||||
:src="selected.img"
|
||||
alt
|
||||
/>
|
||||
</div>
|
||||
<div><span>图片主标题:</span><el-input v-model="selected.name" /></div>
|
||||
<div><span>图片描述:</span><el-input v-model="selected.describe" /></div>
|
||||
<div class="tips">
|
||||
建议尺寸:<span>{{ selected.size }}</span>
|
||||
</div>
|
||||
<div>
|
||||
图片链接:<el-input
|
||||
class="outsideUrl"
|
||||
v-model="selected.url"
|
||||
:disabled="!!selected.type && selected.type !== 'link'"
|
||||
placeholder="https://"
|
||||
/>
|
||||
<el-button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</el-button
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<el-button size="small" type="primary" @click="handleSelectImg"
|
||||
>选择图片</el-button
|
||||
>
|
||||
|
||||
<el-button size="small" type="primary" @click="handleSelectGoods('')"
|
||||
>选择商品</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 装修标题 -->
|
||||
<el-dialog
|
||||
v-model="showModal1"
|
||||
title="装修"
|
||||
|
||||
width="800"
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-top-advert">
|
||||
<div><span>主标题:</span><el-input v-model="selected.title" /></div>
|
||||
<div><span>副标题:</span><el-input v-model="selected.secondTitle" /></div>
|
||||
<div>
|
||||
<span
|
||||
>副标题链接:<el-input
|
||||
class="outsideUrl"
|
||||
v-model="selected.url"
|
||||
:disabled="!!selected.type && selected.type !== 'link'"
|
||||
placeholder="https://" /></span
|
||||
><el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectLink"
|
||||
>选择链接</el-button
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<span>背景色:</span
|
||||
><el-color-picker v-if="selected.bgColor" v-model="selected.bgColor" />
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import ossManage from "@/views/shop/ossManages";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
export default {
|
||||
props:{
|
||||
data:{
|
||||
type:Object,
|
||||
default:null
|
||||
}
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
components:{
|
||||
ossManage
|
||||
},
|
||||
components: {
|
||||
ossManage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: this.data.options, // 当前数据
|
||||
showModal: false, // modal显隐
|
||||
showModal1: false, // modal显隐
|
||||
selected: {}, // 已选数据
|
||||
picModelFlag: false, // 选择图片modal
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 装修modal
|
||||
handleSelectModel(item, type) {
|
||||
this.selected = item;
|
||||
console.warn(item);
|
||||
if (type) {
|
||||
this.showModal1 = true;
|
||||
} else {
|
||||
this.showModal = true;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options:this.data.options, // 当前数据
|
||||
showModal:false, // modal显隐
|
||||
showModal1:false, // modal显隐
|
||||
selected: {}, // 已选数据
|
||||
picModelFlag: false // 选择图片modal
|
||||
}
|
||||
handleSelectLink() {
|
||||
// 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open("link");
|
||||
},
|
||||
methods:{
|
||||
// 装修modal
|
||||
handleSelectModel (item, type) {
|
||||
this.selected = item;
|
||||
console.warn(item);
|
||||
if(type){
|
||||
this.showModal1 = true
|
||||
} else {
|
||||
this.showModal = true
|
||||
}
|
||||
|
||||
},
|
||||
handleSelectLink() { // 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open('link')
|
||||
},
|
||||
handleSelectGoods(item) { // 调起选择商品
|
||||
console.warn(item);
|
||||
if (item) this.selected = item;
|
||||
this.$refs.liliDialog.open('goods', 'single')
|
||||
setTimeout(() => {
|
||||
this.$refs.liliDialog.goodsData = [this.selected]
|
||||
}, 500);
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink (val) {
|
||||
this.selected.url = this.$options.filters.formatLinkType(val);
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData (val) {
|
||||
console.log(val);
|
||||
let goods = val[0]
|
||||
console.log(this.selected);
|
||||
this.selected.img = goods.thumbnail
|
||||
this.selected.price = goods.price
|
||||
this.selected.name = goods.goodsName
|
||||
this.selected.url = `/goodsDetail?skuId=${goods.id}&goodsId=${goods.goodsId}`
|
||||
},
|
||||
handleSelectImg(){ // 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
},
|
||||
// 选择图片回显
|
||||
callbackSelected (val) {
|
||||
this.picModelFlag = false;
|
||||
this.selected.img = val.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleSelectGoods(item) {
|
||||
// 调起选择商品
|
||||
console.warn(item);
|
||||
if (item) this.selected = item;
|
||||
this.$refs.liliDialog.open("goods", "single");
|
||||
setTimeout(() => {
|
||||
this.$refs.liliDialog.goodsData = [this.selected];
|
||||
}, 500);
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink(val) {
|
||||
this.selected.url = this.$filters.formatLinkType(val);
|
||||
this.selected.type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData(val) {
|
||||
let goods = val[0];
|
||||
console.log(this.selected);
|
||||
this.selected.img = goods.thumbnail;
|
||||
this.selected.price = goods.price;
|
||||
this.selected.name = goods.goodsName;
|
||||
this.selected.url = `/goodsDetail?skuId=${goods.id}&goodsId=${goods.goodsId}`;
|
||||
},
|
||||
handleSelectImg() {
|
||||
// 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
},
|
||||
// 选择图片回显
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
this.selected.img = val.url;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import './setup-box.scss';
|
||||
.new-goods{
|
||||
@import "./setup-box.scss";
|
||||
.new-goods {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
> div {
|
||||
width: 393px;
|
||||
height: 440px;
|
||||
}
|
||||
|
||||
.left > .content {
|
||||
> div:nth-child(1) {
|
||||
height: 240px;
|
||||
flex-direction: column;
|
||||
border: 1px solid #eee;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
justify-content: space-between;
|
||||
img {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
.describe {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
> div:nth-child(2) {
|
||||
border-right: 1px solid #eee;
|
||||
}
|
||||
> div:nth-child(3),
|
||||
> div:nth-child(4) {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
|
||||
.middle > .content {
|
||||
> div {
|
||||
border-style: solid;
|
||||
border-color: #eee;
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
> div:nth-child(1),
|
||||
> div:nth-child(2),
|
||||
> div:nth-child(3) {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
> div:nth-child(6),
|
||||
> div:nth-child(3) {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.right > .content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
>div{
|
||||
width: 393px;
|
||||
height: 440px;
|
||||
}
|
||||
|
||||
.left>.content{
|
||||
>div:nth-child(1){
|
||||
height: 240px;
|
||||
flex-direction: column;
|
||||
border: 1px solid #eee;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
justify-content: space-between;
|
||||
img{
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
.describe{margin-top: 10px;}
|
||||
}
|
||||
>div:nth-child(2){border-right: 1px solid #eee;}
|
||||
>div:nth-child(3),>div:nth-child(4){border-bottom: 1px solid #eee;}
|
||||
}
|
||||
|
||||
.middle>.content{
|
||||
>div{
|
||||
border-style:solid;
|
||||
border-color: #eee;
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
>div:nth-child(1),>div:nth-child(2),>div:nth-child(3){border-right-width: 1px;}
|
||||
>div:nth-child(6), >div:nth-child(3){border-bottom-width: 0;}
|
||||
}
|
||||
|
||||
.right>.content{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
font-size: 12px;
|
||||
>div{
|
||||
position: relative;
|
||||
width: 120px;
|
||||
padding: 5px 10px 0 10px;
|
||||
img{
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
border-bottom: 1px solid #eee;
|
||||
:nth-child(2){
|
||||
height: 38px;
|
||||
overflow: hidden;
|
||||
}
|
||||
:nth-child(3){
|
||||
color: $theme_color;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.jiaobiao{
|
||||
position: absolute;
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
top: 10px;
|
||||
right: 16px;
|
||||
background: url('../../../assets/festival_icon.png');
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
}
|
||||
.jiaobiao1,.jiaobiao4{
|
||||
background-position: -2px -30px;
|
||||
}
|
||||
.jiaobiao2,.jiaobiao5{
|
||||
background-position: -31px -30px;
|
||||
}
|
||||
.jiaobiao3,.jiaobiao6{
|
||||
background-position: -60px -30px;
|
||||
}
|
||||
}
|
||||
>div:nth-child(4),>div:nth-child(5),>div:nth-child(6){border: none;}
|
||||
}
|
||||
|
||||
.top-header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 50px;
|
||||
padding: 0 10px;
|
||||
background: #c43d7e;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
font-size: 12px;
|
||||
> div {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
padding: 5px 10px 0 10px;
|
||||
img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
border-bottom: 1px solid #eee;
|
||||
:nth-child(2) {
|
||||
height: 38px;
|
||||
overflow: hidden;
|
||||
}
|
||||
:nth-child(3) {
|
||||
color: $theme_color;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.jiaobiao {
|
||||
position: absolute;
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
top: 10px;
|
||||
right: 16px;
|
||||
background: url("../../../assets/festival_icon.png");
|
||||
color: #fff;
|
||||
span:nth-child(1){
|
||||
font-size: 20px;
|
||||
}
|
||||
span:nth-child(2){
|
||||
font-size: 12px;
|
||||
}
|
||||
text-align: center;
|
||||
}
|
||||
.jiaobiao1,
|
||||
.jiaobiao4 {
|
||||
background-position: -2px -30px;
|
||||
}
|
||||
.jiaobiao2,
|
||||
.jiaobiao5 {
|
||||
background-position: -31px -30px;
|
||||
}
|
||||
.jiaobiao3,
|
||||
.jiaobiao6 {
|
||||
background-position: -60px -30px;
|
||||
}
|
||||
}
|
||||
.content{
|
||||
padding: 10px 12px 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
height: 370px;
|
||||
> div:nth-child(4),
|
||||
> div:nth-child(5),
|
||||
> div:nth-child(6) {
|
||||
border: none;
|
||||
}
|
||||
.con-item{
|
||||
width: 185px;
|
||||
height: 120px;
|
||||
display: flex;
|
||||
padding-left: 10px;
|
||||
padding-top: 10px;
|
||||
img{
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.top-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 50px;
|
||||
padding: 0 10px;
|
||||
background: #c43d7e;
|
||||
color: #fff;
|
||||
span:nth-child(1) {
|
||||
font-size: 20px;
|
||||
}
|
||||
.describe{
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-top: 15px;
|
||||
span:nth-child(2) {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
padding: 10px 12px 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
height: 370px;
|
||||
}
|
||||
.con-item {
|
||||
width: 185px;
|
||||
height: 120px;
|
||||
display: flex;
|
||||
padding-left: 10px;
|
||||
padding-top: 10px;
|
||||
img {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
.describe {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
.modal-top-advert{
|
||||
align-items: start;
|
||||
padding: 0 30px;
|
||||
.modal-top-advert {
|
||||
align-items: start;
|
||||
padding: 0 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</li>
|
||||
<div class="setup-box" style="width:100px;left:1100px;">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
|
||||
<el-button size="small" @click.stop="handleSelectModel">编辑</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
@@ -16,26 +16,26 @@
|
||||
<img :src="item.img" width="210" height="210" :alt="item.name">
|
||||
<p>{{item.name}}</p>
|
||||
<p>
|
||||
<span>{{item.price | unitPrice('¥')}}</span>
|
||||
<!-- <span>{{item.price | unitPrice('¥')}}</span> -->
|
||||
<span>{{ $filters.unitPrice(item.price, '¥') }}</span>
|
||||
<!-- <span>{{ $filters.unitPrice(item.price, '¥') }}</span> -->
|
||||
</p>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<Button size="small" @click.stop="handleSelectGoods(item)">编辑</Button>
|
||||
<el-button size="small" @click.stop="handleSelectGoods(item)">编辑</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
draggable
|
||||
|
||||
width="800"
|
||||
:z-index="100"
|
||||
:mask-closable="false"
|
||||
>
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-tab-bar">
|
||||
<Button type="primary" size='small' @click="handleAddNav">添加分类</Button>
|
||||
<el-button type="primary" size='small' @click="handleAddNav">添加分类</el-button>
|
||||
<table cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -46,16 +46,16 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in conData.options.navList" :key="index">
|
||||
<td><Input v-model="item.title" /></td>
|
||||
<td><Input v-model="item.desc" /></td>
|
||||
<td><el-input v-model="item.title" /></td>
|
||||
<td><el-input v-model="item.desc" /></td>
|
||||
<td v-if="index!=0">
|
||||
<Button type="error" size="small" @click="handleDelNav(index)">删除</Button>
|
||||
<el-button type="danger" size="small" @click="handleDelNav(index)">删除</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@@ -100,10 +100,10 @@ export default {
|
||||
},
|
||||
handleSelectGoods(item) { // 调起选择商品弹窗
|
||||
if(item) this.selected = item;
|
||||
this.$refs.liliDialog.flag = true;
|
||||
this.$refs.liliDialog.goodsFlag = true;
|
||||
this.$refs.liliDialog.singleGoods();
|
||||
|
||||
this.$refs.liliDialog.open('goods', 'single')
|
||||
setTimeout(() => {
|
||||
this.$refs.liliDialog.goodsData = [this.selected]
|
||||
}, 500);
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData(val){
|
||||
@@ -175,16 +175,16 @@ export default {
|
||||
cursor: pointer;
|
||||
}
|
||||
border-right: 1px solid #eee;
|
||||
|
||||
|
||||
}
|
||||
li:last-of-type{
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
.curr{
|
||||
p:nth-child(1){
|
||||
background-color: $theme_color;
|
||||
|
||||
|
||||
color: #fff;
|
||||
}
|
||||
p:nth-child(2){
|
||||
@@ -223,4 +223,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
155
seller/src/views/shop/modelList/oneRowThreeColumns.vue
Normal file
155
seller/src/views/shop/modelList/oneRowThreeColumns.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div class="line flex flex-j-sb">
|
||||
<div class="column" v-for="(item,index) in data.options.list" :key="index">
|
||||
<div v-if="!item.img" class="placeholder">占位符</div>
|
||||
<img v-else :src="item.img" class="three-column-img">
|
||||
</div>
|
||||
<div class="setup-box">
|
||||
<div>
|
||||
<el-button
|
||||
size="small"
|
||||
@click.stop="handleSelectModel(data.options.list)"
|
||||
>编辑</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="装修"
|
||||
|
||||
width="800"
|
||||
|
||||
:close-on-click-modal="false"
|
||||
append-to-body destroy-on-close>
|
||||
<div class="modal-tab-bar">
|
||||
<div v-for="(item,index) in data.options.list" :key="index">
|
||||
<img :src="item.img" class="three-column-img">
|
||||
<div>推荐尺寸:{{item.size}}</div>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectImg(index)"
|
||||
>选择图片</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ml_10"
|
||||
type="primary"
|
||||
@click="handleSelectLink(index)"
|
||||
>选择链接</el-button
|
||||
>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog
|
||||
ref="liliDialog"
|
||||
@selectedLink="selectedLink"
|
||||
@selectedGoodsData="selectedGoodsData"
|
||||
></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<el-dialog v-model="picModelFlag" width="1200px" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
export default {
|
||||
name: "oneRowThreeColumns",
|
||||
components:{ossManage},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showModal:false,
|
||||
selected: {}, // 已选数据
|
||||
picModelFlag:false,
|
||||
current:0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 回显图片
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
this.selected[this.current].img = val.url;
|
||||
console.log(this.selected)
|
||||
},
|
||||
// 编辑模块
|
||||
handleSelectModel(item) {
|
||||
this.selected = item;
|
||||
this.showModal = true;
|
||||
|
||||
},
|
||||
// 选择商品回调
|
||||
selectedGoodsData(val) {
|
||||
console.log(val);
|
||||
let goods = val[0];
|
||||
this.selected.img = goods.thumbnail;
|
||||
this.selected.price = goods.price;
|
||||
this.selected.name = goods.goodsName;
|
||||
this.selected.url = `/goodsDetail?skuId=${goods.id}&goodsId=${goods.goodsId}`;
|
||||
},
|
||||
// 选择链接回调
|
||||
selectedLink(val) {
|
||||
this.selected.url = this.$filters.formatLinkType(val);
|
||||
this.selected.type =
|
||||
val.___type === "other" && val.url === "" ? "link" : "other";
|
||||
},
|
||||
handleSelectLink(index) {
|
||||
// 调起选择链接弹窗
|
||||
this.$refs.liliDialog.open("link");
|
||||
this.current = index;
|
||||
},
|
||||
handleSelectImg(index){
|
||||
// 选择图片
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModelFlag = true;
|
||||
this.current = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./setup-box.scss";
|
||||
.three-column-img{
|
||||
width:385px;
|
||||
height: 165px
|
||||
}
|
||||
.line:hover{
|
||||
>.setup-box{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.placeholder{
|
||||
background: #666;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.line{
|
||||
position: relative;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.column{
|
||||
width: 385px;
|
||||
height: 165px;
|
||||
|
||||
>img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user