manager 升级到vue3

This commit is contained in:
pikachu1995@126.com
2026-05-25 10:49:09 +08:00
parent e7350899bf
commit 615ee91511
239 changed files with 22907 additions and 30841 deletions

View File

@@ -1,181 +1,137 @@
<template>
<div>
<Card>
<Form :model="liveForm" ref="liveForm" :rules="liveRulesForm" :label-width="120">
<FormItem label="直播标题" prop="name">
<Input disabled v-model="liveForm.name" style="width:460px"></Input>
<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>
</FormItem>
<FormItem label="主播昵称" prop="anchorName">
<Input disabled v-model="liveForm.anchorName" style="width:360px"></Input>
</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>
</FormItem>
<FormItem label="直播时间" prop="startTime">
<DatePicker disabled format="yyyy-MM-dd HH:mm" type="datetimerange" v-model="times" @on-change="handleChangeTime" :options="optionsTime" placeholder="直播计划开始时间-直播计划结束时间" style="width: 300px">
</DatePicker>
</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>
</FormItem>
</el-form-item>
<FormItem label="主播微信号" prop="anchorWechat">
<Input disabled v-model="liveForm.anchorWechat" style="width:360px" placeholder="主播微信号"></Input>
<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>
</FormItem>
</el-form-item>
<!-- 分享卡片 -->
<FormItem label="分享卡片封面" prop="feedsImg">
<el-form-item label="分享卡片封面" prop="feedsImg">
<div class="upload-list" v-if="liveForm.feedsImg">
<template>
<img :src="liveForm.feedsImg">
<div class="upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(liveForm.feedsImg)"></Icon>
</div>
</template>
</div>
<Upload v-if="liveForm.feedsImg.length ==0" ref="upload" :show-upload-list="false" :on-success="handleFeedsImgSuccess" :default-file-list="defaultImgList" :format="['jpg','jpeg','png']"
:on-format-error="handleFormatError" :max-size="1024" :on-exceeded-size="handleMaxSize" type="drag" :action="action" :headers="accessToken" style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="ios-camera" size="20"></Icon>
<img :src="liveForm.feedsImg">
<div class="upload-list-cover" @click="handleView(liveForm.feedsImg)">
<span class="view-icon">查看</span>
</div>
</Upload>
</div>
<div class="tips">
直播间分享图,图片规则:建议像素800*640,大小不超过1M;
</div>
</FormItem>
<!-- 直播间背景墙 -->
<FormItem label="直播间背景墙" prop="coverImg">
</el-form-item>
<el-form-item label="直播间背景墙" prop="coverImg">
<div class="upload-list" v-if="liveForm.coverImg">
<template>
<img :src="liveForm.coverImg">
<div class="upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(liveForm.coverImg)"></Icon>
</div>
</template>
</div>
<Upload v-if="liveForm.coverImg.length ==0" ref="upload" :show-upload-list="false" :on-success="handleCoverImgSuccess" :default-file-list="defaultImgList" :format="['jpg','jpeg','png']"
:on-format-error="handleFormatError" :max-size="1024" :on-exceeded-size="handleMaxSize" type="drag" :action="action" :headers="accessToken" style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="ios-camera" size="20"></Icon>
<img :src="liveForm.coverImg">
<div class="upload-list-cover" @click="handleView(liveForm.coverImg)">
<span class="view-icon">查看</span>
</div>
</Upload>
</div>
<div class="tips"> 直播间背景图,图片规则:建议像素1080*1920,大小不超过1M</div>
</FormItem>
<!-- 直播间背景墙 -->
<FormItem label="直播间分享图" prop="shareImg">
</el-form-item>
<el-form-item label="直播间分享图" prop="shareImg">
<div class="upload-list" v-if="liveForm.shareImg">
<template>
<img :src="liveForm.shareImg">
<div class="upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(liveForm.shareImg)"></Icon>
</div>
</template>
</div>
<Upload v-if="liveForm.shareImg.length ==0" ref="upload" :show-upload-list="false" :on-success="handleShareImgSuccess" :default-file-list="defaultImgList" :format="['jpg','jpeg','png']"
:on-format-error="handleFormatError" :max-size="1024" :on-exceeded-size="handleMaxSize" type="drag" :action="action" :headers="accessToken" style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="ios-camera" size="20"></Icon>
<img :src="liveForm.shareImg">
<div class="upload-list-cover" @click="handleView(liveForm.shareImg)">
<span class="view-icon">查看</span>
</div>
</Upload>
</div>
<div class="tips"> 直播间分享图,图片规则:建议像素800*640,大小不超过1M</div>
</FormItem>
</el-form-item>
<FormItem label="商品" v-if="$route.query.id">
<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>
<div v-if="row.priceType == 2">{{row.price | unitPrice('¥')}}至{{row.price2 | unitPrice('¥')}}</div>
<div v-if="row.priceType == 3">{{row.price | unitPrice('¥')}}<span class="original-price">{{row.price2 | unitPrice('¥')}}</span></div>
</div>
</template>
<template slot-scope="{ row }" slot="quantity">
<div>{{row.quantity}}</div>
</template>
</Table>
<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>
</FormItem>
</el-form-item>
<FormItem>
<Button type="primary" @click="createLives()">保存</Button>
<el-form-item>
<el-button type="primary" @click="createLives()">保存</el-button>
</el-form-item>
</el-form>
</el-card>
</FormItem>
</Form>
</Card>
<!-- 浏览图片 -->
<Modal title="查看图片" v-model="imageVisible">
<el-dialog v-model="imageVisible" title="查看图片" width="600px">
<img :src="imageSrc" v-if="imageVisible" style="width: 100%">
</Modal>
</el-dialog>
</div>
</template>
<script>
import { getLiveInfo } from "@/api/promotion";
export default {
data() {
return {
imageVisible: false, //查看图片的dailog
imageSrc: "", //查看图片的路径
imageVisible: false,
imageSrc: "",
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: [], //直播商品集合
commodityList: "", //商品集合
times: [],
liveData: [],
commodityList: "",
};
},
mounted() {
/**
* 如果query.id有值说明是查看详情
* liveStatus 可以判断当前直播状态 从而区分数据 是否是未开始、已开启、已关闭、
*/
if (this.$route.query.id) {
// 获取直播间详情
this.getLiveDetail();
}
this.accessToken = {
@@ -184,48 +140,32 @@ export default {
},
methods: {
/**
* 上传图片查看图片
*/
handleView(src) {
this.imageVisible = true;
this.imageSrc = src;
},
// 上传文件超过大小限制
handleMaxSize(file) {
this.$Notice.warning({
title: "文件大小过大",
desc: "所选文件大小过大, 不得超过 1M.",
});
},
/**
* 获取直播间详情
*/
async getLiveDetail() {
let result = await getLiveInfo(this.$route.query.id);
// 将数据回调到liveform里面
if (result.success) {
let data = result.result;
for (let key in data) {
this.liveForm[key] = data[key];
}
// 将选择的商品回调给表格
this.liveData = data.commodityList;
this.commodityList = 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;
}
},
@@ -236,7 +176,7 @@ export default {
<style lang="scss" scoped>
.action {
display: flex;
::v-deep .ivu-btn {
:deep(.el-button) {
margin: 0 5px !important;
}
}
@@ -253,7 +193,6 @@ export default {
.flex-goods {
margin: 10px;
display: flex;
align-items: center;
> img {
margin-right: 10px;
@@ -297,7 +236,7 @@ export default {
.upload-list:hover .upload-list-cover {
display: block;
}
.upload-list-cover i {
.view-icon {
color: #fff;
font-size: 20px;
cursor: pointer;

View File

@@ -1,181 +1,93 @@
<template>
<div>
<Card>
<Tabs v-model="searchForm.status">
<!-- 标签栏 -->
<TabPane
<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"
>
</TabPane>
</Tabs>
<Table :columns="liveColumns" :data="liveData"></Table>
<Row type="flex" style="margin: 20px" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
/>
</el-tabs>
<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>
<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"
:page-size="searchForm.pageSize"
@on-change="changePageNumber"
@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="changePageNumber"
@size-change="changePageSize"
/>
</div>
</el-card>
</div>
</template>
<script>
import { getLiveList, whetherStar } 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: "是否推荐",
align: "center",
render: (h, params) => {
return h("div", [
h(
"i-switch",
{
// 数据库0 enabled,1 disabled
props: {
type: "primary",
size: "large",
value: params.row.recommend == true,
},
on: {
"on-change": () => {
this.star(params.row, params.index);
},
},
},
[
h("span", {
slot: "open",
domProps: {
innerHTML: "是",
},
}),
h("span", {
slot: "close",
domProps: {
innerHTML: "否",
},
}),
]
),
]);
},
},
{
title: "直播状态",
render: (h, params) => {
if (params.row.status == "NEW") {
return h("div", [h("tag", { props: { color: "blue" } }, "未开始")]);
} else if (params.row.status == "START") {
return h("div", [h("tag", { props: { color: "green" } }, "直播中")]);
} else {
return h("div", [h("tag", { props: { color: "volcano" } }, "已结束")]);
}
},
},
{
title: "操作",
key: "action",
render: (h, params) => {
return h(
"div",
{
style: {
display: "flex",
},
},
[
h(
"Button",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.getLiveDetail(params.row);
},
},
},
"查看"
),
]
);
},
},
], //table中显示的title
liveData: [], //table中显示的直播数据
liveData: [],
};
},
watch: {
// 直播状态
"searchForm.status": {
handler() {
this.liveData = [];
@@ -188,42 +100,17 @@ export default {
this.getStoreLives();
},
methods: {
/**
* 是否推荐
*/
async star(val, index) {
let switched;
if (this.liveData[index].recommend) {
this.$set(this.liveData[index], "recommend", false);
switched = false;
} else {
this.$set(this.liveData[index], "recommend", true);
switched = true;
}
let switched = this.liveData[index].recommend;
await whetherStar({ id: val.id, recommend: switched });
this.getStoreLives();
},
/**
* 页面数据大小分页回调
*/
changePageSize(val) {
this.searchForm.pageSize = val;
changePageSize() {
this.getStoreLives();
},
/**
* 分页回调
*/
changePageNumber(val) {
this.searchForm.pageNumber = val;
changePageNumber() {
this.getStoreLives();
},
/**
* 获取店铺直播间列表
*/
async getStoreLives() {
let result = await getLiveList(this.searchForm);
if (result.success) {
@@ -231,10 +118,6 @@ export default {
this.total = result.result.total;
}
},
/**
* 获取直播间详情
*/
getLiveDetail(val) {
this.$router.push({
path: "/live-detail",