This commit is contained in:
2024-09-10 10:49:08 +08:00
parent b5fd06b800
commit dd4f5938da
6391 changed files with 722800 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
<template>
<!-- 数据循环 timeId 时间戳加随机数唯一值 -->
<block v-for="(v, i) in adList" :key="v.timeId">
<view class="ad-item">
<view class="ad-img-wrapper">
<view class="title">广告图片</view>
<view style="flex:1">
<JeepayUploadImg v-model:src="v.imgUrl" bizType="notice" />
</view>
</view>
<view class="ad-sort" :class="{ 'border-none': adList.length - 1 == i }">
<view class="title">广告排序</view>
<input type="number" v-model="v.sort" placeholder="请输入广告排序"
placeholder-style="color: #b3b3b3ff; font-size: 32rpx;" maxlength="5" />
<view class="del-but" hover-class="jeepay-hover-button" @tap="delAdData(v.timeId)">删除该条</view>
</view>
</view>
</block>
<!-- 添加数据 -->
<view class="add-img-but" hover-class="jeepay-hover-button" @tap="addAdData">
<image class="add-icon-img" src="/pageDevice/static/icon/ad-add.svg"></image>
添加广告图片 </view>
</template>
<script setup>
import infoBox from '@/commons/utils/infoBox.js'
const props = defineProps({
adList: { type: Array, default: () => ([]) }
});
// 添加数据方法
const addAdData = () => {
props.adList.push({ timeId: new Date().getTime() + Math.random() })
}
// 删除数据方法
const delAdData = (key) => {
if(props.adList.length<=1) return infoBox.showToast('最后一条数据不可删除。')
const index = props.adList.findIndex(v => v.timeId == key)
props.adList.splice(index, 1)
}
</script>
<style lang="scss" scoped>
.title {
margin-right: 70rpx;
color: #4d4d4dff;
font-size: 32rpx;
font-weight: 400;
white-space: nowrap;
}
.ad-item {
padding: 40rpx 0 0 40rpx;
}
.ad-img-wrapper {
display: flex;
align-items: center;
}
.ad-sort {
display: flex;
align-items: center;
margin-top: 40rpx;
height: 120rpx;
border-bottom: 1rpx solid #edededff;
}
.del-but {
display: flex;
justify-content: center;
align-items: center;
margin-right: 40rpx;
width: 148rpx;
height: 70rpx;
color: #ff0000ff;
font-size: 27rpx;
border-radius: 10rpx;
background: #ff00000f;
}
.add-img-but {
margin: 40rpx;
margin-top: 20rpx;
display: flex;
justify-content: center;
align-items: center;
height: 110rpx;
color: #2d2d2dff;
font-size: 32rpx;
border: 2rpx dashed #0000001a;
background: #00000005;
border-radius: 10rpx;
}
.border-none {
border: none !important;
}
.jeepay-hover-button{
opacity: 0.5;
background-color: rgba($color: #000000, $alpha: 0.09);
}
.add-icon-img{
margin-right: 20rpx;
width: 25rpx;
}
</style>

View File

@@ -0,0 +1,144 @@
<template>
<view class="page-wrapper">
<JeepayCustomNavbar textColor="#000" bgDefaultColor="#fff" :title="vdata.advertId ? '广告编辑' : '广告创建'"
backCtrl="back" />
<view class="ad-title-wrapper">
<view class="ad-title">广告标题</view>
<input type="text" v-model="vdata.title" placeholder="请输入广告标题"
placeholder-style="color: #b3b3b3ff; font-size: 32rpx;font-weight: 400;" maxlength="12">
</view>
<JSwitchCard borderWidth="0" title="是否发布" :tipsWidth='410' tips="发布后,刷脸设备上仅展示当前广告中包含的图片" v-if='!vdata.advertId'>
<template #right>
<JeepayStateSwitch v-model:state="vdata.releaseState" :showSwitchType="true" :confirm="false" />
</template>
</JSwitchCard>
<view class="ad-content">
<AdItems :adList="vdata.adList" />
</view>
<!-- 保存编辑 -->
<view class="footer-wrapper">
<view class="footer-button footer-button-style">
<button hover-class="hover-button" hover-stay-time="150" class="flex-center" @tap="addOrEdit">{{ vdata.advertId ?
'保存编辑' : '确认创建' }}</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive } from "vue"
import { onLoad } from '@dcloudio/uni-app'
import infoBox from '@/commons/utils/infoBox.js'
import { reqLoad, API_URI_PAY_AD_LIST } from "@/http/apiManager.js"
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import AdItems from "./components/AdItems.vue"
onLoad((options) => {
if (options.id) {
vdata.advertId = options.id
getDetails()
}
})
const vdata = reactive({
advertType: 1,
releaseState: 1,
adList: [{ timeId: new Date().getTime() + Math.random() }]
})
const addOrEdit = () => {
// 上传前格式化数据
if(!vdata.title) return infoBox.showToast('请填写广告标题')
if (formatAdData()) return
vdata.appContent = JSON.stringify(vdata.adList)
reqLoad.addOrUpdate(vdata.advertId ? vdata.advertId : false, API_URI_PAY_AD_LIST, vdata).then(res => {
go.back(1, emit.ENAME_REF_AD_DETAILS)
emit.refPageAndSearchEmit(emit.ENAME_REF_AD_LIST)
})
}
const getDetails = () => {
reqLoad.getById(API_URI_PAY_AD_LIST, vdata.advertId).then(({ bizData }) => {
bizData.adList = JSON.parse(bizData.appContent)
bizData.adList.forEach(v => {
v.timeId = new Date().getTime() + Math.random()
})
Object.assign(vdata, bizData)
})
}
const formatAdData = () => {
if (vdata.adList.findIndex(v => v.imgUrl) == '-1') return infoBox.showToast('空数据不可保存')
vdata.adList = vdata.adList.filter(v=>v.imgUrl) // 筛选有值字段
vdata.adList.forEach((v, i) => {
delete v.timeId //删除唯一值 后端不许要存储
if(!v.sort){
v.sort = i+1 //如果没有填写 排序字段 将 下标赋值给 排序字段
}
})
return false
}
</script>
<style lang="scss" scoped>
.title {
color: #4d4d4dff;
font-size: 32rpx;
font-weight: 400;
}
.ad-content {
margin-top: 20rpx;
padding: 0.1rpx;
background-color: #fff;
}
.ad-title-wrapper {
display: flex;
align-items: center;
padding: 0 40rpx;
height: 120rpx;
background-color: #fff;
input {
margin-left: 70rpx;
}
margin-bottom: 20rpx;
}
.footer-wrapper {
height: 170rpx;
background-color: transparent;
.footer-button {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
padding: 30rpx;
&::after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
height: 1rpx;
background-color: #edededff;
}
button {
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
.hover-button {
opacity: 0.5;
}
}
}
</style>

View File

@@ -0,0 +1,123 @@
<template>
<view class="page-wrapper">
<view class="search-header">
<view class="search-mian">
<image src="/static/iconImg/icon-search.svg" mode=""></image> <input type="text" disabled placeholder="搜索广告标题"
placeholder-style="color: #00000059;font-size: 27rpx;font-weight: 400;" @tap="toSearch">
</view>
</view>
<JeepayTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFunc">
<template #tableBody="{ record }">
<FaceCardRender :title="record.title" :advertId="record.advertId" :imgUrl="record.imgUrl"
:releaseState="record.releaseState" />
</template>
</JeepayTableList>
<view class="footer-wrapper">
<view class="footer-button footer-button-style">
<button hover-class="hover-button" hover-stay-time="150" class="flex-center" @tap="createdAd">创建广告</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from "vue"
import { reqLoad, API_URI_PAY_AD_LIST } from "@/http/apiManager"
import { onLoad, onUnload } from '@dcloudio/uni-app'
import FaceCardRender from "/pages/list/render/FaceCardRender.vue"
import emit from '@/commons/utils/emit.js'
import go from '@/commons/utils/go.js'
uni.$on(emit.ENAME_REF_AD_LIST, (data) => {
jeepayTableListRef.value.refTable(true)
})
onUnload(() => {
uni.$off(emit.ENAME_REF_AD_LIST)
})
const jeepayTableListRef = ref(null)
const reqTableDataFunc = (params) => {
params.advertType = 1
return reqLoad.list(API_URI_PAY_AD_LIST, params)
}
const createdAd = () => {
go.to('PAGES_AD_EDIT')
}
const toSearch = () => {
go.toSearchPage('faceImgAd', 'faceImgAd')
}
</script>
<style lang="scss" scoped>
.page-wrapper {
min-height: calc(100vh - 160rpx);
}
.search-header {
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
padding: 20rpx 30rpx;
height: 110rpx;
background-color: #fff;
image {
padding: 20rpx;
width: 25rpx;
height: 25rpx;
}
.search-mian {
flex: 1;
display: flex;
height: 100%;
border-radius: 12rpx;
opacity: 1;
background: #f5f5f5ff;
input {
height: 100%;
}
}
}
.footer-wrapper {
height: 170rpx;
background-color: transparent;
.footer-button {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 30rpx;
&::after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
height: 1rpx;
background-color: #edededff;
}
button {
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
.hover-button {
opacity: 0.5;
}
}
}
.block {
height: 150rpx;
}
</style>

View File

@@ -0,0 +1,125 @@
<template>
<JeepayBackground :bgColorStyle="{ height: '706rpx' }">
<JeepayCustomNavbar textColor="#fff"
bgDefaultColor="linear-gradient(270deg, rgba(72, 192, 255, 1) 0%, rgba(51, 157, 255, 1) 100%)" title="广告详情"
backCtrl="back" />
<JeepayTableListItem viewClass="list-item-by-detail" logo="/pageDevice/static/icon/ad-white.svg"
:title="vdata.title" :subtitle="vdata.advertId" :moreBtnList="list" />
<view class="create-time">
<view class="time-title">创建时间</view>
<view class="time-info">{{ vdata.createdAt }}</view>
</view>
<JeepayCard editText="编辑广告" @editTap="toEditAd">
<JeepayDescview>
<block v-for="(v, i) in vdata.appContent">
<JeepayDescviewItem :title="`广告图片(${i + 1}`">
<template #desc>
<image class="ad-img" :src="v.imgUrl" mode="aspectFill">
</image>
</template>
</JeepayDescviewItem>
</block>
</JeepayDescview>
</JeepayCard>
<JeepayCard title='其他设置' viewStyle="margin-top:30rpx">
<JSwitchCard title="是否发布" :tipsWidth='410' tips="发布后,刷脸设备上仅展示当前广告中包含的图片">
<template #right>
<JeepayStateSwitch v-model:state="vdata.releaseState" :showSwitchType="true"
:updateStateFunc="updateStateFunc" />
</template>
</JSwitchCard>
</JeepayCard>
<JeepayPopupConfirm ref="refTips" />
<JSinglePopup ref="refMore" :list="list" activeColor="#FF5B4C" />
</JeepayBackground>
</template>
<script setup>
import { reqLoad, API_URI_PAY_AD_LIST } from "@/http/apiManager.js"
import http from "@/http/http"
import emit from '@/commons/utils/emit.js'
import infoBox from '@/commons/utils/infoBox.js'
import { reactive, ref } from "vue"
import go from '@/commons/utils/go.js'
import { onLoad,onUnload } from '@dcloudio/uni-app'
onLoad((options) => {
vdata.advertId = options.id
getDetails()
})
uni.$on(emit.ENAME_REF_AD_DETAILS, (data) => {
getDetails()
})
const list = reactive([{
label: '编辑广告',
value: 'editAd',
fun: toEditAd,
},
{
label: '删除广告',
value: 'deleteAd',
color: '#FF5B4C',
fun: function () {
refTips.value.open('是否确认删除该条广告?').then(() => {
http.req(API_URI_PAY_AD_LIST, { delAdvertIds: vdata.advertId }, "DELETE").then(res => {
infoBox.showSuccessToast('删除成功').then(res => {
go.back(1,emit.ENAME_REF_AD_LIST)
})
})
}).catch(() => {
refMore.value.open()
})
}
},
])
const refTips = ref(null)
const refMore = ref(null)
const vdata = reactive({})
function toEditAd () {
go.to('PAGES_AD_EDIT', { id: vdata.advertId })
}
// 获取详情
const getDetails = () => {
reqLoad.getById(API_URI_PAY_AD_LIST, vdata.advertId).then(({ bizData }) => {
bizData.appContent = JSON.parse(bizData.appContent)
Object.assign(vdata, bizData)
})
}
// 修改发布状态
const updateStateFunc = (state) => {
reqLoad.addOrUpdate(vdata.advertId, API_URI_PAY_AD_LIST, { releaseState: state }).then(res=>{
emit.refPageAndSearchEmit( emit.ENAME_REF_AD_LIST)
})
}
onUnload(() => uni.$off(emit.ENAME_REF_AD_DETAILS))
</script>
<style lang="scss" scoped>
.create-time {
display: flex;
justify-content: space-between;
margin: 0 75rpx;
padding: 50rpx 0;
font-size: 30rpx;
border-top: 1rpx solid rgba(255, 255, 255, 0.2);
.time-title {
color: rgba(255, 255, 255, 0.7);
}
.time-info {
color: #fff;
}
}
.ad-img {
width: 150rpx;
height: 150rpx;
border-radius: 20rpx;
}
.c-desc-view-item ::v-deep .title {
justify-content: flex-start !important;
}
</style>