稳定版

zsk_admin
zsk 6 months ago
parent a2d3f4267b
commit 10115a8bd4

@ -1,50 +0,0 @@
import request from "../utils/request";
// 获取中奖列表
export function getCarouselListApi(page, limit = 10) {
return request({
url: `/admin/banner/${page}/${limit}`,
method: "get",
});
}
// 保存中奖
export function saveCarouselApi(data) {
return request({
url: `/admin/banner/save`,
method: "post",
data: { img: data.img,title: data.title,status: data.status }
});
}
// 删除中奖
export function deleteCarouselApi(id) {
return request({
url: `/admin/banner/remove/${id}`,
method: "delete",
});
}
// 修改中奖
export function updateCarouselApi(data) {
return request({
url: `/admin/banner/update`,
method: "put",
data
});
}
// 上传图片
export function uploadImageApi(file) {
const formData = new FormData();
formData.append('file', file);
return request({
url: '/admin/cms/upload',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
});
}

@ -0,0 +1,75 @@
import request from "../utils/request";
import qs from "qs";
let setqs = function (data) {
return qs.stringify(data);
};
// 获取平台消息列表
export function getCmsListNew (data) {
return request({
url: "/admin/v4/bocai/cms/list",
method: "post",
data: setqs(data),
});
}
// 删除
export function delCms (id) {
return request({
url: "/yicai/bocai/cms/del/" + id,
method: "get",
});
}
// 详情
export function getCmsDetail (id) {
return request({
url: "/yicai/bocai/cms/details/" + id,
method: "get",
});
}
/*
获取金刚区列表
*/
export function getPositionList (data) {
return request({
url: "/admin/v4/diamond/position/getPage",
method: "post",
data: setqs(data),
});
}
// 新增
export function addPositionApi (data) {
return request({
url: "/admin/v4/diamond/position/addOrUpdate",
method: "post",
data: setqs(data),
});
}
// 删除
export function delPositionApi (data) {
return request({
url: "/admin/v4/diamond/position/delete",
method: "post",
data: setqs(data),
});
}
// 状态更新
export function updatePositionApi (data) {
return request({
url: "/admin/v4/diamond/position/updateStatus",
method: "post",
data: setqs(data),
});
}
// 获取职位列表
export function getList (data) {
return request({
url: "/admin/v4/custom/job/list",
method: "post",
data: setqs(data),
});
}

@ -1,59 +0,0 @@
import request from "../utils/request";
// 获取内容列表
export function getContentListApi(page, limit = 10,classify) {
return request({
url: `/admin/cms/${page}/${limit}?classify=${classify}`,
method: "get",
});
}
// 新增内容
export function saveContentApi(data) {
return request({
url: `/admin/cms/save`,
method: "post",
data
});
}
// 新增内容
export function getHzd(data) {
return request({
url: `/admin/cms/get/61`,
method: "get",
data
});
}
// 更新内容
export function updateContentApi(data) {
return request({
url: `/admin/cms/update`,
method: "put",
data
});
}
// 删除内容
export function deleteContentApi(id) {
return request({
url: `/admin/cms/remove/${id}`,
method: "delete",
});
}
// 上传图片
export function uploadImageApi(file) {
const formData = new FormData();
formData.append('file', file);
return request({
url: '/admin/cms/upload',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
});
}

@ -1,52 +0,0 @@
import request from "../utils/request";
// 获取彩票列表
export function getLotteryListApi(page, limit, classify) {
return request({
url: `/admin/lottery/${page}/${limit}?classify=${classify}`,
method: "get",
})
}
// 获取今日开奖通告
export function getTodayLotteryApi() {
return request({
url: `/admin/lottery/last`,
method: "get",
})
}
// 获取彩票详情
export function getLotteryDetailApi(id) {
return request({
url: `/admin/lottery/get/${id}`,
method: "get",
})
}
// 删除彩票记录
export function deleteLotteryApi(id) {
return request({
url: `/admin/lottery/remove/${id}`,
method: "delete",
})
}
// 保存彩票记录
export function saveLotteryApi(data) {
return request({
url: `/admin/lottery/save`,
method: "post",
data,
})
}
// 更新彩票记录
export function updateLotteryApi(data) {
return request({
url: `/admin/lottery/update`,
method: "put",
data,
})
}

@ -1,81 +0,0 @@
import request from "../../utils/request";
import qs from "qs";
let setqs = function (data) {
return qs.stringify(data);
};
// 保存内容
export function saveMessageApi (data) {
console.log(data);
return request({
url: `/admin/cms/save`,
method: "POST",
data,
});
}
// 修改内容
export function updateMessageApi (data) {
return request({
url: `/admin/cms/update`,
method: "PUT",
data,
});
}
// 获取内容列表
export function getMessageListApi (data) {
return request({
url: `/admin/cms/${data.page}/${data.limit}`,
method: "get",
params: {
status: data.status,
keyword: data.keyword
}
// data,
});
}
// 获取内容
export function getMessageDetailApi (id) {
return request({
url: `/admin/cms/get/${id}`,
method: "get",
// data,
});
}
// 导入股权结构文件
export function importStockModelApi (data) {
return request({
url: `/admin/stock/structure/import`,
method: "post",
headers: {
"Content-Type": 'multipart/form-data',
},
data: setqs(data)
});
}
// 获取股权结构列表
export function getStockInfoListApi (data) {
return request({
url: `/admin/stock/structure/list`,
method: "get",
});
}
// 获取股权结构列表
export function getStockMoreListApi (data) {
return request({
url: `/admin/stock/change/list`,
method: "get",
});
}
// 删除用户
export function delMessageApi (data) {
return request({
url: `/admin/cms/remove/${data}`,
method: "DELETE",
});
}

@ -1,52 +0,0 @@
import request from "../utils/request"
// 获取笔记列表
export function getScheduleListApi(page, limit, classify) {
return request({
url: `/admin/schedule/${page}/${limit}?classify=${classify}`,
method: "get",
})
}
// 获取今日笔记
export function getTodayScheduleApi() {
return request({
url: `/admin/schedule/last`,
method: "get",
})
}
// 获取笔记详情
export function getScheduleDetailApi(id) {
return request({
url: `/admin/schedule/get/${id}`,
method: "get",
})
}
// 删除笔记
export function deleteScheduleApi(id) {
return request({
url: `/admin/schedule/remove/${id}`,
method: "delete",
})
}
// 保存笔记
export function saveScheduleApi(data) {
return request({
url: `/admin/schedule/save`,
method: "post",
data,
})
}
// 更新笔记
export function updateScheduleApi(data) {
return request({
url: `/admin/schedule/update`,
method: "put",
data,
})
}

@ -1,60 +0,0 @@
import request from "../../utils/request";
import qs from "qs";
let setqs = function (data) {
return qs.stringify(data);
};
// 获取企业信息
export function getProjectInfoApi (data) {
console.log(data);
return request({
url: `/admin/company/info`,
method: "get",
});
}
// 更新企业信息
export function updateProjectInfoApi (data) {
return request({
url: `/admin/company/update`,
method: "PUT",
data,
});
}
// 导入股权结构文件
export function importStockModelApi (data) {
return request({
url: `/admin/stock/structure/import`,
method: "post",
headers: {
"Content-Type": 'multipart/form-data',
},
data: setqs(data)
});
}
// 获取股权结构列表
export function getStockInfoListApi (data) {
return request({
url: `/admin/stock/structure/list`,
method: "get",
});
}
// 获取股权结构列表
export function getStockMoreListApi (data) {
return request({
url: `/admin/stock/change/list`,
method: "get",
});
}
// 删除用户
export function delUserApi (data) {
return request({
url: `/admin/user/remove/${data}`,
method: "DELETE",
});
}

@ -1,79 +0,0 @@
import request from "../../utils/request";
import qs from "qs";
let setqs = function (data) {
return qs.stringify(data);
};
// 获取用户列表
export function getUserListApi (data) {
console.log(data);
return request({
url: `/admin/user/${data.page}/${data.limit}?keyword=${data.keyword}`,
method: "get",
});
}
// 获取用户列表
export function getStockUserListApi (data) {
console.log(data);
return request({
url: `/admin/user/stock/${data.page}/${data.limit}?keyword=${data.keyword}`,
method: "get",
});
}
// 用户状态变更
export function updateUserStatusApi (data) {
return request({
url: `/admin/user/updateStatus/${data.id}/${data.status}`,
method: "get",
});
}
// 新增用户
export function addUserApi (data) {
return request({
url: `/admin/user/save`,
method: "post",
data
});
}
// 新增个人数据
export function addStockUserApi (data) {
return request({
url: `/admin/user/stock/save`,
method: "post",
data
});
}
// 更新用户
export function updateUserApi (data) {
return request({
url: `/admin/user/update`,
method: "put",
data
});
}
// 更新用户数据
export function updateUserStockApi (data) {
return request({
url: `/admin/user/stock/update`,
method: "put",
data
});
}
// 删除用户
export function delUserApi (data) {
return request({
url: `/admin/user/remove/${data}`,
method: "DELETE",
});
}
// 获取股权结构列表
export function getUserMoreListApi (data) {
return request({
url: `/admin/user/stock/record/${data.userId}/${data.page}/${data.limit}`,
method: "get",
});
}

@ -1,272 +0,0 @@
<template>
<!-- 稍后处理时间组件 -->
<div class="g-components-interval g_flex_column_between">
<div v-if="speed > 0" class="interval-box">
<!-- 存放时间 -->
<div class="time-box g_flex_row_between g_flex_none">
<div class="g_flex_1 g_flex_row_start key">
<div class="g_flex_none g_flex_row_start">
<div class="g_flex_column_center icon-box">
<ClockCircleOutlined style="color: #929292;" />
</div>
<div class="g_flex_column_center text">稍后处理</div>
</div>
<div class="g_flex_none g_flex_row_start item-box">
<div class="small-box g_flex_row_start">
<div class="item g_fs_12" v-for="(item,index) in time" :key="index" @click="handleUpdateTime(item,index)" :class="active == index ? 'item-active' : ''">{{item.text}}</div>
</div>
<div class="g_flex_column_center" style="margin-left: 3px;">
<a-date-picker v-model:value="timer" :show-time="{ format: 'HH:mm' }" format="YYYY-MM-DD HH:mm" size="small" class="g_w_150" @change="handlePointTimer" />
</div>
</div>
</div>
<div class="g_flex_none value g_flex_column_center" @click="handleSendEvent(30)">
<div class="icon-bos">
<ThunderboltOutlined class="g_w_12 g_h_18" />
</div>
</div>
</div>
<div class="g_flex_row_between g_flex_1">
<!-- 存放输入框和提示语 -->
<div class="input-box g_flex_1">
<div class="an-input g_flex_column_center g-ant-textarea">
<a-textarea v-model:value="send_text" placeholder="请输入跟进记录" :autoSize="{ minRows: 3, maxRows: 3 }" class="textare" style="border:0;" @change="handleChange" />
</div>
<div class="time-tip g_flex_column_center c045 f12 g_h_23">{{tip}}</div>
</div>
<!-- 存放提交按钮 -->
<div class="submit-box g_flex_none g_flex_column_center">
<div class="btn g_flex_c" @click="handleSubmitEvent"></div>
</div>
</div>
</div>
</div>
</template>
<script setup>
/*
* @function quickEvent 快捷发送事件
* @function submitEvent 提交按钮事件
*/
import { ref, onMounted, getCurrentInstance, h, watch, defineEmits } from 'vue'
import { ThunderboltOutlined, EditOutlined, EyeInvisibleOutlined, UserAddOutlined, TeamOutlined, PhoneOutlined, PlusCircleOutlined, MinusCircleOutlined, ClockCircleOutlined, PauseCircleOutlined, StopOutlined, InfoCircleOutlined, PoweroffOutlined } from '@ant-design/icons-vue'
import { Modal, message } from 'ant-design-vue'
import { useRouter, useRoute } from 'vue-router'
import { useStore } from '../../stores/counter.ts'
import dayjs from 'dayjs'
/* #################### 初始化事件 #################### */
const router = useRouter() //
const route = useRoute()
const emits = defineEmits(['quickEvent', 'submitEvent'])
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G
const storeJS = useStore()
const speed = ref(0)
watch(storeJS.deliveryUserid, (val) => {
if (val.content == -1) {
speed.value = 0
} else {
speed.value = 1
}
active.value = -1
send_text.value = ''
timer.value = ''
str.value = ''
tip.value = ''
})
const time = ref([
{
text: '30min',
num: '30',
remark: '30分钟',
},
{
text: '1h',
num: '60',
remark: '1小时',
},
{
text: '2h',
num: '120',
remark: '2小时',
},
{
text: '4h',
num: '240',
remark: '4小时',
},
{
text: '1d',
num: '1440',
remark: '1天',
},
{
text: '2d',
num: '2880',
remark: '2天',
},
{
text: '3d',
num: '4320',
remark: '3天',
},
])
const active = ref(-1)
const tip = ref('')
const handleUpdateTime = (item, index) => {
if (index < 7) {
tip.value = '提示:系统会在' + item.remark + '后提醒你'
active.value = index
timer.value = ''
str.value = ''
}
}
const send_text = ref('')
const timer = ref('')
const str = ref('')
const handlePointTimer = (value, dateString) => {
str.value = dateString
active.value = -1
tip.value = '提示:系统会在' + dateString + '提醒你'
}
//
const handleSendEvent = () => {
commonJS.gConfirmModal('快速稍后处理', '系统会在30分钟后提醒你', () => {
emits('quickEvent')
})
}
//
const handleSubmitEvent = () => {
let promise = new Promise((resolve, reject) => {
emits('submitEvent', {
type: str.value == '' ? 1 : 3,
num: active.value < 0 ? '' : time.value[active.value].num,
str: str.value,
remark: send_text.value,
})
resolve()
})
promise
.then(() => {
active.value = -1
send_text.value = ''
timer.value = ''
str.value = ''
tip.value = ''
})
.catch()
}
</script>
<style lang="less">
.g-components-interval {
.interval-box {
height: 132px;
box-shadow: 0px -4px 4px 0px rgba(228, 228, 228, 0.5);
}
.time-box {
border-bottom: 1px solid #eee;
height: 33px;
.key,
.value {
height: 100%;
}
.icon-box {
padding: 0 6px 0 6px;
}
.text {
color: #929292;
font-size: 14px;
}
.item-box {
.item {
border-radius: 3px;
background-color: rgba(250, 250, 250, 1);
border: 1px solid rgba(217, 217, 217, 1);
padding: 0px 9px;
height: 22px;
line-height: 18px;
margin-left: 5px;
margin-top: 4.5px;
cursor: pointer;
color: #656565;
&:hover {
color: #109eff;
}
&:first-child {
margin-left: 10px;
}
}
.item-active {
background-color: #109eff;
color: #fff;
border-color: #109eff;
&:hover {
color: #fff;
}
}
}
.value {
cursor: pointer;
.icon-bos {
padding: 0 10px;
border-left: 1px solid #d9d9d9;
}
}
}
.input-box {
padding-left: 0px;
.time-tip {
padding-left: 10px;
margin-top: 3px;
font-size: 14px;
color: #666;
}
}
.submit-box {
padding: 0 15px;
.btn {
width: 60px;
height: 28px;
border-radius: 3px;
background-color: rgba(24, 144, 255, 1);
color: #fff;
font-size: 14px;
cursor: pointer;
}
}
.ant-calendar-picker {
min-width: 48px !important;
width: 48px;
.custom_default {
min-width: 48px !important;
text-decoration: underline;
cursor: pointer;
}
}
}
@media screen and (max-width: 1680px) {
.g-components-interval {
.time-box {
.icon-box {
padding: 0 4px 0 4px;
}
.text {
font-size: 12px;
}
.item-box {
.item {
padding: 0px 2px;
line-height: 18px;
margin-left: 4px;
margin-top: 4.5px;
&:first-child {
margin-left: 5px;
}
}
}
}
}
}
</style>

@ -1,220 +0,0 @@
<template>
<div class="g-components-image-swiper-picture">
<div class="g_flex_row_start_none">
<div class="default-img g_position_rela" @click="handlePrevEvent" v-if="swiperItem.list.length > swiperItem.num && isShowPrev">
<img src="../../../assets/image/other/prev.png" class="g_w_28 g_h_28 g_cursor_point" style="position: absolute;left: -12px;top: 50%;transform: translateY(-50%);z-index: 1;" />
</div>
<div class="g_clear_scroll" style="overflow: auto hidden;max-width: 172px;" :style="{
'maxWidth':swiperItem.num * (swiperItem.size.width + swiperItem.mr) + 'px'
}">
<div class="move-obj g_clear_scroll" :style="{
'transform':'translateX(' + move + 'px)',
'height':swiperItem.size.height + 'px',
}">
<div class="g_flex_row_start image-box" :style="{'width':(swiperItem.size.width + swiperItem.mr) * swiperItem.list.length + 'px'}" :class="'g_h_' + swiperItem.size.height">
<div class="g_cursor_point g_flex_row_start" v-for="(item,index) in swiperItem.list" :key="index" :class="'g_mr_' + mr">
<div v-if="item.indexOf('.mp4') == -1">
<a-image :width="swiperItem.size.width" :height="swiperItem.size.height" :src="decodeURI(item)" class="g_flex_column_center" style="object-fit: cover;" />
</div>
<div v-if="item.indexOf('.mp4') > 0">
<div class="mask-video g_flex_c" :style="{
'width':swiperItem.size.width + 'px',
'height':swiperItem.size.height + 'px'
}" @click="handleOpenVideoModal(item)">
<i class="iconfont icon-kaishi g_c_c g_fsi_20"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="default-img g_position_rela" @click="handleNextEvent" v-if="swiperItem.list.length > swiperItem.num && isShowNext">
<img src="../../../assets/image/other/next.png" class="g_w_28 g_h_28 g_cursor_point" style="position: absolute;right: -12px;top: 50%;transform: translateY(-50%);z-index: 1;" />
</div>
<div class="g_flex_column_center g_fs_14 g_c_6 g_cursor_point" style="text-decoration: underline;" @click="handleOpenUploadModal" :class="swiperItem.list.length == 0 ? '' : 'g_ml_22'" v-if="swiperItem.isEdit"></div>
</div>
<!-- 视频 -->
<videoPreview :videoModal="videoModal" />
<!-- <a-modal v-model:open="videoModal.isShow" title :footer="null" style="width: 734px;" wrapClassName="video-modal" :destroyOnClose="true">
<div class="g_flex_row_center">
<video :controls="true" style="width: 90%;max-height:calc(100vh - 200px);">
<source :src="videoModal.url" type="video/mp4" />
<source :src="videoModal.url" type="video/ogg" />您的浏览器不支持 HTML5 video 标签
</video>
</div>
</a-modal>-->
</div>
</template>
<script setup>
/*
* @params list 展示的数组
* @params size 尺寸对象形式存放图片的宽高
* @params num 默认显示的数量数值类型
* @params mr 右边距数值类型
* @params edit 是否显示编辑按钮
*/
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps } from 'vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import videoPreview from './videoPreview.vue'
/* #################### 初始化事件 #################### */
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G
const props = defineProps({
list: {
type: Array,
default: () => {
return []
},
},
size: {
type: Object,
default: () => {
return {
width: 80,
height: 45,
}
},
},
num: {
type: Number,
default: () => {
return 4
},
},
mr: {
type: Number,
default: () => {
return 5
},
},
edit: {
type: Boolean,
default: () => {
return false
},
},
})
const swiperItem = ref({
list: [],
size: {
width: 0,
height: 0,
},
num: 4,
mr: 5,
isEdit: false,
})
onMounted(() => {
let _list = []
if (props.list && props.list.length > 0) {
_list = props.list
} else {
_list = []
}
if (!props.size) {
props.size.width = 80
props.size.height = 45
}
if (_list.length > props.num) {
isShowPrev.value = false
isShowNext.value = true
} else {
isShowPrev.value = false
isShowNext.value = false
}
if (!props.num) {
props.num = 4
}
if (!props.mr) {
props.mr = 5
}
if (!props.edit) {
props.edit = false
}
swiperItem.value = {
list: _list,
size: {
width: Number(props.size.width),
height: Number(props.size.height),
},
num: Number(props.num),
mr: Number(props.mr),
isEdit: props.edit,
}
})
/* #################### 控制器 #################### */
const isShowPrev = ref(false)
const isShowNext = ref(true)
const move = ref(0)
const handlePrevEvent = () => {
//
if (move.value >= 0) {
move.value = 0
isShowPrev.value = false
isShowNext.value = true
} else {
move.value += swiperItem.value.size.width + swiperItem.value.mr
isShowPrev.value = true
isShowNext.value = true
if (move.value == 0) {
move.value = 0
isShowPrev.value = false
isShowNext.value = true
}
}
}
const handleNextEvent = () => {
//
if (move.value <= -(swiperItem.value.size.width + swiperItem.value.mr) * (swiperItem.value.list.length - swiperItem.value.num)) {
move.value = -(swiperItem.value.size.width + swiperItem.value.mr) * (swiperItem.value.list.length - swiperItem.value.num)
isShowPrev.value = true
isShowNext.value = false
} else {
isShowPrev.value = true
isShowNext.value = true
move.value -= swiperItem.value.size.width + swiperItem.value.mr
if (move.value <= -(swiperItem.value.size.width + swiperItem.value.mr) * (swiperItem.value.list.length - swiperItem.value.num)) {
move.value = -(swiperItem.value.size.width + swiperItem.value.mr) * (swiperItem.value.list.length - swiperItem.value.num)
isShowPrev.value = true
isShowNext.value = false
}
}
}
const handleOpenUploadModal = () => {
//
}
/* #################### 视频弹窗 #################### */
const videoModal = ref({
isShow: false,
url: '',
})
const handleOpenVideoModal = ($data) => {
//
videoModal.value.url = $data
videoModal.value.isShow = true
}
const bodyStyle = ref({
width: '800px',
top: '50%',
transform: 'translateY(-50%)',
'padding-top': '0',
'padding-bottom': '0',
})
</script>
<style lang="less">
.g-components-image-swiper-picture {
.mask-video {
background-color: #000;
}
.move-obj {
transition: all 0.3s linear;
}
}
</style>

@ -1,195 +0,0 @@
<!-- 图库列表 -->
<template>
<div class="g-components-image-user-picture">
<div class="title-box g_flex_row_between">
<div class="g_fs_14 g_c_0 title g_pl_8">用户图库</div>
<div class="g_fs_14 g_c_6 edit g_pr_8 g_cursor_point" @click="handleOpenEditModal"></div>
</div>
<div class="panel g_flex_row_start g_pl_11 g_pb_11" style="min-height:calc(100% - 32px)">
<div v-if="imageList.length > 0" class="g_flex_row_start_c">
<div class="g_w_80 g_h_80 g_flex_c item" v-for="(item,index) in imageList" :key="index">
<div v-if="item.type == 'img'" class="g_border_e g_flex_c g_w_78 g_h_78" style="border-radius: 4px;">
<a-image :width="70" :height="70" :src="item.thumbUrl" style="border-radius: 4px;" />
</div>
<div v-else-if="item.type == 'mp4'" @click="handleOpenVideoModal(item)" class="g_border_e g_flex_c flex_c g_w_78 g_h_78 g_bg_0 g_cursor_point" style="border-radius: 4px;">
<!-- <video :width="70" :height="70" @click="handleOpenVideoModal(item)" :src="item.thumbUrl" style="border-radius: 4px;" /> -->
<i class="iconfont icon-kaishi g_c_c g_fsi_20"></i>
</div>
</div>
</div>
<div v-if="imageList.length == 0">
<div class="g_w_80 g_h_80 g_flex_c item">
<div class="g_border_e g_flex_c g_w_78 g_h_78" style="border-radius: 4px;">
<a-image :width="70" :height="70" src="http://matripe.oss-cn-beijing.aliyuncs.com/defaultMountain.png" style="border-radius: 4px;" />
</div>
</div>
</div>
</div>
<a-modal v-model:open="imageModel.isShow" title="用户图库" width="640px" centered :destroyOnClose="true" :forceRender="true">
<div class="g_pt_30 modal-box">
<a-form :model="imageModel" name="basic" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }" autocomplete="off" style="width: 80%;" class="g_ml_51">
<a-form-item label="附件" name="remark">
<div class="picture-box">
<annexPanel :list="imageList" from="user" @submitEvent="getFilelist" @removeEvent="handleRemove" accept="image/png, image/jpg, image/jpeg, video/mp4" />
</div>
</a-form-item>
</a-form>
</div>
<template #footer>
<a-button @click="handleCloseImage"></a-button>
</template>
</a-modal>
<!-- 视频预览 -->
<videoPreview :videoModal="videoModal" />
</div>
</template>
<script setup>
/*
* @params list 图片数组
* @params userid 用户id
* @params from 来源字符串 默认为default调用指定接口
* @function submitEvent 上传成功事件
* list:图片数组,
* id:当前上传成功的id,
* annex:annex的成功回调
* @function removeEvent 删除按钮事件
* 返回对象格式内容为图片信息
* @function closeModel 关闭弹窗事件
*/
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps } from 'vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { uploadImage } from '../../../api/base.js'
import { delivryUploadUserImage, delivryDelUserImage } from '../../../api/other/delivery.js'
import annexPanel from '../upload/annex.vue'
import videoPreview from './videoPreview.vue'
/* #################### 初始化事件 #################### */
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G
const emits = defineEmits(['submitEvent', 'removeEvent', 'closeModel'])
const props = defineProps({
list: {
type: Array,
default: () => {
return []
},
},
from: {
type: String,
default: () => {
return 'default'
},
},
userid: {
type: Number,
default: () => {
return 0
},
},
})
onMounted(() => {
console.log('mounted 用户图库:', props.list)
imageList.value = props.list
imageList.value.forEach((item) => {
if (item.url.indexOf('mp4') > -1) {
item.type = 'mp4'
} else {
item.type = 'img'
}
})
console.log('mounted 用户图库:', imageList.value)
})
watch(props.list, (val) => {
console.log('watch 用户图库:', val)
imageList.value = val
})
watch(props.userid, (val) => {
console.log('props.userid', val)
props.userid = val.content
})
/**
* 视频预览相关
*/
const videoModal = ref({
isShow: false,
url: '',
})
const handleOpenVideoModal = ($data) => {
//
console.log($data)
videoModal.value.url = $data.url
videoModal.value.isShow = true
}
/**
* 视频预览相关 end
*/
const imageList = ref([])
const imageModel = ref({
isShow: false,
})
const handleOpenEditModal = () => {
//
imageModel.value.isShow = true
}
const getFilelist = (e) => {
console.log(props)
if (props.from == 'default') {
delivryUploadUserImage({
fkId: props.userid,
url: e.image,
type: 20,
recordState: 1,
}).then((imageRes) => {
imageList.value[imageList.value.length - 1].id = imageRes.data.img.id
emits('submitEvent', {
list: imageList.value,
id: imageRes.data.img.id,
annex: e,
})
})
} else {
emits('submitEvent', {
list: imageList.value,
id: '',
annex: e,
})
}
}
const handleRemove = ($data) => {
emits('removeEvent', $data)
}
const handleCloseImage = () => {
imageModel.value.isShow = false
emits('closeModel')
}
</script>
<style lang="less" scoped>
.g-components-image-user-picture {
width: 288px;
border: 1px solid #eee;
border-radius: 4px;
.title-box {
background-color: #f3f3f3;
line-height: 32px;
.edit {
text-decoration: underline;
}
}
.item {
margin-top: 11px;
margin-right: 11px;
&:nth-child(3n) {
margin-right: 0;
}
}
}
/deep/ :where(.css-dev-only-do-not-override-185kyl0).ant-empty .ant-empty-image {
height: 56px !important;
}
</style>

@ -1,51 +0,0 @@
<template>
<div>
<!-- 视频 -->
<a-modal v-model:open="videoModal.isShow" title :footer="null" style="width: 734px;" wrapClassName="video-modal" :destroyOnClose="true">
<div class="g_flex_row_center">
<video :controls="true" style="width: 90%;max-height:calc(100vh - 200px);">
<source :src="videoModal.url" type="video/mp4" />
<source :src="videoModal.url" type="video/ogg" />您的浏览器不支持 HTML5 video 标签
</video>
</div>
</a-modal>
</div>
</template>
<script setup>
/*
* @params videoModal 配置对象
*/
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps } from 'vue'
import { message } from 'ant-design-vue'
const props = defineProps({
videoModal: {
type: Object,
default: {
isShow: false,
url: '',
},
},
})
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G
onMounted(() => {})
</script>
<style lang='less' scoped>
.video-modal {
.ant-modal-content {
background-color: transparent;
box-shadow: none;
}
.ant-modal-close {
width: 30px;
height: 30px;
color: #ccc;
svg {
width: 30px;
height: 30px;
}
}
}
</style>

@ -1,84 +0,0 @@
<template>
<div>
<a-select v-model:value="selectedList" mode="multiple" placeholder="请选择驻场" option-label-prop="onsiteChildren" @change="onSiteChange">
<a-select-option v-for="item in onsiteList" :disabled="(selectedList ? (selectedList.length >= 3 ? true : false) :false) && item.disabled" :value="item.userName" :title="item.id">{{item.userName}}</a-select-option>
</a-select>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps,computed } from 'vue'
import { message } from 'ant-design-vue'
import { getOnsiteListApi } from '../../../api/manage/onsite.js'
const props = defineProps({
selectedList: {
type: Array,
default: [],
},
})
const emits = defineEmits(['selectChange'])
// const selectedList = ref(props.selectedList)
watch(
() => props.selectedList,
(val) => {
console.log(val)
onSiteChange(val)
},
{
// immediate: true,
}
)
let selectedList = computed(()=>{
return props.selectedList
})
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G
onMounted(() => {
getOnsiteList()
})
const onsiteList = ref([])
const agencyId = ref(localStorage.getItem('DAOTIAN_userinfo_agencyid'))
/**
* 获取驻场列表
*/
const getOnsiteList = () => {
let subInfo = {
agencyId: agencyId.value,
pageSize: 10000,
pageNum: 1,
}
getOnsiteListApi(subInfo).then((res) => {
console.log(res)
onsiteList.value = res.data.recordList
})
}
/**
* 驻场选择变化
*/
const onSiteChange = (e, e1) => {
console.log(e)
console.log(e1)
console.log(onsiteList.value)
let newArr = []
//
onsiteList.value.forEach((item) => {
if (e.findIndex((i1) => i1 == item.userName) > -1) {
item.disabled = false
newArr.push(item)
} else {
item.disabled = true
}
})
// selectedList = e
console.log(newArr)
emits('selectChange', newArr)
}
</script>
<style lang='less' scoped>
</style>

@ -1,293 +0,0 @@
<template>
<div class="p-components-map-poi">
<div id="container"></div>
<div id="myPageTop" >
<div class="g_flex_row_center" style="position: relative;">
<div>
<input id="tipinput" placeholder="请输入关键词搜索" autocomplete="off" v-model="keyword" />
</div>
<div class="btn g_flex_c">
<svg focusable="false" data-icon="search" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"></path></svg>
</div>
</div>
</div>
<div class="g_pt_10 g_flex_row_between">
<div>
<div class="g_fw_700 g_fs_14">{{mapInfo.name}}</div>
<div class="g_fs_14">{{mapInfo.address}}</div>
</div>
<div class="g_flex_column_center" v-if="mapInfo.name">
<a-button type="primary" @click="submitForm"></a-button>
</div>
</div>
</div>
</template>
<script setup>
import {
ref,
onMounted,
getCurrentInstance,
watch,
defineEmits,
defineProps
} from 'vue';
import {
Modal,
message
} from 'ant-design-vue';
import AMapLoader from "@amap/amap-jsapi-loader";
import {
mapConfig
} from "../../../utils/config.js";
/* #################### 初始化事件 #################### */
const emits = defineEmits(['submitEvent'])
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G;
const mapInfo = ref({
name:"",
address:"",
lat:"",
lng:""
});
const keyword = ref('');
const selectInfo = ref({});
const props = defineProps({
info:{
type: Object,
default: () => {
return {
name:"",
address:"",
lat:"",
lng:""
}
}
},
})
const defaultInfo = ref({
mdistrict:"",
});
onMounted(()=>{
mapInfo.value = props.info;
keyword.value = mapInfo.value.name;
});
/* ############################## 地图配置 ############################## */
window._AMapSecurityConfig = {
securityJsCode: mapConfig.secret,
};
AMapLoader.load({
key: mapConfig.key,
version: "2.0",
plugins: ["AMap.Scale","AMap.HawkEye","AMap.ToolBar","AMap.ControlBar","AMap.Geocoder"],
})
.then((AMap) => {
/* ################################# 初始化 ################################# */
var map = new AMap.Map("container",{
zoom: 12,
resizeEnable: true
}); //"container" <div> id
/* ################################# 点击事件 ################################# */
var geocoder = new AMap.Geocoder();
var marker,lnglat = [];
map.on("click", function (ev) {
mapInfo.value = {
name:'',
address:'',
lat:ev.lnglat.lat,
lng:ev.lnglat.lng
}
keyword.value = mapInfo.value.name;
lnglat = [ev.lnglat.lng,ev.lnglat.lat];
geocoder.getAddress(lnglat, function(status, result) {
if (marker) {
marker.setMap(null);
marker = null;
}
setTimeout(()=>{
console.log('点击点返回结果:',result);
if (status === 'complete' && result.info === 'OK') {
let _address = "",
_district = result.regeocode.addressComponent.province + result.regeocode.addressComponent.city + result.regeocode.addressComponent.district;
if(result.regeocode.addressComponent.neighborhood){
_address = result.regeocode.addressComponent.neighborhood;
}else{
_address = result.regeocode.formattedAddress.replace(_district + result.regeocode.addressComponent.township,() => '');
}
mapInfo.value.name = _address;
keyword.value = mapInfo.value.name;
mapInfo.value.address = result.regeocode.formattedAddress;
selectInfo.value = {
address:result.regeocode.formattedAddress,
district:_district,
lat:mapInfo.value.lat,
lng:mapInfo.value.lng,
name:mapInfo.value.name,
}
defaultInfo.value = {
mdistrict:_district
}
marker = new AMap.Marker({
icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png",
position: [mapInfo.value.lng, mapInfo.value.lat],
offset: new AMap.Pixel(-13, -30)
});
marker.setMap(map);
}
},10)
})
});
/* ################################# 工具条 ################################# */
var scale = new AMap.Scale({
visible: true
}),
toolBar = new AMap.ToolBar({
visible: true,
position: {
top: '110px',
right: '40px'
}
}),
controlBar = new AMap.ControlBar({
visible: true,
position: {
top: '10px',
right: '10px'
}
}),
overView = new AMap.HawkEye({
visible: true
});
map.addControl(scale);
map.addControl(toolBar);
map.addControl(controlBar);
map.addControl(overView);
/* ################################# POI搜索与选择 ################################# */
//
var autoOptions = {
input: "tipinput"
};
AMap.plugin(['AMap.PlaceSearch','AMap.AutoComplete'], function(){
var auto = new AMap.AutoComplete(autoOptions);
var placeSearch = new AMap.PlaceSearch({
map: map
}); //
auto.on("select", select);//
function select(e) {
console.log('map 获取下拉选择地址信息:',e)
placeSearch.setCity(e.poi.adcode);
placeSearch.search(e.poi.name); //
selectInfo.value = e.poi;
if(e.poi.location){
mapInfo.value = {
name:e.poi.name,
address:e.poi.district + e.poi.address,
lat:e.poi.location.lat,
lng:e.poi.location.lng
}
}else{
mapInfo.value = {
name:e.poi.name,
address:e.poi.district + e.poi.address,
lat:'',
lng:''
}
}
keyword.value = mapInfo.value.name;
defaultInfo.value = {
mdistrict:e.poi.district
}
}
});
}).catch((e) => {
console.log('地图异常状态数据:',e);
});
const submitForm = ()=>{
if(mapInfo.value.lat == ""){
console.log('经纬度:',mapInfo.value)
message.error('请重新选择')
return false;
}
emits("submitEvent",{
pointInfo:Object.assign(defaultInfo.value,mapInfo.value),
initInfo:Object.assign(defaultInfo.value,selectInfo.value)
});
}
</script>
<style lang="less">
.p-components-map-poi{
#container{
width: 100%;
height: calc(100vh - 254px);
}
#myPageTop{
position: absolute;
top: 106px;
width: 280px;
border: none;
right: 236px;
padding: 0;
}
#myPageTop input{
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
font-variant: tabular-nums;
list-style: none;
-webkit-font-feature-settings: "tnum";
font-feature-settings: "tnum";
position: relative;
display: inline-block;
width: 100%;
height: 32px;
padding: 4px 11px;
color: rgba(0,0,0,.65);
font-size: 14px;
line-height: 1.5;
background-color: #fff;
background-image: none;
border: 1px solid #d9d9d9;
border-radius: 4px;
-webkit-transition: all .3s;
transition: all .3s;
width: 280px;
outline: #1677ff;
}
#myPageTop input:focus{
border-color: #40a9ff;
border-right-width: 1px!important;
}
#myPageTop .btn{
cursor: pointer;
width: 32px;
height: 32px;
background-color: #1677ff;
color: #fff;
position: absolute;
right: 0;
top: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.amap-icon img{
width: 25px;
height: 34px;
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -1,44 +0,0 @@
<template>
<div class>
<span class="timebox">{{ timedata.deadline }}</span>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps } from 'vue'
const props = defineProps({
timedata: {
type: Object,
default: () => {
return {
isfinish: true,
deadline: 60,
timer: null,
}
},
},
})
// const deadline = ref(60)
onMounted(() => {
setDeadline()
})
const setDeadline = () => {
props.timedata.timer = setInterval(() => {
props.timedata.deadline--
console.log(props.timedata.deadline)
if (props.timedata.deadline <= 0) {
props.timedata.deadline = 60
props.timedata.isfinish = true
clearInterval(props.timedata.timer)
}
}, 1000)
}
</script>
<style scoped lang="less">
.timebox {
display: inline-block;
width: 72px;
text-align: center;
}
</style>

@ -1,227 +0,0 @@
<!-- 附件上传 -->
<template>
<div class="g-components-upload-picture">
<a-upload v-model:file-list="fileList" class="avatar-uploader" :show-upload-list="true" :before-upload="beforeUpload" @preview="setVisible" :list-type="listtype" @change="handleUpload" @remove="handleRemove" :maxCount="maxCount" :accept="accept">
<img v-if="image" :src="image" alt="avatar" />
<div v-else>
<div v-if="listtype == 'picture'">
<a-button>
<template #icon>
<PlusOutlined />
</template>
{{ btnText }}
</a-button>
</div>
<div v-if="listtype == 'picture-card'">
<plus-outlined />
<div style="margin-top: 8px" v-if="btnText != '职位图片'">{{ btnText }}</div>
</div>
</div>
</a-upload>
<a-image v-if="imgUrl" :width="200" :height="0" :style="{ display: 'none', verticalAlign: 'top' }" :preview="{ visible, onVisibleChange: closeVisible }" :src="imgUrl" />
<!-- 视频预览 -->
<videoPreview :videoModal="videoModal" />
</div>
<!-- -->
</template>
<script setup>
/*
* @params list 回显的图片数组
* @params from 来源 字符串 默认为default调用指定接口
* @params listtype 类型 字符串
* picture 卡片式文件列表
* picture-card 照片墙式文件列表
* @function submitEvent 上传成功回调返回对象格式
* {
* list:图片数组
* image:当前上传的oss地址
* }
* @function removeEvent 删除事件返回对象格式内容为图片信息
*/
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps } from "vue";
import { PlusOutlined } from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
import { uploadImage } from "../../../api/base.js";
import { delivryUploadUserImage, delivryDelUserImage } from "../../../api/other/delivery.js";
import { useStore } from "../../../stores/counter.ts";
import videoPreview from "../image/videoPreview.vue";
import $ from "jquery";
/* #################### 初始化事件 #################### */
const storeJS = useStore();
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G;
const emits = defineEmits(["submitEvent", "removeEvent"]);
const props = defineProps({
list: {
type: Array,
default: () => {
return [];
},
},
from: {
type: String,
default: () => {
return "default";
},
},
type: {
type: String,
default: () => {
return "picture";
},
},
text: {
type: String,
default: () => {
return "上传";
},
},
accept: {
type: String,
default: () => {
return "image/png,image/jpg,image/jpeg";
},
},
maxCount: {
type: Number,
default: () => {
return 2;
},
},
});
const listtype = ref("picture");
const image = ref("");
const fileList = ref([]);
const btnText = ref("");
const imgUrl = ref("");
onMounted(() => {
image.value = "";
fileList.value = props.list;
console.log("fileList.value", fileList.value);
listtype.value = props.type ? props.type : "picture";
btnText.value = props.text ? props.text : "上传";
// console.log('annex mounted:',props,' -- ',props.list);
});
const beforeUpload = (file) => {
return false;
};
const closeVisible = () => {
visible.value = false;
};
const visible = ref(false);
const videoModal = ref({});
const setVisible = (file) => {
console.log(file.thumbUrl);
if (file.thumbUrl.indexOf("mp4") > -1) {
setTimeout(() => {
videoModal.value.url = file.url;
videoModal.value.isShow = true;
}, 200);
} else {
imgUrl.value = file.thumbUrl;
setTimeout(() => {
visible.value = true;
}, 200);
}
};
const handleUpload = (info) => {
console.log("info", info);
// return;
if (info.file.status == "removed") {
//
} else {
//
uploadImage().then((res) => {
let dataObj = {};
dataObj.policy = res.data.data.policy;
dataObj.signature = res.data.data.signature;
dataObj.ossaccessKeyId = res.data.data.accessid;
dataObj.key = res.data.data.dir + commonJS.getUUID() + "_${filename}";
dataObj.dir = res.data.data.dir;
dataObj.host = res.data.data.host;
let url = "http://matripe-cms.oss-cn-beijing.aliyuncs.com";
var formData = new FormData();
//formDataappend
formData.append("key", dataObj.key); //oss
formData.append("OSSAccessKeyId", dataObj.ossaccessKeyId); //accessKeyId
formData.append("policy", dataObj.policy); //policy
formData.append("Signature", dataObj.signature); //
formData.append("success_action_status", "200"); // 204
formData.append("file", info.file); //
//
$.ajax({
type: "post",
url: "http://matripe-cms.oss-cn-beijing.aliyuncs.com",
data: formData,
contentType: false, // Content-Type
processData: false,
success: function (data) {
fileList.value[fileList.value.length - 1].thumbUrl = dataObj.host + "/" + dataObj.key.replace("${filename}", info.file.name);
if (props.from == "default") {
delivryUploadUserImage({
fkId: storeJS.$state.deliveryUserid.content,
url: fileList.value[fileList.value.length - 1].thumbUrl,
type: 20,
recordState: 1,
}).then((imageRes) => {
message.success("添加成功");
fileList.value[fileList.value.length - 1].id = imageRes.data.img.id;
emits("submitEvent", {
list: fileList.value,
image: fileList.value[fileList.value.length - 1].thumbUrl,
});
});
} else {
emits("submitEvent", {
list: fileList.value,
image: fileList.value[fileList.value.length - 1].thumbUrl,
});
}
},
fail: function (err) {
console.log(err);
},
});
});
}
};
const handleRemove = ($data) => {
if (props.from == "default") {
delivryDelUserImage($data.id).then(() => {
message.success("删除成功");
emits("removeEvent", $data);
});
} else {
emits("removeEvent", $data);
}
};
</script>
<style lang="less">
.g-components-upload-picture {
.ant-upload-list {
display: flex;
display: -webkit-flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
.ant-upload-list-item-container {
width: calc(50% - 20px);
margin-right: 20px;
&:nth-child(2n) {
margin-right: 0;
}
}
}
.ant-upload-list-item-name {
color: #1677ff !important;
&:hover {
background-color: #ffffff !important;
}
}
}
</style>

@ -1,139 +0,0 @@
<!-- 身份证上传 -->
<template>
<div class="g-components-upload-idcard">
<a-upload list-type="picture-card" class="avatar-uploader" :show-upload-list="false" :before-upload="beforeUpload" @change="handleUpload" :accept="accept">
<img v-if="image && from == 'idcard'" :src="image" alt="avatar" style="height: 32px;width: auto;" />
<div v-else class="g_flex_row_center">
<PlusOutlined class="g_c_8c g_fw_600 g_fs_14 g_mr_2" />
<div class="ant-upload-text g_fs_14 g_c_8c">上传证件</div>
</div>
</a-upload>
</div>
</template>
<script setup>
/*
* @params url 回显的图片
* @params from 来源
* default普通图片上传
* idcard身份证识别上传
* @function submitEvent 识别成功回调返回对象格式
* {
* info:身份证携带信息
* image:身份证图片oss地址
* }
*/
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps } from 'vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { uploadImage } from '../../../api/base.js'
import $ from 'jquery'
/* #################### 初始化事件 #################### */
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G
const emits = defineEmits(['submitEvent'])
const props = defineProps({
url: {
type: String,
default: () => {
return ''
},
},
from: {
type: String,
default: () => {
return 'default'
},
},
accept: {
type: String,
default: () => {
return 'image/png,image/jpg,image/jpeg'
},
},
})
onMounted(() => {
image.value = props.url
})
const image = ref('')
const beforeUpload = (file) => {
return false
}
const handleUpload = (info) => {
uploadImage().then((res) => {
let dataObj = {}
dataObj.policy = res.data.data.policy
dataObj.signature = res.data.data.signature
dataObj.ossaccessKeyId = res.data.data.accessid
dataObj.key = res.data.data.dir + commonJS.getUUID() + '_${filename}'
dataObj.dir = res.data.data.dir
dataObj.host = res.data.data.host
let url = 'http://matripe-cms.oss-cn-beijing.aliyuncs.com'
var formData = new FormData()
//
var idcardFormData = new FormData()
idcardFormData.append('uploadFile', info.file)
//formDataappend
formData.append('key', dataObj.key) //oss
formData.append('OSSAccessKeyId', dataObj.ossaccessKeyId) //accessKeyId
formData.append('policy', dataObj.policy) //policy
formData.append('Signature', dataObj.signature) //
formData.append('success_action_status', '200') // 204
formData.append('file', info.file) //
//
$.ajax({
type: 'post',
url: 'http://matripe-cms.oss-cn-beijing.aliyuncs.com',
data: formData,
contentType: false, // Content-Type
processData: false,
success: function (data) {
image.value = dataObj.host + '/' + dataObj.key.replace('${filename}', info.file.name)
if (props.from == 'default') {
//
emits('submitEvent', {
info: {},
image: image.value,
})
} else if (props.from == 'idcard') {
$.ajax({
type: 'post',
url: 'http://idaotian.com/yishoudan/commons/idCardOcrRecognize',
data: idcardFormData,
headers: {
Authorization: 'Bearer ' + localStorage.getItem('DAOTIAN_token'),
},
contentType: false, // Content-Type
processData: false,
success: function (idCardData) {
if (idCardData.status == 200) {
emits('submitEvent', {
info: idCardData.data,
image: image.value,
})
} else {
console.log('识别异常:', err)
}
},
fail: function (err) {
console.log(err)
},
})
}
},
fail: function (err) {
console.log('上传异常:', err)
},
})
})
}
</script>
<style lang="less">
.g-components-upload-idcard {
}
</style>

@ -1,269 +0,0 @@
<template>
<div class="g-components-wx">
<div class="panel">
<div class="m-fee" style="">
<div class="g_flex_row_start g_c_f40" style="font-size: 1rem">
<div class="fee-title">服务费</div>
<div v-if="info.feeObj.id != 6 && info.feeObj.id != 5">{{ (info.feeObj.id == 7 ? "" : info.feeObj.val) + info.feeObj.suffix }}</div>
<div v-if="info.feeObj.id == 6">{{ "" + info.feeObj.val + info.feeObj.suffix }}</div>
<div v-if="info.feeObj.id == 5">{{ "" + info.feeObj.val + info.feeObj.suffix }}</div>
</div>
<div>
<i class="iconfont icon-zhengyan1 g_c_f40"></i>
</div>
</div>
<div class="show-box g_position_rela g_clear_scroll">
<!-- 服务费 -->
<!-- <div class="m-fee g_position_abso" style="right:.6rem;top:1.2rem">
<div style="font-size:.7rem" class="fee-title">服务费</div>
<div style="font-size:.7rem" v-if="info.feeObj.id != 6 && info.feeObj.id != 5">{{(info.feeObj.id == 7 ? '':info.feeObj.val) + info.feeObj.suffix}}</div>
<div style="font-size:.7rem" v-if="info.feeObj.id == 6">{{'' + info.feeObj.val + info.feeObj.suffix}}</div>
<div style="font-size:.7rem" v-if="info.feeObj.id == 5">{{'' + info.feeObj.val + info.feeObj.suffix}}</div>
</div> -->
<!-- 顶部信息 -->
<div class="m-title">
<div class="g_flex_row_between">
<div class="g_flex_1 g_ell_1 g_c_3 g_fw_600 name" :title="info.name">{{ info.name }}</div>
</div>
</div>
<!-- 副标题信息 -->
<div class="sub-info g_flex_row_start m-sub-title" style="margin-bottom: 0.4rem">
<div class="g_flex_row_start" style="margin-right: 0.5rem">
<!-- <div class="g_c_7 g_flex_column_center" style="margin-right: 0.15rem">
<img src="../../../../src/assets/image/month.svg" style="width: 0.7rem; height: 0.7rem" />
</div> -->
<div class="cont g_flex_column_center g_c_f40 g_fw_500">
<template v-if="info.salaryClassifyObj.id == 4 || info.salaryClassifyObj.id == 6">
{{ info.salaryClassifyObj.str }}
</template>
<template v-else-if="info.salaryClassifyObj.id == 7"> {{ info.salaryClassifyValue || "-" }} / </template>
<template v-else-if="info.salaryClassifyObj.id == 2 || info.salaryClassifyObj.id == 3 || info.salaryClassifyObj.id == 5"> {{ info.salaryClassifyObj.str || "-" }}{{ info.salaryClassifyValue || "-" }}{{ info.salaryClassifyObj.suffix || "-" }} </template>
<template v-else> {{ info.salaryClassifyValue || "-" }} {{ info.salaryClassifyObj.suffix || "-" }} </template>
</div>
<!-- aa{{info.salaryClassifyValue}}{{info.salaryClassifyObj}}bb -->
</div>
</div>
<!-- 副标题信息 -->
<div class="sub-info g_flex_row_start m-sub-title" style="margin-bottom: 0.2rem">
<div class="g_flex_row_start" style="margin-right: 0.5rem">
<div class="g_c_7 g_flex_column_center">
<EnvironmentOutlined class="g_c_7 icon" />
</div>
<div class="g_c_7 cont g_flex_column_center">{{ info.cityInfo.city == "undefined, undefined" ? "请选择企业地址" : info.cityInfo.city }}</div>
</div>
<div class="g_flex_row_start">
<div class="g_c_7 g_flex_column_center">
<TeamOutlined class="g_c_7 icon" />
</div>
<div class="g_c_7 cont g_flex_column_center">{{ info.otherInfo.sexAge }} </div>
</div>
</div>
<div class="sub-info g_flex_row_start m-sub-title" style="margin-bottom: 0.4rem">
<div class="g_flex_row_start" style="margin-right: 0.5rem">
<i class="iconfont icon-zhaopinqiye" style="font-size: 0.7rem; margin-right: 0.3rem"></i>
<!-- <div class="g_c_7 g_flex_column_center" style="margin-right: 0.15rem">
<img src="../../../../src/assets/image/month.svg" style="width: 0.7rem; height: 0.7rem" />
</div> -->
<div class="cont g_flex_column_center g_c_7 g_fw_500">
{{ info.store || "请输入招聘企业" }}
</div>
<!-- aa{{info.salaryClassifyValue}}{{info.salaryClassifyObj}}bb -->
</div>
</div>
<!-- 企业 -->
<div class="boss-info g_flex_row_start">
<div class="bom g_flex_row_start">
<div class="logo g_flex_none g_flex_column_center">
<img v-if="info.bossInfo.logo" :src="info.bossInfo.logo" class="img" />
<img v-if="!info.bossInfo.logo" src="../../../assets/image/shareJob/nopicture.png" class="img" />
</div>
<div class="g_flex_column_center g_flex_1">
<div class="g_ell_1 g_c_3 title" :title="info.bossInfo.title">{{ info.bossInfo.title }}</div>
</div>
</div>
</div>
<!-- 详情 -->
<div class="m-desc">
<!-- <div class="tip g_fs_18 g_c_3 g_flex_column_center">职位描述</div> -->
<div class="g_c_7 desc" v-if="info.desc_yq == '-'"></div>
<div v-html="info.desc_yq || '-'" style="white-space: pre-line" class="g_c_7 desc" v-else></div>
</div>
<!-- 中奖 -->
<div class="m-swiper-box" style="padding-top: 0.8rem; border-top: 1px solid #f5f5f5">
<div v-if="info.list.length == 0">
<img src="../../../assets/image/shareJob/nopicture.png" class="empty-img" />
</div>
<div v-else class="g_flex_row_start_none" style="overflow: hidden">
<div v-for="(item, index) in info.list" :key="index">
<img :src="item" class="a-img" />
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance, watch, defineEmits, defineProps } from "vue";
import { TeamOutlined, EnvironmentOutlined } from "@ant-design/icons-vue";
import swiperPanel from "../image/swiperPicture.vue";
/* #################### 初始化事件 #################### */
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G;
const props = defineProps({
info: {
type: Object,
default: () => {
return {
name: "-",
minMonthlyPay: "-",
maxMonthlyPay: "-",
salaryClassify: "-",
salaryClassifyValue: "-",
cityInfo: {
city: "-",
},
otherInfo: {
sexAge: "-",
},
bossInfo: {
logo: "",
title: "-",
},
desc_yq: "-",
list: [],
feeObj: { str: "按小时", pre: "按时", suffix: "元/小时", val: 1 },
};
},
},
});
watch(props, (val) => {});
const toGetPrice = (price) => {
return commonJS.toGetPrice(price);
};
</script>
<style lang="less">
/* 375稿
* 1px ÷ 20 = 1rem;
*/
.g-components-wx {
.panel {
// width: 375px;
// height: 812px;
position: relative;
width: 320px;
height: 690px;
box-shadow: 0px 2px 15px 0px rgba(0, 0, 0, 0.15);
border-radius: 30px;
background-image: url("../../../assets/image/job/bg.png");
background-repeat: no-repeat;
background-size: 320px 690px;
padding-top: 75px;
.m-fee {
position: absolute;
display: flex;
justify-content: space-between;
padding: 0 1rem;
top: 5rem;
width: 100%;
height: 4rem;
align-items: center;
background-color: #ffede6;
border-top: 1px solid #ff4400;
border-bottom: 1px solid #ff4400;
.fee-title {
// min-width: 4.5rem;
// width: 100%;
}
}
.show-box {
padding: 0px 1rem 0;
height: calc(100% - 65px);
overflow-y: auto;
padding-bottom: 1rem;
margin-top: 4rem;
// .m-fee {
// min-width: 4rem;
// padding: 0.125rem 0;
// border-radius: 6px;
// text-align: center;
// background-color: #fff1ec;
// color: #ff4400;
// overflow: hidden;
// .fee-title {
// min-width: 4.5rem;
// width: 100%;
// color: #fff;
// background-color: #ff4400;
// }
// }
.m-title {
padding: 1.2rem 0 0.5rem;
.name {
font-size: 1.2rem;
}
.price {
font-size: 0.9rem;
margin-left: 0.5rem;
}
}
.sub-info {
margin-bottom: 1.2rem;
.icon {
font-size: 0.7rem;
margin-right: 0.2rem;
}
.cont {
font-size: 0.7rem;
}
}
.boss-info {
background-color: rgba(0, 182, 102, 0.05);
padding: 0.6rem 0.8rem;
.img {
width: 1.9rem;
height: 1.9rem;
border-radius: 50%;
}
.title {
margin-left: 0.5rem;
font-size: 0.7rem;
}
}
.m-desc {
margin-top: 1.2rem;
.desc {
font-size: 0.7rem;
letter-spacing: 1;
word-break: break-all;
}
}
.m-swiper-box {
margin-top: 0.8rem;
.empty-img {
width: 3rem;
height: 3rem;
border-radius: 6px;
}
}
}
}
.a-img {
width: 3.05rem;
height: 3.05rem;
border-radius: 0.2rem;
margin-right: 0.55rem;
margin-bottom: 0.8rem;
&:nth-child(5) {
margin-right: 0;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -79,7 +79,7 @@ const route = useRoute();
import { useStore } from "@/stores/counter";
const storeJS = useStore();
import Mfooter from "../layout/m-footer.vue";
import timmer from "./components/timmer.vue";
// import timmer from "./components/timmer.vue";
import { getPhoneCodeApi, loginApi, infoApi } from "../api/login.js";
onBeforeUnmount(() => {
console.log("进入登录页面");

@ -1,88 +0,0 @@
<template>
<div style="border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
</div>
</template>
<script setup>
import '@wangeditor/editor/dist/css/style.css'
import { onBeforeUnmount, ref, shallowRef, onMounted, watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { uploadImageApi } from "../../api/contentConfig";
const props = defineProps({
modelValue: {
type: String,
default: '',
},
});
const emit = defineEmits(['update:modelValue', 'image-upload']);
const editorRef = shallowRef();
const valueHtml = ref(props.modelValue);
watch(() => props.modelValue, (newValue) => {
if (newValue !== valueHtml.value) {
valueHtml.value = newValue;
}
});
watch(valueHtml, (newValue) => {
emit('update:modelValue', newValue);
});
const toolbarConfig = {};
const editorConfig = {
placeholder: '请输入内容...',
MENU_CONF: {}
};
editorConfig.MENU_CONF['uploadImage'] = {
async customUpload(file, insertFn) {
try {
const response = await uploadImageApi(file);
const imageUrl = 'http://123.249.121.26:8801/images/' + response.data;
insertFn(imageUrl);
} catch (error) {
console.error('Image upload failed:', error);
}
}
};
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = (editor) => {
editorRef.value = editor;
};
onMounted(() => {
setTimeout(() => {
valueHtml.value = props.modelValue;
}, 100);
});
</script>
<style scoped>
.wysiwyg-editor {
border: 1px solid #ccc;
z-index: 100;
}
</style>

@ -1,134 +0,0 @@
<template>
<div class="g_flex_row_center">
<div class="m-job-detail g_pt_24" style="width: 880px">
<a-form :model="currentInfo" class="main_container" @finish="submitInfo" :labelCol="{ span: 3 }" :wrapperCol="{ span: 20 }">
<a-form-item class="g_mb_12" label="标题" name="title" :rules="[{ required: true, message: '请输入标题' }]">
<a-input v-model:value="currentInfo.title" placeholder="请输入标题"></a-input>
</a-form-item>
<a-form-item class="g_mb_12" label="发布时间" name="publishTimeStr" :rules="[{ required: false, message: '请选择发布时间' }]">
<a-date-picker v-model:value=" currentInfo.publishTimeStr" placeholder="请选择发布时间" :minuteStep="30" format="YYYY-MM-DD HH:mm" :showTime="{ format: 'HH:mm' }" style="width: 100%" />
</a-form-item>
<a-form-item class="g_mb_12" label="内容" :rules="[{ required: true, message: '请输入内容' }]" name="content">
<iframe src="./static/editor.html" class="g_border_d" width="100%" height="500px" frameborder="0" ref="iframeDom" style="border-radius: 6px"></iframe>
</a-form-item>
<!-- <div class="g_flex_row_center">
<div class="g_fs_14">内容</div>
<div class="g_mt_0 g_br_6 g_flex_1" style="border: 1px solid #d9d9d9"></div>
</div> -->
<a-form-item class="g_mb_12">
<div class="g_flex_row_start g_mt_24 g_ml_110">
<a-button class="g_mr_16" @click="cancel"></a-button>
<!-- <a-button class="g_mr_16" @click="subType = 0" html-type="submit">存草稿</a-button> -->
<a-button type="primary" @click="subType = 1" html-type="submit">发布</a-button>
</div>
</a-form-item>
</a-form>
<!-- <div class="g_flex_row_center">
<div class="g_fs_14">内容</div>
<div class="g_mt_0 g_br_6 g_flex_1" style="border: 1px solid #d9d9d9">
<iframe src="../../../public/static/editor.html" width="100%" height="500px" frameborder="0" ref="iframeDom" style="border-top-left-radius: 6px"></iframe>
</div>
</div> -->
</div>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance, watch, onBeforeUnmount } from "vue";
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G;
import { useRouter, useRoute } from "vue-router";
const router = useRouter(); //
const route = useRoute();
import dayjs from "dayjs"
dayjs.locale("zh-cn");;
import { saveMessageApi,getMessageDetailApi,updateMessageApi } from "../../api/messageConfig/message";
import { message } from "ant-design-vue";
import { useStore } from "@/stores/counter";
//
// const currentTime = ref(dayjs());
// console.log('currentTime.value',currentTime.value);
const storeJS = useStore();
let currentInfo = ref({});
onMounted(() => {
console.log(route);
let newList = [{}, {}, {}];
newList.forEach((item, index) => {
item.rank = index + 1;
item.title = "常用发票主体信息" + index;
item.content = "默认主体:郑州伯才供应链科技有限公司 单位名称:郑州伯才供应链科技有限公司 纳税人识别号91410100MA9L4HDT0L 地址:河南自贸试验区郑州" + index;
item.time = "2024-03-11 13:04:24";
});
if (route.query.id) {
// currentInfo.value = newList[Number(route.query.id)];
getMessageDetailApi(route.query.id).then((res) => {
console.log(res.data);
// currentInfo.value.publishTimeStr = res.data.publishTime;
currentInfo.value = res.data;
currentInfo.value.publishTimeStr = dayjs(res.data.publishTime);
})
}
setTimeout(() => {
initData();
}, 1000);
// getMessageDetailApi(route.query.id).then((res) => {
// console.log(res);
// })
});
const iframeDom = ref();
window.addEventListener("message", (val) => {
// console.log(val.data);
if (val.data.lake) {
currentInfo.value.contentYuque = val.data.lake;
currentInfo.value.content = val.data.html;
currentInfo.value.remake = val.data.remake;
console.log(currentInfo.value);
}
});
const initData = () => {
iframeDom.value.contentWindow.postMessage("");
console.log(currentInfo.value.content);
// iframeDom.value.onload = function () {
console.log(route);
if (route.name == "messageEdit") {
iframeDom.value.contentWindow.postMessage(currentInfo.value.content);
} else {
iframeDom.value.contentWindow.postMessage("");
}
// };
};
const cancel = () => {
router.back();
};
const subType = ref(0);
const submitInfo = () => {
console.log(subType.value);
console.log(currentInfo.value);
// console.log(dayjs(currentInfo.value.publishTimeStr).format("YYYY-MM-DD HH:mm"));
let obj = {
title: currentInfo.value.title,
content: currentInfo.value.content,
remake: currentInfo.value.remake,
contentYuque: currentInfo.value.contentYuque,
publishTimeStr: dayjs(currentInfo.value.publishTimeStr).format("YYYY-MM-DD HH:mm") + ":00",
status: subType.value,
};
if (route.name == "messageEdit") {
obj.recordId = route.query.id
updateMessageApi(obj).then((res) => {
router.back();
})
}else{
saveMessageApi(obj).then((res) => {
router.back();
});
}
};
</script>
<style lang="less" scoped></style>

@ -1,347 +0,0 @@
<template>
<div class="content-management">
<a-tabs v-model:activeKey="activeTab" @change="tabChange">
<a-tab-pane key="recommendations" tab="今日推荐"></a-tab-pane>
<a-tab-pane key="stores" tab="门店"></a-tab-pane>
<a-tab-pane key="events" tab="赛事分析"></a-tab-pane>
<!-- <a-tab-pane key="highlights" tab="划重点"></a-tab-pane> -->
<template #rightExtra>
<a-button type="primary" @click="showAddModal"></a-button>
</template>
</a-tabs>
<a-table :columns="columns" :data-source="filteredData" :rowKey="record => record.id">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'content' && activeTab !== 'highlights'">
<div v-if="record.classify === 1">
<a-image
:src="record.img"
:width="50"
:height="50"
style="margin-right: 5px;"
/>
</div>
<span v-else v-text="record.content1"></span>
</template>
<template v-if="column.key === 'relatedOption' && activeTab === 'highlights'">
<span>{{ getRelatedOptionLabel(record.relatedOption) }}</span>
</template>
<template v-if="column.key === 'status' && activeTab !== 'highlights'">
<a-tag :color="record.status === 1 ? 'green' : 'orange'">
{{ record.status === 1 ? '已发布' : '未发布' }}
</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" @click="editItem(record)"></a-button>
<a-button v-if="activeTab !== 'recommendations'" type="link" @click="deleteItem(record)"></a-button>
</a-space>
</template>
</template>
</a-table>
<a-modal
v-model:visible="modalVisible"
:title="modalMode === 'add' ? '新增内容' : '编辑内容'"
@ok="handleModalOk"
@cancel="handleModalCancel"
width="800px"
>
<a-form :model="formState" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
<a-form-item label="类型" v-if="activeTab !== 'highlights'">
<a-select v-model:value="formState.classify" :disabled="modalMode === 'edit'">
<a-select-option :value="1">今日推荐</a-select-option>
<a-select-option :value="0">门店</a-select-option>
<a-select-option :value="2">赛事分析</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="标题">
<a-input v-model:value="formState.title" placeholder="输入标题"/>
</a-form-item>
<template v-if="activeTab !== 'highlights'">
<a-form-item label="主图">
<a-upload
v-model:fileList="formState.images"
list-type="picture-card"
:max-count="1"
@preview="handlePreview"
@change="handleImageChange"
:customRequest="customRequest"
>
<div v-if="formState.images.length < 1">
<plus-outlined />
<div style="margin-top: 8px">上传图片</div>
</div>
</a-upload>
</a-form-item>
<a-form-item label="内容" v-if="formState.classify !== 1">
<wysiwyg-editor v-model="formState.content" @image-upload="handleEditorImageUpload" />
</a-form-item>
<a-form-item label="状态">
<a-switch v-model:checked="formState.status" :checked-value="1" :unchecked-value="0" />
</a-form-item>
</template>
<a-form-item label="关联选项" v-if="activeTab === 'highlights'">
<a-select v-model:value="formState.relatedOption">
<a-select-option v-for="option in relatedOptions" :key="option.key" :value="option.key">
{{ option.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
<a-modal v-model:visible="previewVisible" :title="previewTitle" :footer="null">
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import WysiwygEditor from './WysiwygEditor.vue';
import { saveContentApi,getHzd, updateContentApi, getContentListApi, deleteContentApi, uploadImageApi } from "../../api/contentConfig";
const activeTab = ref('recommendations');
const modalVisible = ref(false);
const modalMode = ref('add');
const previewVisible = ref(false);
const previewImage = ref('');
const previewTitle = ref('');
const columns = computed(() => {
if (activeTab.value === 'highlights') {
return [
{ title: '类型', dataIndex: 'classify', key: 'classify' },
{ title: '标题', dataIndex: 'title', key: 'title' },
{ title: '关联', dataIndex: 'relatedOption', key: 'relatedOption' },
{ title: '操作', key: 'action' },
];
} else {
return [
{ title: '类型', dataIndex: 'classify', key: 'classify' },
{ title: '标题', dataIndex: 'title', key: 'title' },
{ title: '内容', dataIndex: 'content', key: 'content' },
{ title: '状态', dataIndex: 'status', key: 'status' },
{ title: '操作', key: 'action' },
];
}
});
const data = reactive([]);
const classify = ref(1);
const formState = reactive({
id: null,
classify: 1,
title: '',
content: '',
img: '',
images: [],
status: 0,
relatedOption: null,
});
const relatedOptions = [
{ key: 1, label: '足球总进球' },
{ key: 2, label: '足球2.0' },
{ key: 3, label: '足球3.0' },
{ key: 4, label: '足球中高倍' },
{ key: 5, label: '足球高倍' },
{ key: 6, label: '足球8.0' },
{ key: 7, label: '篮球' },
{ key: 8, label: '排列三' },
{ key: 9, label: '快乐八' },
];
const filteredData = computed(() => {
const tabToClassify = {
'recommendations': 1,
'stores': 0,
'events': 2,
'highlights': 61,
};
return data.filter(item => item.classify === tabToClassify[activeTab.value]);
});
const showAddModal = () => {
modalMode.value = 'add';
const tabToClassify = {
'recommendations': 1,
'stores': 0,
'events': 2,
'highlights': 61,
};
Object.assign(formState, {
id: null,
classify: tabToClassify[activeTab.value],
title: '',
content: '',
img: '',
images: [],
status: activeTab.value === 'highlights' ? 1 : 0,
relatedOption: null
});
modalVisible.value = true;
};
const editItem = (record) => {
modalMode.value = 'edit';
Object.assign(formState, {
...record,
images: record.img ? [{
uid: -1,
name: 'image.jpg',
status: 'done',
url: record.img,
}] : [],
relatedOption: record.relatedOption,
});
modalVisible.value = true;
};
const deleteItem = async (record) => {
try {
await deleteContentApi(record.id);
message.success('删除成功');
fetchData();
} catch (error) {
message.error('删除失败');
}
};
const handleModalOk = async () => {
try {
const data = {
classify: activeTab.value === 'highlights' ? 61 : formState.classify,
title: formState.title,
content: activeTab.value === 'highlights' ? '' : (formState.classify === 1 ? '' : formState.content),
img: activeTab.value === 'highlights' ? '' : processImagePath(formState.img),
status: activeTab.value === 'highlights' ? 1 : formState.status,
relatedOption: activeTab.value === 'highlights' ? formState.relatedOption : undefined,
remark: activeTab.value === 'highlights' ? formState.relatedOption : undefined,
};
if (modalMode.value === 'add') {
await saveContentApi(data);
} else {
await updateContentApi({ ...data, recordId: activeTab.value === 'highlights' ? 61 : formState.id });
}
message.success(modalMode.value === 'add' ? '添加成功' : '编辑成功');
modalVisible.value = false;
fetchData();
} catch (error) {
message.error(modalMode.value === 'add' ? '添加失败' : '编辑失败');
}
};
const handleModalCancel = () => {
modalVisible.value = false;
};
const processImagePath = (imgPath) => {
const urlPrefix = 'http://123.249.121.26:8801/images/';
if (imgPath.startsWith(urlPrefix)) {
return imgPath.substring(urlPrefix.length);
}
return imgPath;
};
const tabChange = (activeKey) => {
classify.value = activeKey === 'recommendations' ? 1 : activeKey === 'stores' ? 0 : activeKey === 'events' ? 2 : 61;
fetchData();
};
const handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj);
}
previewImage.value = file.url || file.preview;
previewVisible.value = true;
previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
};
const customRequest = async ({ file, onSuccess, onError }) => {
try {
const response = await uploadImageApi(file);
formState.img = response.data;
onSuccess(response, file);
} catch (error) {
onError(error);
}
};
const handleImageChange = ({ fileList }) => {
formState.images = fileList;
};
const handleEditorImageUpload = async (file) => {
try {
const response = await uploadImageApi(file);
const imageUrl = `http://123.249.121.26:8801/images/${response.data}`;
return imageUrl; //
} catch (error) {
message.error('图片上传失败');
return '';
}
};
const getBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
};
const fetchData = async () => {
try {
console.log(activeTab.value);
if (activeTab.value == 'highlights') {
const response = await getHzd();
const records = response.data;
console.log(records);
//
data.splice(0, data.length, ...records);
} else {
const response = await getContentListApi(1, 10, classify.value);
const records = response.data.records.map(record => {
if (record.img) {
record.img = 'http://123.249.121.26:8801/images/' + record.img;
}
//100
record.content1 = record.content.length > 100 ? record.content.substring(0, 100) + '...' : record.content;
return record;
});
data.splice(0, data.length, ...records);
}
} catch (error) {
message.error('获取数据失败');
}
};
const getRelatedOptionLabel = (optionKey) => {
const option = relatedOptions.find(option => option.key === optionKey);
return option ? option.label : '';
};
onMounted(() => {
fetchData();
});
</script>
<style scoped>
.content-management {
padding: 24px;
}
.table-actions {
margin-bottom: 16px;
text-align: right;
}
</style>

@ -1,280 +0,0 @@
<template>
<div class="today-notes">
<a-tabs v-model:activeKey="activeTab" @change="handleTabChange">
<a-tab-pane v-for="type in noteTypes" :key="type.key" :tab="type.label">
<a-table :columns="getColumns(type.key)" :data-source="filteredData" :rowKey="record => record.recordId">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'scheduleJson'">
<span v-if="record.classify !== 8 && record.classify !== 9">
{{ formatScheduleJson(record.scheduleJson) }}
</span>
</template>
<template v-if="column.key === 'today'">
<span>{{ record.today }}</span>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" @click="editItem(record)"></a-button>
<a-button type="link" @click="deleteItem(record)"></a-button>
</a-space>
</template>
</template>
</a-table>
</a-tab-pane>
<template #rightExtra>
<a-button type="primary" @click="showAddModal"></a-button>
</template>
</a-tabs>
<a-modal
v-model:visible="modalVisible"
:title="(modalMode === 'add' ? '新增' : '编辑') + currentNoteTypeLabel"
@ok="handleModalOk"
@cancel="handleModalCancel"
width="800px"
>
<a-form :model="formState" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-form-item label="日期" name="todayStr" :rules="[{ required: true, message: '请选择日期' }]">
<a-date-picker v-model:value="formState.todayStr" style="width: 100%" format="YYYY-MM-DD" />
</a-form-item>
<a-form-item label="类型" name="classify" :rules="[{ required: true, message: '请选择类型' }]">
<a-select v-model:value="formState.classify">
<a-select-option v-for="type in noteTypes" :key="type.key" :value="type.key">
{{ type.label }}
</a-select-option>
</a-select>
</a-form-item>
<template v-if="formState.classify !== 8 && formState.classify !== 9">
<a-form-item label="比赛" name="match" :rules="[{ required: true, message: '请输入比赛' }]">
<a-input v-model:value="formState.match" />
</a-form-item>
<a-form-item label="结果1" name="team1" :rules="[{ required: true, message: '请输入结果1' }]">
<a-input v-model:value="formState.team1" />
</a-form-item>
<!-- <a-form-item label="结果2" name="team2" :rules="[{ required: false, message: '请输入结果2' }]">
<a-input v-model:value="formState.team2" />
</a-form-item> -->
<!-- <a-form-item label="比分结果" name="result" :rules="[{ required: true, message: '请输入结果' }]">
<a-input v-model:value="formState.result" />
</a-form-item> -->
</template>
<a-form-item label="赔率" name="odds">
<a-input v-model:value="formState.odds" />
</a-form-item>
<a-form-item label="中否" name="fruit">
<a-input v-model:value="formState.fruit" />
</a-form-item>
<a-form-item v-if="formState.classify === 8" label="开奖号" name="winNo">
<a-input v-model:value="formState.winNo" />
</a-form-item>
<a-form-item v-if="formState.classify === 8 || formState.classify === 9" label="推荐号" name="recommendNo">
<a-input v-model:value="formState.recommendNo" />
</a-form-item>
<a-form-item label="截止时间" name="endTime">
<a-input v-model:value="formState.endTime" />
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { getScheduleListApi, deleteScheduleApi, saveScheduleApi, updateScheduleApi } from '../../api/scheduleConfig';
const noteTypes = [
{ key: 1, label: '总进球' },
{ key: 2, label: '足球2.0' },
{ key: 3, label: '足球3.0' },
{ key: 4, label: '中高倍' },
{ key: 5, label: '高倍' },
{ key: 6, label: '足球8.0' },
{ key: 7, label: '篮球' },
{ key: 8, label: '排列三' },
{ key: 9, label: '快乐八' },
];
const activeTab = ref(noteTypes[0].key);
const modalVisible = ref(false);
const modalMode = ref('add');
const data = reactive([]);
const formState = reactive({
recordId: null,
todayStr: '',
classify: 1,
match: '',
team1: '',
team2: '',
result: '',
odds: '',
fruit: '',
winNo: '',
recommendNo: '',
endTime: '',
});
const filteredData = computed(() => {
return data.map(item => ({
...item,
today: dayjs(item.today).format('YYYY-MM-DD')
})).filter(item => item.classify === activeTab.value);
});
const currentNoteType = computed(() => {
return noteTypes.find(type => type.key === activeTab.value) || noteTypes[0];
});
const currentNoteTypeLabel = computed(() => {
return currentNoteType.value.label;
});
const formatScheduleJson = (scheduleJson) => {
try {
const parsed = JSON.parse(scheduleJson);
return `${parsed.match} ${parsed.team1}`;
} catch (error) {
return scheduleJson;
}
};
const showAddModal = () => {
modalMode.value = 'add';
Object.assign(formState, {
recordId: null,
todayStr: dayjs(),
classify: activeTab.value,
match: '',
team1: '',
team2: '',
result: '',
odds: '',
fruit: '',
winNo: '',
recommendNo: '',
endTime: '',
});
modalVisible.value = true;
};
const editItem = (record) => {
modalMode.value = 'edit';
Object.assign(formState, {
...record,
todayStr: dayjs(record.today),
});
if (record.scheduleJson) {
try {
const parsed = JSON.parse(record.scheduleJson);
formState.match = parsed.match;
formState.team1 = parsed.team1;
formState.team2 = parsed.team2;
formState.result = parsed.result;
} catch (error) {
console.error('Error parsing scheduleJson:', error);
}
}
modalVisible.value = true;
};
const deleteItem = async (record) => {
try {
await deleteScheduleApi(record.id);
message.success('删除成功');
fetchData();
} catch (error) {
message.error('删除失败');
}
};
const handleModalOk = async () => {
try {
let payload = {
...formState,
recordId: formState.id,
todayStr: formState.todayStr.format('YYYY-MM-DD'),
};
if (payload.classify !== 8 && payload.classify !== 9) {
payload.scheduleJson = JSON.stringify({
match: payload.match,
team1: payload.team1,
team2: payload.team2,
result: payload.result,
});
//
delete payload.match;
delete payload.team1;
delete payload.team2;
delete payload.result;
}else{
payload.scheduleJson = payload.scheduleJson ? payload.scheduleJson : '{"match":"","team1":"","team2":"","result":""}';
}
if (modalMode.value === 'add') {
await saveScheduleApi(payload);
} else {
await updateScheduleApi(payload);
}
message.success(modalMode.value === 'add' ? '添加成功' : '编辑成功');
modalVisible.value = false;
fetchData();
} catch (error) {
message.error(modalMode.value === 'add' ? '添加失败' : '编辑失败');
}
};
const handleModalCancel = () => {
modalVisible.value = false;
};
const fetchData = async () => {
try {
const response = await getScheduleListApi(1, 100, activeTab.value);
data.splice(0, data.length, ...response.data.records);
} catch (error) {
message.error('获取数据失败');
}
};
const handleTabChange = (newActiveKey) => {
activeTab.value = newActiveKey;
fetchData();
};
const getColumns = (classify) => {
const baseColumns = [
{ title: '日期', dataIndex: 'today', key: 'today' },
{ title: '赔率', dataIndex: 'odds', key: 'odds' },
{ title: '结果', dataIndex: 'fruit', key: 'fruit' },
{ title: '截止日期', dataIndex: 'endTime', key: 'endTime' },
{ title: '操作', key: 'action' },
];
if (classify === 8) {
baseColumns.splice(1, 0, { title: '开奖号', dataIndex: 'winNo', key: 'winNo' });
baseColumns.splice(2, 0, { title: '推荐号', dataIndex: 'recommendNo', key: 'recommendNo' });
} else if (classify === 9) {
baseColumns.splice(1, 0, { title: '推荐号', dataIndex: 'recommendNo', key: 'recommendNo' });
} else {
baseColumns.splice(1, 0, { title: '比赛内容', key: 'scheduleJson' });
}
return baseColumns;
};
onMounted(() => {
fetchData();
});
</script>
<style scoped>
.today-notes {
padding: 24px;
}
</style>

@ -1,104 +0,0 @@
<template>
<div class="important-points">
<a-form :model="formState" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }">
<a-form-item label="标题">
<a-input v-model:value="formState.title" />
</a-form-item>
<a-form-item label="关联项">
<a-select v-model:value="formState.remark" style="width: 100%">
<a-select-option v-for="type in noteTypes" :key="type.key" :value="type.key">
{{ type.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
<a-row>
<a-col :span="6" :offset="4"> <a-button type="primary" @click="handleSave"></a-button>
</a-col>
</a-row>
<a-divider />
<!-- <div class="content-preview">
<h2>内容预览</h2>
<p>标题: {{ formState.title }}</p>
<p>关联项: {{ getRemarkLabel(formState.remark) }}</p>
</div> -->
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { saveContentApi,getHzd, updateContentApi, getContentListApi, deleteContentApi, uploadImageApi } from "../../api/contentConfig";
const noteTypes = [
{ key: 1, label: '总进球' },
{ key: 2, label: '足球2.0' },
{ key: 3, label: '足球3.0' },
{ key: 4, label: '中高倍' },
{ key: 5, label: '高倍' },
{ key: 6, label: '足球8.0' },
{ key: 7, label: '篮球' },
{ key: 8, label: '排列三' },
{ key: 9, label: '快乐八' },
];
const formState = reactive({
recordId: 61,
title: '',
remark: null,
});
const getRemarkLabel = (key) => {
const type = noteTypes.find(t => t.key === key);
return type ? type.label : '未选择';
};
const fetchData = async () => {
try {
const response = await getHzd();
formState.title = response.data.title;
formState.remark = response.data.remark !== null ? parseInt(response.data.remark) : null;
} catch (error) {
message.error('获取数据失败');
}
};
const handleSave = async () => {
try {
await updateContentApi({
recordId: formState.recordId,
title: formState.title,
content: formState.remark,
remark:formState.remark
});
message.success('保存成功');
} catch (error) {
message.error('保存失败');
}
};
const handleTitleChange = (e) => {
formState.title = e.target.value;
};
const handleRemarkChange = (value) => {
formState.remark = value;
};
onMounted(() => {
fetchData();
});
</script>
<style scoped>
.important-points {
padding: 24px;
}
.content-preview {
background-color: #f0f2f5;
padding: 16px;
border-radius: 4px;
}
</style>

@ -1,247 +0,0 @@
<template>
<div class="carousel-management">
<div class="table-actions">
<a-button type="primary" @click="showAddModal"></a-button>
</div>
<a-table :columns="columns" :data-source="data" :rowKey="record => record.id">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'img'">
<template v-if="record.img.endsWith('.mp4')">
<video
:src="record.img"
:width="50"
:height="50"
style="margin-right: 5px;"
controls
/>
</template>
<template v-else>
<a-image
:src="record.img"
:width="50"
:height="50"
style="margin-right: 5px;"
/>
</template>
</template>
<template v-if="column.key === 'status'">
<a-tag :color="record.status === 1 ? 'green' : 'red'">
{{ record.status === 1 ? '启用' : '不启用' }}
</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" @click="editItem(record)"></a-button>
<a-button type="link" @click="deleteItem(record)"></a-button>
</a-space>
</template>
</template>
</a-table>
<a-modal
v-model:visible="modalVisible"
:title="modalMode === 'add' ? '新增轮播图' : '编辑轮播图'"
@ok="handleModalOk"
@cancel="handleModalCancel"
width="800px"
>
<a-form :model="formState" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
<a-form-item label="标题" name="title" :rules="[{ required: true, message: '请输入标题' }]">
<a-input v-model:value="formState.title" />
</a-form-item>
<a-form-item label="图片" name="img" :rules="[{ required: true, message: '请上传图片' }]">
<a-upload
v-model:fileList="formState.images"
list-type="picture-card"
:max-count="1"
@preview="handlePreview"
@change="handleImageChange"
:customRequest="customRequest"
>
<div v-if="formState.images.length < 1">
<plus-outlined />
<div style="margin-top: 8px">上传图片</div>
</div>
</a-upload>
</a-form-item>
<a-form-item label="状态" name="status">
<a-switch v-model:checked="formState.status" :checked-value="1" :unchecked-value="0" />
</a-form-item>
</a-form>
</a-modal>
<a-modal v-model:visible="previewVisible" :title="previewTitle" :footer="null">
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { getCarouselListApi, saveCarouselApi, deleteCarouselApi, updateCarouselApi, uploadImageApi } from "../../api/carouselConfig";
const modalVisible = ref(false);
const modalMode = ref('add');
const previewVisible = ref(false);
const previewImage = ref('');
const previewTitle = ref('');
const columns = [
{ title: '标题', dataIndex: 'title', key: 'title' },
{ title: '图片', dataIndex: 'img', key: 'img' },
{ title: '状态', dataIndex: 'status', key: 'status' },
{ title: '操作', key: 'action' },
];
const data = reactive([]);
const formState = reactive({
id: null,
title: '',
images: [],
img: '',
status: 1,
});
const showAddModal = () => {
modalMode.value = 'add';
Object.assign(formState, { id: null, title: '', images: [], img: '', status: 1 });
modalVisible.value = true;
};
const editItem = (record) => {
modalMode.value = 'edit';
Object.assign(formState, {
id: record.id,
title: record.title,
images: [{
uid: -1,
name: 'image.jpg',
status: 'done',
url: record.img,
}],
img: record.img,
status: record.status,
});
modalVisible.value = true;
};
const deleteItem = async (record) => {
try {
await deleteCarouselApi(record.id);
message.success('删除成功');
fetchData();
} catch (error) {
message.error('删除失败');
}
};
const handleModalOk = async () => {
console.log(formState);
try {
const data = {
title: formState.title,
img: processImagePath(formState.img),
status: formState.status
};
if (modalMode.value === 'add') {
console.log(data);
await saveCarouselApi(data);
} else {
await updateCarouselApi({ ...data, recordId: formState.id });
}
message.success(modalMode.value === 'add' ? '添加成功' : '编辑成功');
modalVisible.value = false;
fetchData();
} catch (error) {
message.error(modalMode.value === 'add' ? '添加失败' : '编辑失败');
}
};
const processImagePath = (imgPath) => {
const urlPrefix = 'http://123.249.121.26:8801/images/';
if (imgPath.startsWith(urlPrefix)) {
return imgPath.substring(urlPrefix.length);
}
return imgPath;
};
const handleModalCancel = () => {
modalVisible.value = false;
};
const handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj);
}
previewImage.value = file.url || file.preview;
previewVisible.value = true;
previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
};
const customRequest = async ({ file, onSuccess, onError }) => {
try {
const response = await uploadImageApi(file);
formState.img = response.data.url;
onSuccess(response, file);
} catch (error) {
onError(error);
}
};
const handleImageChange = ({ fileList }) => {
formState.images = fileList;
if (fileList.length > 0) {
const lastFile = fileList[fileList.length - 1];
formState.img = lastFile.response ? lastFile.response.data : lastFile.url;
}
};
const getBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
};
const fetchData = async () => {
try {
const response = await getCarouselListApi(1);
// data.splice(0, data.length, ...response.data.records);
const records = response.data.records.map(record => {
if (record.img) {
record.img = 'http://123.249.121.26:8801/images/' + record.img;
}
return record;
});
data.splice(0, data.length, ...records);
} catch (error) {
message.error('获取数据失败');
}
};
onMounted(() => {
fetchData();
});
</script>
<style scoped>
.carousel-management {
padding: 24px;
}
.table-actions {
margin-bottom: 16px;
text-align: right;
}
</style>

@ -1,222 +0,0 @@
<template>
<div class="lottery-management">
<a-tabs v-model:activeKey="activeTab" @change="handleTabChange">
<a-tab-pane v-for="type in lotteryTypes" :key="type.key" :tab="type.label">
<a-table :columns="columns" :data-source="filteredData" :rowKey="record => record.recordId">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'numbers'">
<span>
{{ getFormattedNumbers(record) }}
</span>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" @click="editItem(record)"></a-button>
<a-button type="link" @click="deleteItem(record)"></a-button>
</a-space>
</template>
</template>
</a-table>
</a-tab-pane>
<template #rightExtra>
<a-button type="primary" @click="showAddModal"></a-button>
</template>
</a-tabs>
<a-modal
v-model:visible="modalVisible"
:title="(modalMode === 'add' ? '新增' : '编辑') + currentLotteryTypeLabel"
@ok="handleModalOk"
@cancel="handleModalCancel"
width="800px"
>
<a-form :model="formState" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-form-item label="日期" name="todayStr" :rules="[{ required: true, message: '请选择日期' }]">
<a-date-picker v-model:value="formState.todayStr" style="width: 100%" format="YYYY-MM-DD" />
</a-form-item>
<a-form-item label="期数" name="lotteryNo" :rules="[{ required: true, message: '请输入期数' }]">
<a-input v-model:value="formState.lotteryNo" placeholder="例如第250007期" />
</a-form-item>
<a-form-item v-for="i in currentLotteryType.blueCount" :key="`blue${i}`" :label="`蓝球${i}`" :name="`blue${i}`" :rules="[{ required: true, message: '请输入数字' }]">
<a-input-number v-model:value="formState[`blue${i}`]" :min="0" :max="99" />
</a-form-item>
<a-form-item v-for="i in currentLotteryType.redCount" :key="`red${i}`" :label="`红球${i}`" :name="`red${i}`" :rules="[{ required: true, message: '请输入数字' }]">
<a-input-number v-model:value="formState[`red${i}`]" :min="0" :max="99" />
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { getLotteryListApi, deleteLotteryApi, saveLotteryApi, updateLotteryApi } from '../../api/lotteryConfig';
const lotteryTypes = [
{ key: 1, label: '超级大乐透', blueCount: 5, redCount: 2 },
{ key: 2, label: '双色球', blueCount: 6, redCount: 1 },
{ key: 3, label: '排列三', blueCount: 3, redCount: 0 },
{ key: 4, label: '排列五', blueCount: 5, redCount: 0 },
{ key: 5, label: '3D', blueCount: 3, redCount: 0 },
{ key: 6, label: '快乐八', blueCount: 20, redCount: 0 },
];
const activeTab = ref(lotteryTypes[0].key);
const modalVisible = ref(false);
const modalMode = ref('add');
const columns = [
{ title: '日期', dataIndex: 'today', key: 'today' },
{ title: '期数', dataIndex: 'lotteryNo', key: 'lotteryNo' },
{ title: '开奖号码', key: 'numbers', width: '300px' },
{ title: '操作', key: 'action' },
];
const data = reactive([]);
const formState = reactive({
recordId: null,
todayStr: '',
classify: 1,
lotteryNo: '',
});
for (let i = 1; i <= 20; i++) {
formState[`blue${i}`] = '';
}
for (let i = 1; i <= 5; i++) {
formState[`red${i}`] = '';
}
const filteredData = computed(() => {
return data.filter(item => item.classify === activeTab.value);
});
const currentLotteryType = computed(() => {
return lotteryTypes.find(type => type.key === activeTab.value) || lotteryTypes[0];
});
const currentLotteryTypeLabel = computed(() => {
return currentLotteryType.value.label;
});
const showAddModal = () => {
modalMode.value = 'add';
Object.assign(formState, {
recordId: null,
todayStr: dayjs(),
classify: activeTab.value,
lotteryNo: '',
});
for (let i = 1; i <= 20; i++) {
formState[`blue${i}`] = '';
}
for (let i = 1; i <= 5; i++) {
formState[`red${i}`] = '';
}
modalVisible.value = true;
};
const editItem = (record) => {
modalMode.value = 'edit';
Object.assign(formState, {
...record,
todayStr: dayjs(record.today),
});
modalVisible.value = true;
};
const deleteItem = async (record) => {
try {
await deleteLotteryApi(record.id);
message.success('删除成功');
fetchData();
} catch (error) {
message.error('删除失败');
}
};
const removeEmptyFields = (obj) => {
return Object.fromEntries(
Object.entries(obj).filter(([_, v]) => v !== '' && v !== null)
);
};
const handleModalOk = async () => {
try {
delete formState.today;
delete formState.createTime;
delete formState.isDeleted;
delete formState.updateTime;
delete formState.week;
let payload = {
...formState,
todayStr: formState.todayStr.format('YYYY-MM-DD'),
classify: activeTab.value,
recordId: formState.id,
};
payload = removeEmptyFields(payload);
if (modalMode.value === 'add') {
await saveLotteryApi(payload);
} else {
await updateLotteryApi(payload);
}
message.success(modalMode.value === 'add' ? '添加成功' : '编辑成功');
modalVisible.value = false;
fetchData();
} catch (error) {
message.error(modalMode.value === 'add' ? '添加失败' : '编辑失败');
}
};
const handleModalCancel = () => {
modalVisible.value = false;
};
const fetchData = async () => {
try {
const response = await getLotteryListApi(1, 100, activeTab.value);
data.splice(0, data.length, ...response.data.records.map(record => ({
...record,
today: dayjs(record.today).format('YYYY-MM-DD')
})));
} catch (error) {
message.error('获取数据失败');
}
};
const handleTabChange = (newActiveKey) => {
activeTab.value = newActiveKey;
fetchData();
};
onMounted(() => {
fetchData();
});
const getFormattedNumbers = (record) => {
const type = lotteryTypes.find(t => t.key === record.classify);
const numbers = [];
for (let i = 1; i <= type.blueCount; i++) {
if (record[`blue${i}`]) numbers.push(record[`blue${i}`]);
}
for (let i = 1; i <= type.redCount; i++) {
if (record[`red${i}`]) numbers.push(record[`red${i}`]);
}
return numbers.join(', ');
};
</script>
<style scoped>
.lottery-management {
padding: 24px;
}
</style>
Loading…
Cancel
Save