这次真的不一样了,修改了CSS样式,在前端就做了图片压缩,10m图片瞬间变为800k以下,新增活动管理、轮播图管理
This commit is contained in:
parent
4ee1cfa3a9
commit
2bd3a67a7d
|
@ -15,7 +15,7 @@
|
|||
<style>
|
||||
html,body,#app{
|
||||
height:100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
|
53
package-lock.json
generated
53
package-lock.json
generated
|
@ -201,6 +201,15 @@
|
|||
"regenerator-runtime": "^0.14.0"
|
||||
}
|
||||
},
|
||||
"@babel/runtime-corejs3": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.26.10.tgz",
|
||||
"integrity": "sha512-uITFQYO68pMEYR46AHgQoyBg7KPPJDAbGn4jUTIRgCFJIp88MIBUianVOplhZDEec07bp9zIyr4Kp0FCyQzmWg==",
|
||||
"requires": {
|
||||
"core-js-pure": "^3.30.2",
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
}
|
||||
},
|
||||
"@babel/standalone": {
|
||||
"version": "7.26.1",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/standalone/-/standalone-7.26.1.tgz",
|
||||
|
@ -1322,6 +1331,11 @@
|
|||
"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="
|
||||
},
|
||||
"blueimp-canvas-to-blob": {
|
||||
"version": "3.29.0",
|
||||
"resolved": "https://registry.npmmirror.com/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.29.0.tgz",
|
||||
"integrity": "sha512-0pcSSGxC0QxT+yVkivxIqW0Y4VlO2XSDPofBAqoJ1qJxgH9eiUDLv50Rixij2cDuEfx4M6DpD9UGZpRhT5Q8qg=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
|
@ -1434,6 +1448,15 @@
|
|||
"resolved": "https://registry.npmmirror.com/compatx/-/compatx-0.1.8.tgz",
|
||||
"integrity": "sha512-jcbsEAR81Bt5s1qOFymBufmCbXCXbk0Ql+K5ouj6gCyx2yHlu6AgmGIi9HxfKixpUDO5bCFJUHQ5uM6ecbTebw=="
|
||||
},
|
||||
"compressorjs": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/compressorjs/-/compressorjs-1.2.1.tgz",
|
||||
"integrity": "sha512-+geIjeRnPhQ+LLvvA7wxBQE5ddeLU7pJ3FsKFWirDw6veY3s9iLxAQEw7lXGHnhCJvBujEQWuNnGzZcvCvdkLQ==",
|
||||
"requires": {
|
||||
"blueimp-canvas-to-blob": "^3.29.0",
|
||||
"is-blob": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"compute-scroll-into-view": {
|
||||
"version": "1.0.20",
|
||||
"resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
|
||||
|
@ -1469,6 +1492,11 @@
|
|||
"is-what": "^3.14.1"
|
||||
}
|
||||
},
|
||||
"core-js-pure": {
|
||||
"version": "3.41.0",
|
||||
"resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.41.0.tgz",
|
||||
"integrity": "sha512-71Gzp96T9YPk63aUvE5Q5qP+DryB4ZloUZPSOebGM88VNw8VNfvdA7z6kGA8iGOTEzAomsRidp4jXSmUIJsL+Q=="
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
|
@ -1934,6 +1962,11 @@
|
|||
"binary-extensions": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-blob": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-blob/-/is-blob-2.1.0.tgz",
|
||||
"integrity": "sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw=="
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
|
@ -2385,6 +2418,11 @@
|
|||
"mimic-fn": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"pako": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz",
|
||||
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
|
||||
},
|
||||
"parse-node-version": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
|
||||
|
@ -2644,6 +2682,16 @@
|
|||
"integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
|
||||
"dev": true
|
||||
},
|
||||
"shrinkpng": {
|
||||
"version": "1.2.0-beta.1",
|
||||
"resolved": "https://registry.npmmirror.com/shrinkpng/-/shrinkpng-1.2.0-beta.1.tgz",
|
||||
"integrity": "sha512-14B3Na+thQHyXkz1cMXKcMQ/mYBCJFWck1Z5z3NzmQqF5x712vuM9WWt2g/2V6/+ZYUA40FQLyNl6Q9TcffdEw==",
|
||||
"requires": {
|
||||
"@babel/runtime-corejs3": "^7.18.3",
|
||||
"pako": "^2.0.4",
|
||||
"uzip": "^0.20201231.0"
|
||||
}
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
|
@ -2876,6 +2924,11 @@
|
|||
"picocolors": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"uzip": {
|
||||
"version": "0.20201231.0",
|
||||
"resolved": "https://registry.npmmirror.com/uzip/-/uzip-0.20201231.0.tgz",
|
||||
"integrity": "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng=="
|
||||
},
|
||||
"vite": {
|
||||
"version": "5.4.10",
|
||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.10.tgz",
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"axios": "^1.7.2",
|
||||
"compressorjs": "^1.2.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"element-plus": "^2.9.0",
|
||||
"mitt": "^3.0.1",
|
||||
"pinia": "^2.0.35",
|
||||
"pinia-plugin-persistedstate": "^4.1.2",
|
||||
"querystring": "^0.2.1",
|
||||
"shrinkpng": "^1.2.0-beta.1",
|
||||
"vue": "^3.2.31",
|
||||
"vue-router": "^4.3.3"
|
||||
},
|
||||
|
|
15
src/App.vue
15
src/App.vue
|
@ -33,15 +33,14 @@ const checkLoginState = async ()=>{ //监测登陆状态
|
|||
|
||||
|
||||
<style scoped>
|
||||
html{
|
||||
padding:0;
|
||||
margin: 0;
|
||||
}
|
||||
body{
|
||||
html {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
min-width: 1200px;
|
||||
}
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
<template>
|
||||
<el-container >
|
||||
|
||||
<div class="layout">
|
||||
<el-container style="height: 100%">
|
||||
<!-- 侧边栏-->
|
||||
<Aside/>
|
||||
|
||||
<!-- 主体-->
|
||||
<el-container>
|
||||
<!-- 头部-->
|
||||
<el-header style="font-size: 12px; border-bottom:2px solid #ccc; line-height: 60px; height: 70px;">
|
||||
<el-header style="font-size: 12px; border-bottom:2px solid #ccc; line-height: 60px; height: 70px;min-width: 500px;">
|
||||
<Header/>
|
||||
</el-header>
|
||||
<!-- 身体-->
|
||||
|
@ -17,6 +16,7 @@
|
|||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -29,5 +29,9 @@ import Header from "@/layout/components/Header.vue";
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.layout {
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<el-aside :width="sideWidth + 'px'" style="max-height: 200vh; min-height: 100vh; position: sticky; bottom: 0; left: 0; height: auto; background-color: rgb(170, 113, 81); box-shadow: rgba(0, 21, 155, 0.35) 2px 0 6px" >
|
||||
<el-aside :style="AsideObj">
|
||||
<el-aside :style="AsideObj" >
|
||||
<el-menu
|
||||
background-color="rgb(170, 113, 81)"
|
||||
:collapse="isCollapse"
|
||||
|
@ -10,6 +9,7 @@
|
|||
:default-active="currentRoute"
|
||||
active-text-color="#ffd04b"
|
||||
unique-opened
|
||||
style="height: 100%;overflow-y: scroll;overflow-y: auto;"
|
||||
>
|
||||
<div style="height: 80px; color: white; font-weight: bold;
|
||||
display: flex; align-items: center; justify-content: center">
|
||||
|
@ -62,7 +62,6 @@
|
|||
</template>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
</el-aside>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
@ -183,13 +182,4 @@ const menuRoutes = computed(() => {
|
|||
|
||||
</script>
|
||||
<style scoped>
|
||||
.is-active {
|
||||
color: #ffd04b;
|
||||
}
|
||||
.no-active {
|
||||
color: #ffffff;
|
||||
}
|
||||
.el-menu--horizontal {
|
||||
--el-menu-horizontal-height: 2000px;
|
||||
}
|
||||
</style>
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<div style="position: absolute; right: 40px; display: flex; justify-content: center; align-items: center;">
|
||||
<el-avatar style="margin-right: 10px">
|
||||
<img :src="userInfo.userAvatar" alt="">
|
||||
<img :src="downloadUrl + userInfo.userAvatar" alt="">
|
||||
</el-avatar>
|
||||
|
||||
<el-dropdown style="cursor: pointer;" size="default">
|
||||
|
@ -35,13 +35,15 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import emitter from '@/utils/emitter'
|
||||
import { useRouter } from "vue-router";
|
||||
import myAxios from '@/api/myAxios';
|
||||
import { userStore } from '@/store/userStore';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import Breadcrumb from './Breadcrumb.vue';
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const router = useRouter();
|
||||
const offset = ref(20)
|
||||
const showLog = ref(false)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div style="border: 1px solid #ccc">
|
||||
<Toolbar style="border-bottom: 1px solid #ccc; width: 400px;" :editor="editorRef" :defaultConfig="toolbarConfig"
|
||||
:mode="mode" />
|
||||
<Editor style="height: 500px; overflow-y: hidden; width: 400px;" v-model="context" :value="disableRich" :defaultConfig="editorConfig"
|
||||
<Editor style="height: 500px; overflow-y: hidden; width: 400px;" v-model="valueHtml" :defaultConfig="editorConfig"
|
||||
:mode="mode" @onChange="handleChange" @onCreated="handleCreated" />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -39,7 +39,7 @@ const editorConfig = {
|
|||
}
|
||||
|
||||
editorConfig.readOnly = props.disableRich //控制富文本是否启用
|
||||
|
||||
editorConfig.autoFocus = false
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
async customUpload(file, insertFn) {
|
||||
const res = await myAxios({
|
||||
|
@ -54,7 +54,7 @@ editorConfig.MENU_CONF['uploadImage'] = {
|
|||
}
|
||||
})
|
||||
console.log('图片上传返回值--->',res.data)
|
||||
const downloadUrl = 'http://123.249.108.160:8888/api/file/downloadFile?objectKey=';
|
||||
const downloadUrl = 'https://www.carboner.cn:8888/api/file/downloadFile?objectKey=';
|
||||
insertFn(downloadUrl + res.data.data, res.alt, res.href)
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,8 @@ const handleCreated = (editor) => {
|
|||
editorRef.value = editor // 记录 editor 实例,重要!
|
||||
}
|
||||
const handleChange = (editor) => { //当选项改变时触发emit传值
|
||||
emit('richTextContent', props.context)
|
||||
// console.log(valueHtml.value)
|
||||
emit('richTextContent', valueHtml.value)
|
||||
// emit('disableChange',props.disable)
|
||||
// console.log('html',editor.getHtml());
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ export const constantRoute = [
|
|||
}
|
||||
},
|
||||
{
|
||||
path: '/ManagementCenter',
|
||||
path: '/OutfitManagementCenter',
|
||||
name: '写真产品中心',
|
||||
component: () => import("@/views/CostumeAppointments/ManagementCenter.vue"),
|
||||
meta: {
|
||||
|
@ -241,6 +241,48 @@ export const constantRoute = [
|
|||
}
|
||||
]
|
||||
},
|
||||
//活动资讯管理
|
||||
{
|
||||
path: '/activityMessage',
|
||||
redirect: '/AddMessage',
|
||||
component: () => import("@/layout/Manage.vue"),
|
||||
meta: {
|
||||
title: '活动资讯管理',
|
||||
icon: '',
|
||||
hidden: false
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/AddMessage',
|
||||
name: '添加活动资讯',
|
||||
component: () => import("@/views/ActivityMessageManagement/AddMessage.vue"),
|
||||
meta: {
|
||||
title: '添加活动资讯',
|
||||
icon: 'Edit',
|
||||
hidden: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/MessageCenter',
|
||||
name: '活动资讯中心',
|
||||
component: () => import("@/views/ActivityMessageManagement/MessageCenter.vue"),
|
||||
meta: {
|
||||
title: '活动资讯中心',
|
||||
icon: '',
|
||||
hidden: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/SingleMessageDetail/:id/:flag',
|
||||
name: '资讯详情',
|
||||
component: () => import("@/views/ActivityMessageManagement/SingleMessageDetail.vue"),
|
||||
meta: {
|
||||
title: '资讯详情',
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// 优惠卷信息
|
||||
{
|
||||
path: '/coupon',
|
||||
|
@ -328,6 +370,15 @@ export const constantRoute = [
|
|||
icon: 'User',
|
||||
hidden: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/SingleUserDetail/:id/:flag',
|
||||
name: '用户详情',
|
||||
component: () => import("@/views/User/SingleUserDetail.vue"),
|
||||
meta: {
|
||||
title: '用户详情',
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
import { ref } from 'vue';
|
||||
import myAxios from '@/api/myAxios';
|
||||
import { type UploadFile, type UploadProps,type UploadUserFile} from 'element-plus';
|
||||
import { WarnInfo } from '../messageInfo';
|
||||
|
||||
export const productImgMap = new Map() //商品图片集合
|
||||
export const productImgArr: any = ref([]) //商品图片数组
|
||||
export const ImgArr: any = ref<UploadUserFile[]>([]) //给商品中心页面编辑商品使用
|
||||
export const fileSimple = ref() //单个文件
|
||||
export const form : any = ref({ //添加实体类商品的表单
|
||||
name: '', //商品名称
|
||||
price: '', //商品价格
|
||||
intro: '',//产品简介
|
||||
festivalName: '', //节日名称
|
||||
type: '',//类别
|
||||
label: '',//商品标签
|
||||
// introDetail: '',//详情描述
|
||||
goodImg: '', //商品图片url
|
||||
// detailImg: '', //图文详情url
|
||||
inventory: '', //库存
|
||||
richText: ''
|
||||
})
|
||||
export const editForm: any = ref({}) //编辑后的实体类商品表格
|
||||
|
||||
//图片上传请求 此请求只要选择了图片,就会默认上传
|
||||
export const handleChange = async (file: any, flag: number ) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
// 取出formData对象中的file
|
||||
file: formData.get("file")
|
||||
}
|
||||
})
|
||||
// console.log('图片上传的结果--->',res.data)
|
||||
if (res.data.code === 1) {
|
||||
if ( flag === 2 ) {
|
||||
productImgArr.value.splice(0, productImgArr.value.length) //一并删除数组中存放的图片Url地址
|
||||
productImgMap.set(fileSimple.value.uid,res.data.data)
|
||||
productImgMap.forEach(loopMap) //将图片url插入到数组中
|
||||
form.value.goodImg = formatString()
|
||||
} else if(flag === 0 && ImgArr != null) {
|
||||
dealImgArr(ImgArr.value) //先处理
|
||||
productImgMap.set(fileSimple.value.uid,res.data.data)
|
||||
productImgMap.forEach(loopMap) //将图片url插入到数组中
|
||||
pushImgArr(productImgArr.value)
|
||||
editForm.value.goodImg = formatString()
|
||||
productImgMap.clear() //清除所有的键,防止bug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const formatString = () => { //拼接图片URL,方便传给后端
|
||||
var str = ''
|
||||
str = productImgArr.value.join(';')
|
||||
return str
|
||||
}
|
||||
|
||||
const loopMap = (value: any, key: any, map: any) => { //循环商品图片Map集合函数,用于给请求的字段赋值
|
||||
productImgArr.value.push(value)
|
||||
}
|
||||
|
||||
const pushImgArr = (arr: any) =>{
|
||||
ImgArr.value.splice(0, ImgArr.value.length) //先清空,防止之前的
|
||||
arr.forEach((item:any)=>{
|
||||
ImgArr.value.push({
|
||||
url: item
|
||||
})
|
||||
})
|
||||
console.log('处理完之后的图片数组--->',ImgArr.value);
|
||||
}
|
||||
|
||||
const dealImgArr = (obj: any) =>{ //处理商品图片数组对象
|
||||
productImgArr.value.splice(0, productImgArr.value.length) //防止数组越界
|
||||
console.log('商品图片对象--->',obj);
|
||||
obj.forEach((item: any)=>{
|
||||
if(item.status === 'success') {
|
||||
productImgArr.value.push(item.url) //赋值给商品图片数组
|
||||
}
|
||||
})
|
||||
ImgArr.value.splice(0,ImgArr.value.length)
|
||||
}
|
||||
//针对添加商品的删除图片
|
||||
export const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFile表示当前删除的图片,uploadFiles是还剩余的图片信息
|
||||
productImgMap.delete(uploadFile.uid)
|
||||
productImgArr.value.splice(0, productImgArr.value.length) //一并删除数组中存放的图片Url地址
|
||||
productImgMap.forEach(loopMap)
|
||||
form.value.goodImg = formatString()
|
||||
}
|
||||
|
||||
export const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('最多只能上传七张图片!')
|
||||
}
|
||||
//针对的是商品中心编辑按钮的删除
|
||||
export const removePic : UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFile表示当前删除的图片,uploadFiles是还剩余的图片信息
|
||||
ImgArr.value = ImgArr.value.filter((item:any)=>{
|
||||
return uploadFile.url !== item.url
|
||||
})
|
||||
console.log(ImgArr.value);
|
||||
dealImgArr(ImgArr.value)
|
||||
pushImgArr(productImgArr.value)
|
||||
editForm.value.goodImg = formatString()
|
||||
}
|
4
src/utils/formatImgUpload.ts
Normal file
4
src/utils/formatImgUpload.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
//上传链接
|
||||
export const uploadUrl : string = 'http://localhost:9092/api/file/uploadFile'
|
||||
// export const uploadUrl = 'https://www.carboner.cn:8888/api/file/uploadFile'
|
||||
export const downloadUrl : string = 'https://www.carboner.cn:8888/api/file/downloadFile?objectKey='
|
116
src/utils/imgUpload/ImgListUpload.vue
Normal file
116
src/utils/imgUpload/ImgListUpload.vue
Normal file
|
@ -0,0 +1,116 @@
|
|||
<template>
|
||||
<!-- 批量图片上传 -->
|
||||
<el-upload
|
||||
v-model:file-list="ImgList"
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="ExceedImg"
|
||||
:http-request="compressImage"
|
||||
limit="7"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<el-image :src="dialogImageUrl"/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import myAxios from '@/api/myAxios'
|
||||
import { ref,defineEmits,watch } from 'vue'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import type { UploadProps } from 'element-plus'
|
||||
import { uploadUrl } from '@/utils/formatImgUpload'
|
||||
import { WarnInfo } from "@/utils/messageInfo";
|
||||
import Compressor from "compressorjs";
|
||||
|
||||
const goodImgStr = ref('') //图片字符串
|
||||
const goodImgArr= ref<String[]>([]) //后端数据库返回的图片objectKey
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const loading = ref(false)
|
||||
const ImgList: any = ref([])
|
||||
const emit = defineEmits<Emits>() //向父组件传递数据
|
||||
|
||||
interface Emits {
|
||||
(event: 'update:goodImgArr' , newVal: string): void
|
||||
}
|
||||
|
||||
const compressImage =(file: any)=> { //图片压缩方法
|
||||
// console.log('compressImage',file)
|
||||
return new Promise((resolve, reject) => {
|
||||
new Compressor(file.file, {
|
||||
quality: 0.3, //压缩质量,越高文件越大
|
||||
success(result) {
|
||||
console.log('res--->',result)
|
||||
// 压缩成功后的处理
|
||||
const compressedFile = new File([result], file.file.name, { type: result.type });
|
||||
// 可以在这里预览、上传或者做其他处理
|
||||
console.log("Compressed file:", compressedFile);
|
||||
// 如果需要上传,可以在这里执行上传操作
|
||||
customUpload(compressedFile)
|
||||
// resolve(compressedFile);
|
||||
},
|
||||
error(err) {
|
||||
reject("压缩失败");
|
||||
console.log("Compressor error:", err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //前者是删掉的,后者是删掉后得数组
|
||||
// console.log(uploadFile)
|
||||
// let deleteObjKey = uploadFile.url?.substring(downloadUrl.length)
|
||||
// console.log('格式化后的数组--->',deleteObjKey)
|
||||
goodImgArr.value = goodImgArr.value.filter((item)=>{ //根据相同文件名过滤掉已删掉的
|
||||
return !item.includes(replaceSpecialChars(uploadFile.name))
|
||||
})
|
||||
goodImgStr.value = goodImgArr.value.join(';')
|
||||
}
|
||||
|
||||
const replaceSpecialChars = (input : any) => { //上传文件后一些特殊字符(+、&)会替换为下划线,文件名也要替换
|
||||
// 使用正则表达式替换非中文、字母、数字和点号的字符为下划线
|
||||
return input.replace(/[^a-zA-Z0-9\u4e00-\u9fa5.]/g, '_');
|
||||
}
|
||||
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const ExceedImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('最多只能上传七张图片!')
|
||||
}
|
||||
|
||||
//图片上传方法
|
||||
const customUpload = async (file:any) => {
|
||||
loading.value = true
|
||||
const res = await myAxios({
|
||||
url: uploadUrl,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: file
|
||||
}
|
||||
})
|
||||
// console.log('图片上传结果--->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
goodImgStr.value = ''
|
||||
goodImgArr.value.push(res.data.data)
|
||||
goodImgStr.value = goodImgArr.value.join(';')
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(goodImgStr, (newVal:any) => {
|
||||
emit('update:goodImgArr', newVal)
|
||||
// console.log('监听的新变化--->',newVal)
|
||||
})
|
||||
</script>
|
103
src/utils/imgUpload/ImgSingleUpload.vue
Normal file
103
src/utils/imgUpload/ImgSingleUpload.vue
Normal file
|
@ -0,0 +1,103 @@
|
|||
<template>
|
||||
<!-- 批量图片上传 -->
|
||||
<el-upload
|
||||
v-model:file-list="ImgList"
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
:http-request="compressImage"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="ExceedImg"
|
||||
limit="1"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<el-image :src="dialogImageUrl"/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import myAxios from '@/api/myAxios'
|
||||
import { ref,defineEmits,watch } from 'vue'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import type { UploadProps } from 'element-plus'
|
||||
import { uploadUrl } from '@/utils/formatImgUpload'
|
||||
import { WarnInfo } from "@/utils/messageInfo";
|
||||
import Compressor from "compressorjs";
|
||||
|
||||
const goodImgStr = ref('') //图片字符串
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const loading = ref(false)
|
||||
const ImgList: any = ref([])
|
||||
const emit = defineEmits<Emits>() //向父组件传递数据
|
||||
|
||||
interface Emits {
|
||||
(event: 'update:goodImgArr' , newVal: string): void
|
||||
}
|
||||
|
||||
|
||||
const compressImage =(file: any)=> { //图片压缩方法
|
||||
// console.log('compressImage',file)
|
||||
return new Promise((resolve, reject) => {
|
||||
new Compressor(file.file, {
|
||||
quality: 0.3, //压缩质量,越高文件越大
|
||||
success(result) {
|
||||
console.log('res--->',result)
|
||||
// 压缩成功后的处理
|
||||
const compressedFile = new File([result], file.file.name, { type: result.type });
|
||||
// 可以在这里预览、上传或者做其他处理
|
||||
// console.log("Compressed file:", compressedFile);
|
||||
// 如果需要上传,可以在这里执行上传操作
|
||||
customUpload(compressedFile)
|
||||
// resolve(compressedFile);
|
||||
},
|
||||
error(err) {
|
||||
reject("压缩失败");
|
||||
console.log("Compressor error:", err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //前者是删掉的,后者是删掉后得数组
|
||||
goodImgStr.value = ''
|
||||
}
|
||||
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const ExceedImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('请删掉后再上传')
|
||||
}
|
||||
|
||||
//图片上传方法
|
||||
const customUpload = async (file:any) => {
|
||||
loading.value = true
|
||||
const res = await myAxios({
|
||||
url: uploadUrl,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: file
|
||||
}
|
||||
})
|
||||
console.log('图片上传--->',res)
|
||||
if(res.data.code === 1) {
|
||||
goodImgStr.value = res.data.data
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(goodImgStr, (newVal:any) => {
|
||||
emit('update:goodImgArr', newVal)
|
||||
})
|
||||
</script>
|
148
src/utils/imgUpload/PreviewImgUpload.vue
Normal file
148
src/utils/imgUpload/PreviewImgUpload.vue
Normal file
|
@ -0,0 +1,148 @@
|
|||
<template>
|
||||
<el-upload
|
||||
v-model:file-list="ImgList"
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
:http-request="compressImage"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="ExceedImg"
|
||||
limit="7"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<el-image :src="dialogImageUrl"/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import myAxios from '@/api/myAxios'
|
||||
import { ref,defineEmits,defineProps,watch,onUpdated } from 'vue'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import type { UploadProps } from 'element-plus'
|
||||
import { uploadUrl, downloadUrl } from '@/utils/formatImgUpload'
|
||||
import { WarnInfo } from "@/utils/messageInfo";
|
||||
import Compressor from "compressorjs";
|
||||
|
||||
const goodImgStr = ref('') //图片字符串
|
||||
const goodImgArr= ref<String[]>([]) //后端数据库返回的图片objectKey
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const loading = ref(false)
|
||||
const emit = defineEmits<Emits>()
|
||||
const props = defineProps<Props>() //接收父组件传来的props
|
||||
const previwUrl = ref('')
|
||||
const flag = ref(0)
|
||||
|
||||
|
||||
interface Emits {
|
||||
(event: 'update:goodImgArr' , newVal: string): void
|
||||
}
|
||||
|
||||
interface Props {
|
||||
ImgUrlList: string;
|
||||
}
|
||||
|
||||
onUpdated(()=>{ //组件数据更新后调用
|
||||
if(flag.value === 0){
|
||||
formatImgUrlList()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const compressImage =(file: any)=> { //图片压缩方法
|
||||
// console.log('compressImage',file)
|
||||
return new Promise((resolve, reject) => {
|
||||
new Compressor(file.file, {
|
||||
quality: 0.3, //压缩质量,越高文件越大
|
||||
success(result) {
|
||||
console.log('res--->',result)
|
||||
// 压缩成功后的处理
|
||||
const compressedFile = new File([result], file.file.name, { type: result.type });
|
||||
// 可以在这里预览、上传或者做其他处理
|
||||
// console.log("Compressed file:", compressedFile);
|
||||
// 如果需要上传,可以在这里执行上传操作
|
||||
customUpload(compressedFile)
|
||||
// resolve(compressedFile);
|
||||
},
|
||||
error(err) {
|
||||
reject("压缩失败");
|
||||
console.log("Compressor error:", err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const formatImgUrlList = () => { //回显多张图片
|
||||
flag.value = 1
|
||||
goodImgArr.value = previwUrl.value.split(';')
|
||||
// console.log('分号隔开的数组--->',goodImgArr.value)
|
||||
goodImgArr.value.forEach(item => { //回显
|
||||
ImgList.value.push({
|
||||
url: downloadUrl + item
|
||||
})
|
||||
})
|
||||
goodImgStr.value = goodImgArr.value.join(';') //还原objectKey字符串
|
||||
}
|
||||
|
||||
const ImgList: any = ref([])
|
||||
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //前者是删掉的,后者是删掉后得数组
|
||||
console.log(uploadFile)
|
||||
let deleteObjKey = uploadFile.url?.substring(downloadUrl.length)
|
||||
// console.log('格式化后的数组--->',deleteObjKey)
|
||||
goodImgArr.value = goodImgArr.value.filter(item => item !== deleteObjKey)
|
||||
goodImgArr.value = goodImgArr.value.filter((item)=>{
|
||||
return !item.includes(replaceSpecialChars(uploadFile.name))
|
||||
})
|
||||
goodImgStr.value = goodImgArr.value.join(';')
|
||||
}
|
||||
|
||||
const replaceSpecialChars = (input : any) => { //上传文件后一些特殊字符(+、&)会替换为下划线,文件名也要替换
|
||||
// 使用正则表达式替换非中文、字母、数字和点号的字符为下划线
|
||||
return input.replace(/[^a-zA-Z0-9\u4e00-\u9fa5.]/g, '_');
|
||||
}
|
||||
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
|
||||
const ExceedImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('最多只能上传七张图片!')
|
||||
}
|
||||
//图片上传方法
|
||||
const customUpload = async (file:any) => {
|
||||
loading.value = true
|
||||
const res = await myAxios({
|
||||
url: uploadUrl,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: file
|
||||
}
|
||||
})
|
||||
// console.log('图片上传结果--->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
goodImgArr.value.push(res.data.data)
|
||||
goodImgStr.value = goodImgArr.value.join(';') //上传一张就更新一下goodImgStr
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(()=> props.ImgUrlList, (newVal) => {
|
||||
previwUrl.value = newVal
|
||||
})
|
||||
|
||||
watch(goodImgStr, (newVal:any) => {
|
||||
emit('update:goodImgArr', newVal)
|
||||
// console.log('变化后的goodImgStr: ', goodImgStr.value)
|
||||
})
|
||||
</script>
|
149
src/utils/imgUpload/PreviewSingleImgUpload.vue
Normal file
149
src/utils/imgUpload/PreviewSingleImgUpload.vue
Normal file
|
@ -0,0 +1,149 @@
|
|||
<template>
|
||||
<el-upload
|
||||
v-model:file-list="ImgList"
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="ExceedImg"
|
||||
:http-request="compressImage"
|
||||
limit="1"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<el-image :src="dialogImageUrl"/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import myAxios from '@/api/myAxios'
|
||||
import { ref,defineEmits,defineProps,watch,onUpdated } from 'vue'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import type { UploadProps } from 'element-plus'
|
||||
import { uploadUrl, downloadUrl } from '@/utils/formatImgUpload'
|
||||
import { WarnInfo } from "@/utils/messageInfo";
|
||||
import Compressor from "compressorjs";
|
||||
|
||||
const goodImgStr = ref('') //图片字符串
|
||||
const goodImgArr= ref<String[]>([]) //后端数据库返回的图片objectKey
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const loading = ref(false)
|
||||
const emit = defineEmits<Emits>()
|
||||
const props = defineProps<Props>() //接收父组件传来的props
|
||||
const previwUrl = ref('')
|
||||
const flag = ref(0)
|
||||
|
||||
interface Emits {
|
||||
(event: 'update:goodImgArr' , newVal: string): void
|
||||
}
|
||||
|
||||
interface Props {
|
||||
ImgUrlList: string;
|
||||
}
|
||||
|
||||
onUpdated(()=>{ //组件数据更新后调用
|
||||
if(flag.value === 0) {
|
||||
formatImgUrlList()
|
||||
}
|
||||
})
|
||||
|
||||
const compressImage =(file: any)=> { //图片压缩方法
|
||||
// console.log('compressImage',file)
|
||||
return new Promise((resolve, reject) => {
|
||||
new Compressor(file.file, {
|
||||
quality: 0.3, //压缩质量,越高文件越大
|
||||
success(result) {
|
||||
console.log('res--->',result)
|
||||
// 压缩成功后的处理
|
||||
const compressedFile = new File([result], file.file.name, { type: result.type });
|
||||
// 可以在这里预览、上传或者做其他处理
|
||||
// console.log("Compressed file:", compressedFile);
|
||||
// 如果需要上传,可以在这里执行上传操作
|
||||
customUpload(compressedFile)
|
||||
// resolve(compressedFile);
|
||||
},
|
||||
error(err) {
|
||||
reject("压缩失败");
|
||||
console.log("Compressor error:", err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const formatImgUrlList = () => { //回显多张图片
|
||||
flag.value = 1
|
||||
goodImgArr.value = previwUrl.value.split(';')
|
||||
console.log('分号隔开的数组--->',goodImgArr.value)
|
||||
goodImgArr.value.forEach(item => { //回显
|
||||
ImgList.value.push({
|
||||
url: downloadUrl + item
|
||||
})
|
||||
})
|
||||
goodImgStr.value = goodImgArr.value.join(';') //还原objectKey字符串
|
||||
}
|
||||
|
||||
const ImgList: any = ref([])
|
||||
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //前者是删掉的,后者是删掉后得数组
|
||||
console.log(uploadFile)
|
||||
let deleteObjKey = uploadFile.url?.substring(downloadUrl.length)
|
||||
goodImgArr.value = goodImgArr.value.filter(item => item !== deleteObjKey)
|
||||
goodImgArr.value = goodImgArr.value.filter((item)=>{
|
||||
return !item.includes(replaceSpecialChars(uploadFile.name))
|
||||
})
|
||||
goodImgStr.value = goodImgArr.value.join(';')
|
||||
}
|
||||
|
||||
const replaceSpecialChars = (input : any) => { //上传文件后一些特殊字符(+、&)会替换为下划线,文件名也要替换
|
||||
// 使用正则表达式替换非中文、字母、数字和点号的字符为下划线
|
||||
return input.replace(/[^a-zA-Z0-9\u4e00-\u9fa5.]/g, '_');
|
||||
}
|
||||
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
|
||||
const ExceedImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('请删除之前的再上传')
|
||||
}
|
||||
|
||||
//图片上传方法
|
||||
const customUpload = async (file:any) => {
|
||||
loading.value = true
|
||||
const res = await myAxios({
|
||||
url: uploadUrl,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: file
|
||||
}
|
||||
})
|
||||
// console.log('图片上传结果--->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
goodImgArr.value.push(res.data.data)
|
||||
goodImgStr.value = goodImgArr.value.join(';') //上传一张就更新一下goodImgStr
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(()=> props.ImgUrlList, (newVal) => {
|
||||
previwUrl.value = ''
|
||||
previwUrl.value = newVal
|
||||
// formatImgUrlList()
|
||||
// console.log('变化后的previewUrl--->', previwUrl.value)
|
||||
})
|
||||
|
||||
watch(goodImgStr, (newVal:any) => {
|
||||
emit('update:goodImgArr', newVal)
|
||||
// console.log('变化后的goodImgStr: ', goodImgStr.value)
|
||||
})
|
||||
</script>
|
123
src/views/ActivityMessageManagement/AddMessage.vue
Normal file
123
src/views/ActivityMessageManagement/AddMessage.vue
Normal file
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<div class="flexCard">
|
||||
<!-- 表单 ref 和 prop绑定 用于重置表单 -->
|
||||
<el-card class="form-container" shadow="never" >
|
||||
<div class="form">
|
||||
<el-form ref="resetFormData" :model="form" label-width="auto" size="large" >
|
||||
<div>
|
||||
<el-form-item label="添加活动图片">
|
||||
<ImgSingleUpload @update:goodImgArr="form.image = $event"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="资讯标题">
|
||||
<el-input v-model="form.title" maxlength="12" minlength="2" show-word-limit style="width: 260px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="文章发布时间">
|
||||
<el-date-picker
|
||||
v-model="form.publishTime"
|
||||
type="date"
|
||||
placeholder="选择发布日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled-date="disabledDate"
|
||||
size="large"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="公众号链接">
|
||||
<el-input v-model="form.url" show-word-limit style="width: 260px;" />
|
||||
</el-form-item>
|
||||
<div class="btnBox">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="saveBtn">保存</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, inject } from 'vue';
|
||||
import { SuccessInfo, WarnInfo, CommInfo } from '@/utils/messageInfo'; //封装ElMessage提示
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { saveBtn, invInput } from '@/utils/entityProduct/globalVar';
|
||||
import ImgSingleUpload from "@/utils/imgUpload/ImgSingleUpload.vue";
|
||||
|
||||
|
||||
const resetFormData = ref()
|
||||
const reload: any = inject("reload") //导入组件刷新
|
||||
const form : any = ref({ //添加实体类商品的表单
|
||||
title: '',
|
||||
image: '',
|
||||
publishTime: '',
|
||||
url: '',
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
const disabledDate = (time : any ) => {
|
||||
// console.log('time---->',time.getTime())
|
||||
return time.getTime() > Date.now()
|
||||
}
|
||||
|
||||
//提交表单
|
||||
const onSubmit = async () => {
|
||||
console.log('表单--->',form.value)
|
||||
const values = Object.values(form.value );
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
if (values.some((value: any) => value === null || value === undefined || value === '' )) {
|
||||
WarnInfo('请检查表单数据是否完整填写')
|
||||
return; //空返回结束函数
|
||||
}
|
||||
const res = await myAxios.post('/article/add', {
|
||||
title: form.value.title,
|
||||
image: form.value.image,
|
||||
publishTime: form.value.publishTime.replace(/(.+?)\-(.+?)\-(.+)/,"$1年$2月$3日"),
|
||||
url: form.value.url
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
SuccessInfo('提交成功')
|
||||
form.value = {} //12.18改
|
||||
reload() //上传完后重置表单
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//清除表单
|
||||
const resetForm = () => {
|
||||
resetFormData.value.resetFields()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.flexCard {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
min-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
.form-container {
|
||||
width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form {
|
||||
/* width: 500px; */
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
.btnBox {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
</style>
|
178
src/views/ActivityMessageManagement/MessageCenter.vue
Normal file
178
src/views/ActivityMessageManagement/MessageCenter.vue
Normal file
|
@ -0,0 +1,178 @@
|
|||
<template>
|
||||
<!-- 修改前请注释以前的 -->
|
||||
<!-- 搜索 -->
|
||||
<div class="table_page">
|
||||
<div>
|
||||
<el-input style="width: 240px; margin-right: 10px;" suffix-icon="Search" placeholder="资讯名称" size="default"
|
||||
v-model="productName"></el-input>
|
||||
<el-button type="primary" @click="" style="margin-right: 10px;" size="default">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button type="warning" @click="reset" size="default">重置</el-button>
|
||||
</div>
|
||||
<!-- 批量删除 -->
|
||||
<!-- <div style="margin: 15px 0">-->
|
||||
<!-- <el-popconfirm class="ml-5" confirm-button-text='确定' cancel-button-text='取消' icon="InfoFilled" icon-color="red"-->
|
||||
<!-- title="您确定批量删除这些数据吗?" @confirm="delBatch" width=180>-->
|
||||
<!-- <template #reference>-->
|
||||
<!-- <el-button style="height: 25px" class="ml-5" type="danger">批量删除-->
|
||||
<!-- <el-icon style="margin-left: 5px;">-->
|
||||
<!-- <Remove/>-->
|
||||
<!-- </el-icon>-->
|
||||
<!-- </el-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-popconfirm>-->
|
||||
<!-- </div>-->
|
||||
<!-- 数据展示 -->
|
||||
<el-table :data="tableData" border stripe header-cell-class-name="headerBg"
|
||||
:cell-style="{ 'text-align': 'center', 'font-size': '16px' }" @selection-change="handleSelectionChange"
|
||||
@select="selectChange"
|
||||
:header-cell-style="{ 'text-align': 'center' }">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="id" label="编号" width="80">
|
||||
<template #default="{ $index }">
|
||||
{{ $index + 1 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="title" label="标题"></el-table-column>
|
||||
<el-table-column prop="image" label="预览图" width="200">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<img :src="downloadUrl + scope.row.image" alt="" style="height: 50px;">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="publishTime" label="发布时间" width="150"></el-table-column>
|
||||
<el-table-column label="操作" width="230px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="ReviseOrView(scope.row , 0)">
|
||||
详情
|
||||
</el-button>
|
||||
<el-button size="small" @click="ReviseOrView(scope.row, 1)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-popconfirm class="ml-5" confirm-button-text='确定' cancel-button-text='取消' icon="InfoFilled"
|
||||
icon-color="red"
|
||||
title="是否确认删除" @confirm="deleteMessage(scope.row.id)" width=180>
|
||||
<template #reference>
|
||||
<el-button class="ml-5" type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页器 -->
|
||||
<div style="padding: 10px 0">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
:current-page="searchParams.current" :page-size="searchParams.pageSize" :page-sizes="[5, 10, 15, 20]"
|
||||
:small="null" :disabled="null" :background="null" layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage } from 'element-plus';
|
||||
import {ref, onMounted, inject} from 'vue';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { useRouter } from "vue-router";
|
||||
import {downloadUrl} from '@/utils/formatImgUpload'
|
||||
|
||||
const router = useRouter(); //路由
|
||||
const total = ref(0); //总页数
|
||||
const idList = ref<Number[]>([]);
|
||||
const searchParams: any = ref({ //封装分页
|
||||
current: 1, //当前页码
|
||||
pageSize: 5, //每页显示条数
|
||||
sortField: "id", //根据ID分类
|
||||
sortOrder: "descend" //降序
|
||||
})
|
||||
const productName = ref('');
|
||||
const tableData: any = ref([]); //实体类商品表格
|
||||
const reload: any = inject("reload") //页面重新刷新
|
||||
|
||||
onMounted(() => { //页面加载时获取商品列表和分类页表
|
||||
getMessageList()
|
||||
})
|
||||
const getMessageList = async () => {
|
||||
try {
|
||||
const res = await myAxios.post('/article/query/web', {...searchParams.value});
|
||||
console.log('资讯表格--->', res.data)
|
||||
if (res.data.code === 1) {
|
||||
tableData.value = res.data.data.records;
|
||||
total.value = parseInt(res.data.data.total) //总数据量,用于分页
|
||||
} else {
|
||||
ElMessage({
|
||||
message: '获取数据失败',
|
||||
});
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage({
|
||||
message: '发生错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//删除活动信息
|
||||
const deleteMessage = async (index: number) => {
|
||||
console.log(typeof index)
|
||||
const res = await myAxios.post('/article/delete', {id: index})
|
||||
console.log(res)
|
||||
if (res.data.code === 1) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '删除成功',
|
||||
})
|
||||
await getMessageList()
|
||||
}
|
||||
}
|
||||
|
||||
//详情或编辑
|
||||
const ReviseOrView = ( row: any, flag: number) => {
|
||||
router.push({
|
||||
name: '资讯详情',
|
||||
params: {
|
||||
id: row.id,
|
||||
flag: flag
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//处理行数大小变化
|
||||
const handleSizeChange = (newSize: any) => {
|
||||
searchParams.value.pageSize = newSize //新的页面数
|
||||
getMessageList()
|
||||
}
|
||||
//处理当前表格变化
|
||||
const handleCurrentChange = (Current: any) => {
|
||||
searchParams.value.current = Current
|
||||
getMessageList()
|
||||
}
|
||||
//重置按钮
|
||||
const reset = () => {
|
||||
reload()
|
||||
};
|
||||
|
||||
|
||||
|
||||
const handleSelectionChange = () => {
|
||||
}
|
||||
const selectChange = (selection: any, row: any) => { //selction是对象数组,row是当前行对象
|
||||
idList.value.splice(0, idList.value.length) //删掉
|
||||
selection.forEach((item: any) => {
|
||||
idList.value.push(item.id)
|
||||
})
|
||||
// console.log('idList--->',idList.value);
|
||||
}
|
||||
|
||||
//查询
|
||||
const onSearch = (value: string) => {}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table_page {
|
||||
min-width: 800px;
|
||||
}
|
||||
|
||||
</style>
|
139
src/views/ActivityMessageManagement/SingleMessageDetail.vue
Normal file
139
src/views/ActivityMessageManagement/SingleMessageDetail.vue
Normal file
|
@ -0,0 +1,139 @@
|
|||
<template>
|
||||
<div class="flexCard">
|
||||
<!-- 表单 ref 和 prop绑定 用于重置表单 -->
|
||||
<el-card class="form-container" shadow="never" >
|
||||
<div class="form">
|
||||
<el-form ref="resetFormData" :model="form" label-width="auto" size="large" :disabled="disabled">
|
||||
<div>
|
||||
<el-form-item label="添加活动图片">
|
||||
<PreviewSingleImgUpload :ImgUrlList="form.image" @update:goodImgArr="form.image = $event"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="资讯标题">
|
||||
<el-input v-model="form.title" maxlength="30" minlength="2" show-word-limit style="width: 260px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="文章发布时间">
|
||||
<el-date-picker
|
||||
v-model="form.publishTime"
|
||||
type="date"
|
||||
placeholder="选择发布日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled-date="disabledDate"
|
||||
size="large"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="公众号链接">
|
||||
<el-input v-model="form.url" style="width: 260px;" />
|
||||
</el-form-item>
|
||||
<div class="btnBox">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="saveBtn">保存</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { SuccessInfo, WarnInfo, CommInfo } from '@/utils/messageInfo'; //封装ElMessage提示
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { saveBtn } from '@/utils/entityProduct/globalVar';
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import PreviewSingleImgUpload from "@/utils/imgUpload/PreviewSingleImgUpload.vue";
|
||||
|
||||
|
||||
const route = useRoute();
|
||||
const resetFormData = ref()
|
||||
const form : any = ref({ //添加实体类商品的表单
|
||||
title: '',
|
||||
image: '',
|
||||
publishTime: '',
|
||||
url: '',
|
||||
})
|
||||
const disabled = ref(true)
|
||||
const router = useRouter();
|
||||
|
||||
onMounted(() => {
|
||||
getMessageInfo()
|
||||
if(route.params.flag === '1') {
|
||||
disabled.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const getMessageInfo = async () =>{
|
||||
const res = await myAxios.post('/article/query/id', { id: route.params.id });
|
||||
console.log('后端返回的信息--->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
form.value = res.data.data
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
}
|
||||
}
|
||||
const disabledDate = (time : any ) => {
|
||||
// console.log('time---->',time.getTime())
|
||||
return time.getTime() > Date.now()
|
||||
}
|
||||
|
||||
//提交表单
|
||||
const onSubmit = async () => {
|
||||
// console.log('表单--->',form.value)
|
||||
const values = Object.values(form.value );
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
if (values.some((value: any) => value === null || value === undefined || value === '' )) {
|
||||
WarnInfo('请检查表单数据是否完整填写')
|
||||
return; //空返回结束函数
|
||||
}
|
||||
const res = await myAxios.post('/article/update', {
|
||||
id: form.value.id,
|
||||
title: form.value.title,
|
||||
image: form.value.image,
|
||||
publishTime: form.value.publishTime.replace(/(.+?)\-(.+?)\-(.+)/,"$1年$2月$3日"),
|
||||
url: form.value.url
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
SuccessInfo('提交成功')
|
||||
router.replace('/MessageCenter')
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//清除表单
|
||||
const resetForm = () => {
|
||||
resetFormData.value.resetFields()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.flexCard {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
min-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
.form-container {
|
||||
width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form {
|
||||
/* width: 500px; */
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
.btnBox {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -7,24 +7,17 @@
|
|||
<!-- 表单 ref 和 prop绑定 用于重置表单 -->
|
||||
<el-card class="form-container" shadow="never">
|
||||
<div class="form">
|
||||
<el-form ref="resetFormData" :model="form" label-width="auto" size="large" :rules="rules">
|
||||
<el-form ref="resetFormData" :model="form" size="large" :rules="rules">
|
||||
<div>
|
||||
<el-form-item label="添加商品图片">
|
||||
<!-- 下面的event的作用,传入当前事件对象 -->
|
||||
<el-upload ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 2)" :on-exceed="Exceed_ProductImg"
|
||||
limit="7">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<ImgListUpload @update:goodImgArr="form.goodImg = $event"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="NamePrice">
|
||||
<el-form-item label="产品名称" prop="name">
|
||||
<el-input v-model="form.name" maxlength="12" minlength="2" show-word-limit style="width: 260px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品价格" prop="price">
|
||||
<el-form-item label="产品价格" prop="price" label-width="100">
|
||||
<el-input-number v-model="form.price" min="0" :precision="2" :step="0.5" />
|
||||
<p>元</p>
|
||||
</el-form-item>
|
||||
|
@ -35,7 +28,7 @@
|
|||
style="width: 300px;" />
|
||||
</el-form-item>
|
||||
<div>
|
||||
<el-form-item label="库存" prop="inventory">
|
||||
<el-form-item label="库存" prop="inventory" label-width="80">
|
||||
<el-input-number v-model="form.inventory" min="0" :precision="0" :step="1" :disabled="invInput" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
@ -46,7 +39,7 @@
|
|||
<el-option v-for="item in festivalArr" :key="item" :label="item.name" :value="item.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品类别" prop="type" style="width: 240px;">
|
||||
<el-form-item label="产品类别" prop="type" style="width: 240px;" label-width="80">
|
||||
<el-select v-model="form.type" placeholder="请选择" @change="(event: any) => loadForm(event)" :disabled="typeSelect">
|
||||
<el-option v-for="item in typeList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
|
@ -60,7 +53,8 @@
|
|||
<el-input v-model="labelList[index]" type="text" style="width: 150px;" maxlength="5" show-word-limit
|
||||
@blur="addLabelList" />
|
||||
</div>
|
||||
<el-button type="primary" @click="addLabel">添加</el-button>
|
||||
<el-button type="primary" size="large" @click="addLabel">添加</el-button>
|
||||
<el-button type="danger" size="large" @click="deleteLabel" v-if="labelList.length > 1">删除</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图文" prop="richText">
|
||||
<richTextUtil @richTextContent="getInfo"/>
|
||||
|
@ -80,24 +74,38 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, inject, reactive } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import {ref, onMounted, inject, reactive, onBeforeMount} from 'vue';
|
||||
import { type FormRules } from 'element-plus';
|
||||
import { SuccessInfo, WarnInfo, CommInfo } from '@/utils/messageInfo'; //封装ElMessage提示
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { saveBtn, invInput } from '@/utils/entityProduct/globalVar';
|
||||
import { validateName, validateIntro, validateDetail } from '@/utils/entityProduct/FormRules';
|
||||
import { handleChange, handleRemove, form, Exceed_ProductImg } from '@/utils/entityProduct/picUpload';
|
||||
import richTextUtil from '@/layout/components/richTextUtil.vue';
|
||||
import ImgListUpload from '@/utils/imgUpload/ImgListUpload.vue'
|
||||
|
||||
const resetFormData = ref()
|
||||
const reload: any = inject("reload") //导入组件刷新
|
||||
const typeList: any = ref([])
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const labelList = ref([''])
|
||||
const isqualify : any = ref(false)
|
||||
const typeSelect : any = ref(false) //类别下拉选项栏的禁用状态
|
||||
const previewRichText: any = ref<String>('')
|
||||
const festivalArr : any = ref([]) //节日数组
|
||||
const form : any = ref({ //添加实体类商品的表单
|
||||
name: '', //商品名称
|
||||
price: 0, //商品价格
|
||||
intro: '',//产品简介
|
||||
festivalName: '', //节日名称
|
||||
type: '',//类别
|
||||
label: '',//商品标签
|
||||
goodImg: '', //商品图片url
|
||||
inventory: 0, //库存
|
||||
richText: ''
|
||||
})
|
||||
|
||||
onBeforeMount(()=>{
|
||||
form.value.festivalName = '无'
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getTypeList() //加载类别列表,渲染在产品列表的select选项里面
|
||||
|
@ -122,9 +130,10 @@ const getTypeList = async () => { //获取类别列表作为可选项
|
|||
}
|
||||
//提交表单
|
||||
const onSubmit = async () => {
|
||||
console.log(form.value)
|
||||
const values = Object.values(form.value );
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
if (values.some((value: any) => value === null || value === undefined || value === '' || value === 0)) {
|
||||
if (values.some((value: any) => value === null || value === undefined || value === '' || value === 0 || value === 'PHA+PGJyPjwvcD4=')) {
|
||||
WarnInfo('请检查表单数据是否完整填写')
|
||||
return; //空返回结束函数
|
||||
}
|
||||
|
@ -171,6 +180,11 @@ const addLabel = () => { //添加商品标签按钮的方法
|
|||
labelList.value.push('')
|
||||
}
|
||||
}
|
||||
|
||||
const deleteLabel = () => { //删除标签的方法
|
||||
labelList.value.pop()
|
||||
}
|
||||
|
||||
const addLabelList = () => { //格式化商品标签
|
||||
var string = ''
|
||||
if (!labelList.value.some((item: any) => item === '')) {
|
||||
|
@ -205,8 +219,8 @@ function encode64(text: string): string {
|
|||
.flexCard {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 1200px;
|
||||
overflow-x: auto;
|
||||
min-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.richTextPreview {
|
||||
|
@ -217,7 +231,9 @@ function encode64(text: string): string {
|
|||
margin-right: 10px;
|
||||
}
|
||||
.form-container {
|
||||
width: 700px;
|
||||
width: 900px;
|
||||
height: 800px;
|
||||
overflow: auto;
|
||||
/* margin: 0 auto; */
|
||||
}
|
||||
.form {
|
||||
|
@ -241,4 +257,9 @@ function encode64(text: string): string {
|
|||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.titleText {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
|
@ -11,13 +11,7 @@
|
|||
<div>
|
||||
<el-form-item label="添加商品图片">
|
||||
<!-- 下面的event的作用,传入当前事件对象 -->
|
||||
<el-upload v-model:file-list="ImgArr" ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 2)" :on-exceed="Exceed_ProductImg"
|
||||
limit="7">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<PreviewImgUpload :ImgUrlList="previewImgUrl" @update:goodImgArr="detailFrom.goodImg = $event"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="NamePrice">
|
||||
|
@ -60,9 +54,10 @@
|
|||
<el-input v-model="labelList[index]" type="text" style="width: 150px;" maxlength="5" show-word-limit
|
||||
@blur="addLabelList" />
|
||||
</div>
|
||||
<el-button type="primary" @click="addLabel">添加</el-button>
|
||||
<el-button type="primary" size="large" @click="addLabel">添加</el-button>
|
||||
<el-button type="danger" size="large" @click="deleteLabel" v-if="labelList.length > 1">删除</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图文" prop="richText">
|
||||
<el-form-item label="商品图文" prop="richText" v-loading="loading">
|
||||
<richTextUtil @richTextContent="getInfo" v-model:disableRich="disabledRichText" v-model:context="previewRichText"/>
|
||||
</el-form-item>
|
||||
<div class="btnBox">
|
||||
|
@ -80,22 +75,20 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, inject, reactive, onBeforeMount } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { ref, onMounted, reactive, onBeforeMount } from 'vue';
|
||||
import {type FormRules, type UploadUserFile} from 'element-plus';
|
||||
import { SuccessInfo, WarnInfo, CommInfo } from '@/utils/messageInfo'; //封装ElMessage提示
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { saveBtn, invInput } from '@/utils/entityProduct/globalVar';
|
||||
import { validateName, validateIntro, validateDetail } from '@/utils/entityProduct/FormRules';
|
||||
import { handleChange, handleRemove, form, Exceed_ProductImg } from '@/utils/entityProduct/picUpload';
|
||||
import richTextUtil from '@/layout/components/richTextUtil.vue';
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRoute, useRouter} from "vue-router";
|
||||
import PreviewImgUpload from '@/utils/imgUpload/PreviewImgUpload.vue'
|
||||
const router = useRouter()
|
||||
|
||||
const route = useRoute(); //路由
|
||||
const resetFormData = ref()
|
||||
const reload: any = inject("reload") //导入组件刷新
|
||||
const typeList: any = ref([])
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const labelList = ref([''])
|
||||
const isqualify : any = ref(false)
|
||||
const typeSelect : any = ref(false) //类别下拉选项栏的禁用状态
|
||||
|
@ -107,26 +100,30 @@ const detailFrom : any = ref({
|
|||
festivalName: '', //节日名称
|
||||
type: '',//类别
|
||||
label: '',//商品标签
|
||||
// introDetail: '',//详情描述
|
||||
goodImg: '', //商品图片url
|
||||
// detailImg: '', //图文详情url
|
||||
inventory: '', //库存
|
||||
richText: ''
|
||||
})
|
||||
const disabledRichText:any = ref(false);
|
||||
const previewRichText:any = ref('');
|
||||
const festivalArr : any = ref([]) //节日数组
|
||||
const previewImgUrl = ref('') //预览图字符串
|
||||
const loading = ref(true)
|
||||
|
||||
|
||||
|
||||
onBeforeMount(()=>{ //页面加载最早的生命周期
|
||||
getProductInfo() //编辑页查询商品信息
|
||||
if(route.params.flag === '0'){
|
||||
disabledRichText.value = true;
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getTypeList() //加载类别列表,渲染在产品列表的select选项里面
|
||||
getProductInfo() //编辑页查询商品信息
|
||||
getFestivalArr()
|
||||
setTimeout(()=>{ //定时器
|
||||
loading.value = false
|
||||
},1500)
|
||||
})
|
||||
|
||||
//节日信息
|
||||
|
@ -141,11 +138,13 @@ const getFestivalArr = async () => {
|
|||
|
||||
const getProductInfo = async () => { //商品信息
|
||||
const res = await myAxios.post('/goods/getById',{ id: route.params.id })
|
||||
// console.log('后端查询商品--->',res.data.data)
|
||||
console.log('后端查询商品--->',res.data.data)
|
||||
if(res.data.code === 1) {
|
||||
previewImgUrl.value = res.data.data.goodImg
|
||||
detailFrom.value = res.data.data
|
||||
previewRichText.value = JSON.parse(JSON.stringify(res.data.data.richText))
|
||||
previewRichText.value = res.data.data.richText
|
||||
ImgArr.value.splice(0, ImgArr.value.length)
|
||||
detailFrom.value.festivalName = res.data.data.festivalName.substring(0,1)
|
||||
labelList.value = res.data.data.label.split(';')
|
||||
var tempArr = res.data.data.goodImg.split(';')
|
||||
tempArr.forEach((item: any) => {
|
||||
|
@ -165,9 +164,10 @@ const getTypeList = async () => { //获取类别列表作为可选项
|
|||
|
||||
//提交表单
|
||||
const onSubmit = async () => {
|
||||
console.log('提交前的表格',detailFrom.value)
|
||||
const values = Object.values(detailFrom.value );
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
if (values.some((value: any) => value === null || value === undefined || value === '' || value === 0)) {
|
||||
if (values.some((value: any) => value === null || value === undefined || value === '' || value === 'PHA+PGJyPjwvcD4=')) {
|
||||
WarnInfo('请检查表单数据是否完整填写')
|
||||
return; //空返回结束函数
|
||||
}
|
||||
|
@ -175,8 +175,7 @@ const onSubmit = async () => {
|
|||
// console.log(res.data);
|
||||
if (res.data.code === 1) {
|
||||
SuccessInfo('提交成功')
|
||||
// detailFrom.value = {}
|
||||
// reload() //上传完后重置表单
|
||||
await router.replace('/MerchandiseCenter')
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
return;
|
||||
|
@ -190,7 +189,7 @@ const loadForm = (value: any) => {
|
|||
const resetForm = () => {
|
||||
resetFormData.value.resetFields()
|
||||
}
|
||||
const rules = reactive<FormRules<typeof form>>({ //表单校验规则
|
||||
const rules = reactive<FormRules<typeof detailFrom>>({ //表单校验规则
|
||||
name: [{ validator: validateName, trigger: 'blur' }],
|
||||
intro: [{ validator: validateIntro, trigger: 'blur' }],
|
||||
introDetail: [{ validator: validateDetail, trigger: 'blur' }]
|
||||
|
@ -204,7 +203,9 @@ const addLabel = () => { //添加商品标签按钮的方法
|
|||
labelList.value.push('')
|
||||
}
|
||||
}
|
||||
|
||||
const deleteLabel = () => { //删除标签的方法
|
||||
labelList.value.pop()
|
||||
}
|
||||
const addLabelList = () => { //格式化商品标签
|
||||
var string = ''
|
||||
if (!labelList.value.some((item: any) => item === '')) {
|
||||
|
@ -244,6 +245,7 @@ function encode64(text: string): string {
|
|||
.flexCard {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
min-width: 800px;
|
||||
}
|
||||
|
||||
.richTextPreview {
|
||||
|
@ -255,7 +257,9 @@ function encode64(text: string): string {
|
|||
}
|
||||
|
||||
.form-container {
|
||||
width: 700px;
|
||||
width: 900px;
|
||||
height: 800px;
|
||||
overflow: auto;
|
||||
/* margin: 0 auto; */
|
||||
}
|
||||
.form {
|
||||
|
@ -279,4 +283,9 @@ function encode64(text: string): string {
|
|||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.titleText {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<!-- 修改前请注释以前的 -->
|
||||
<!-- 搜索 -->
|
||||
<div class="table_page">
|
||||
<div>
|
||||
<el-input style="width: 240px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入商品名称" size="default"
|
||||
v-model="productName"></el-input>
|
||||
|
@ -44,7 +45,7 @@
|
|||
<el-table-column prop="goodImg" label="商品图片">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<img :src="scope.row.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
<img :src="downloadUrl + scope.row.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -95,15 +96,17 @@
|
|||
:small="null" :disabled="null" :background="null" layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ElMessage, type UploadProps, genFileId, type UploadRawFile} from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import {ref, onMounted, inject} from 'vue';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { editForm } from '@/utils/entityProduct/picUpload';
|
||||
import { useRouter } from "vue-router";
|
||||
import {downloadUrl} from '@/utils/formatImgUpload'
|
||||
|
||||
const editForm = ref({})
|
||||
const router = useRouter(); //路由
|
||||
const total = ref(0); //总页数
|
||||
const idList = ref<Number[]>([]);
|
||||
|
@ -117,7 +120,6 @@ const productName = ref('');
|
|||
const state = ref(''); //根据商品上架状态select栏
|
||||
const tableData: any = ref([]); //实体类商品表格
|
||||
const reload: any = inject("reload") //页面重新刷新
|
||||
const uploadProductDetail: any = ref() //图片上传的ref绑定
|
||||
const typeList: any = ref([
|
||||
{
|
||||
value1: '',
|
||||
|
@ -251,7 +253,8 @@ const onSearch = (value: string) => {}
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.headerBg {
|
||||
background-color: #eee !important;
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<div class="table_page">
|
||||
<div style="margin-bottom: 10px;">
|
||||
<el-button type="success" @click="showForm">添加类别</el-button>
|
||||
</div>
|
||||
|
@ -25,9 +26,6 @@
|
|||
<el-form-item label="类别名">
|
||||
<el-input v-model="typeForm.typeName" @input="changeInput"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="typeForm.typeIntro" @input="changeInput"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer #default="{ row, $index }">
|
||||
<div class="dialog-footer">
|
||||
|
@ -46,10 +44,9 @@
|
|||
<el-table-column prop="typeUrl" label="类别图片" width="300">
|
||||
<!-- 插槽,拿到父组件的值typeUrl -->
|
||||
<!-- scope 提供了关于当前行的信息 -->
|
||||
<template #default="scope"><img :src="scope.row.typeUrl" alt="" style="height: 50px;"></template>
|
||||
<template #default="scope"><img :src="downloadUrl + scope.row.typeUrl" alt="" style="height: 50px;"></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="typeName" label="类别名称" width="150"></el-table-column>
|
||||
<el-table-column prop="typeIntro" label="备注"></el-table-column>
|
||||
<el-table-column prop="typeName" label="类别名称"></el-table-column>
|
||||
<el-table-column prop="operation" label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="success" @click="editShowForm(scope.$index, scope.row)">修改类别</el-button>
|
||||
|
@ -64,6 +61,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -71,6 +69,7 @@ import {ElMessage, type UploadProps, type UploadUserFile,type UploadFile, genFil
|
|||
import {ErrorInfo, SuccessInfo} from '@/utils/messageInfo';
|
||||
import {onMounted, ref} from 'vue'
|
||||
import myAxios from '@/api/myAxios';
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const fileSimple = ref() //单个文件
|
||||
const selectedItems = ref([])
|
||||
|
@ -84,7 +83,6 @@ const typeForm = ref({
|
|||
id: 0,
|
||||
typeName: '',
|
||||
typeUrl: '',
|
||||
typeIntro: ''
|
||||
})
|
||||
//表格数据
|
||||
const tableData = ref([])
|
||||
|
@ -133,8 +131,7 @@ const handleChange = async (file: any) => {
|
|||
}
|
||||
//上传图片移除
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
console.log(uploadFile, uploadFiles)
|
||||
// typeForm.value.typeUrl = ''
|
||||
// console.log(uploadFile, uploadFiles)
|
||||
typeImg.value.splice(0, typeImg.value.length) //移除展示即可
|
||||
submitable.value = true //再禁止上传
|
||||
}
|
||||
|
@ -176,8 +173,7 @@ const addOrUpdateType = async () => {
|
|||
const res = await myAxios.post('/category/add', {
|
||||
//对齐后端请求体
|
||||
typeName: typeForm.value.typeName,
|
||||
typeUrl: tempImgUrl.value,
|
||||
typeIntro: typeForm.value.typeIntro
|
||||
typeUrl: tempImgUrl.value
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
//提交成功后,之间重置表格
|
||||
|
@ -191,8 +187,7 @@ const addOrUpdateType = async () => {
|
|||
const res = await myAxios.post('/category/update', {
|
||||
id: typeForm.value.id,
|
||||
typeName: typeForm.value.typeName,
|
||||
typeUrl: tempImgUrl.value,
|
||||
typeIntro: typeForm.value.typeIntro
|
||||
typeUrl: tempImgUrl.value
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
//提交成功后,之间重置表格
|
||||
|
@ -211,8 +206,7 @@ const resetForm = () => {
|
|||
typeForm.value = {
|
||||
id: 0,
|
||||
typeName: '',
|
||||
typeUrl: '',
|
||||
typeIntro: ''
|
||||
typeUrl: ''
|
||||
}
|
||||
};
|
||||
const handleSelectionChange = (row: any) => {
|
||||
|
@ -223,7 +217,7 @@ const editShowForm = (index: number, row: any) => {
|
|||
tempImgUrl.value = row.typeUrl //万一上一个上传了没提交编辑
|
||||
typeImg.value.splice(0, typeImg.value.length) //先删除原先的
|
||||
typeImg.value.push({
|
||||
url: row.typeUrl
|
||||
url: downloadUrl + row.typeUrl
|
||||
})
|
||||
dialogVisible.value = true
|
||||
typeForm.value = JSON.parse(JSON.stringify(row))
|
||||
|
@ -247,4 +241,9 @@ const changeInput = () => { //当输入栏变化时解除禁用提交按钮
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.table_page {
|
||||
min-width: 800px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -2,20 +2,13 @@
|
|||
<div class="flexCard">
|
||||
<el-card class="richTextPreview" shadow="never">
|
||||
<div class="titleText">移动端预览</div>
|
||||
<p v-html="form.richText"></p>
|
||||
<p v-html="previewRichText"></p>
|
||||
</el-card>
|
||||
<!-- 表单 ref 和 prop绑定 用于重置表单 -->
|
||||
<el-card class="form-FormContainer" shadow="never">
|
||||
<el-form ref="resetFormData" :model="form" label-width="auto" size="large">
|
||||
<el-form-item label="添加写真展示图片">
|
||||
<!-- 下面的event的作用,传入当前事件对象 -->
|
||||
<el-upload ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 0)"
|
||||
:on-exceed="Exceed_ProductImg" limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<ImgSingleUpload @update:goodImgArr="form.goodImg = $event"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="服装名称" prop="name" style="width: 300px;" label-width="70px">
|
||||
<el-input v-model="form.name" />
|
||||
|
@ -50,7 +43,7 @@
|
|||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="效果图" label-width="70px">
|
||||
<richTextUtil @richTextContent="getInfo"/>
|
||||
<richTextUtil @richTextContent="getRichTextInfo"/>
|
||||
</el-form-item>
|
||||
<div class="totalButton">
|
||||
<el-form-item>
|
||||
|
@ -63,21 +56,21 @@
|
|||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="form-RichTextContainer" shadow="never">
|
||||
<outfitCalendarUtil @calendar-info="getInfo"></outfitCalendarUtil>
|
||||
<outfitCalendarUtil @calendar-info="getDateInfo"></outfitCalendarUtil>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, inject, toRaw, effect } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { ref, onMounted, inject, toRaw } from 'vue';
|
||||
import { ElMessage, type UploadProps, genFileId, type UploadRawFile } from 'element-plus';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import outfitCalendarUtil from '@/layout/components/outfitCalendarUtil.vue';
|
||||
import richTextUtil from '@/layout/components/richTextUtil.vue';
|
||||
import ImgSingleUpload from '@/utils/imgUpload/ImgSingleUpload.vue'
|
||||
|
||||
|
||||
const fileSimple = ref() //单个文件
|
||||
const resetFormData = ref()
|
||||
const form = ref({
|
||||
name: '', //服装名字
|
||||
|
@ -92,11 +85,13 @@ const form = ref({
|
|||
})
|
||||
//导入组件刷新
|
||||
const reload: any = inject("reload")
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const typeList = ref<String[]>([]) //服装类别数组
|
||||
const siteList = ref<String[]>(['室外','室内','均可']) //场地类型
|
||||
const minArr = ref<Number[]>([]) //最小人数数组
|
||||
const maxArr= ref<Number[]>([]) //最大人数数组
|
||||
const previewRichText = ref('') //预览富文本
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getOutfitKind() //获取服装类别
|
||||
for(let i = 0;i <=50 ; i++) { //初始化人数选择的数组
|
||||
|
@ -104,9 +99,7 @@ onMounted(() => {
|
|||
maxArr.value[i] = 2+i
|
||||
}
|
||||
})
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
console.log(uploadFile, uploadFiles)
|
||||
}
|
||||
|
||||
//将 服装类别 赋值到表格里
|
||||
const loadCategory = (value: any) => {
|
||||
form.value.categoryName = value //三元运算符 flag=1 是关于"商品类别"选项的值 flag=0 是关于“是否为节日限定”选项的值
|
||||
|
@ -117,10 +110,11 @@ const loadScene = (value: any) => {
|
|||
}
|
||||
//提交表单
|
||||
const onSubmit = async () => {
|
||||
console.log('提交前的表单---->',form.value)
|
||||
const values : any = Object.values(form.value);
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
console.log(form.value.bookingDateAddRequestList)
|
||||
if (values.some((value:any) => value === null || value === undefined || value === '') || form.value.bookingDateAddRequestList.length == 0) {
|
||||
if (values.some((value:any) => value === null || value === undefined || value === '' || value === 'PHA+PGJyPjwvcD4=') || form.value.bookingDateAddRequestList.length == 0) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '请检查表单数据是否完整填写'
|
||||
|
@ -136,6 +130,7 @@ const onSubmit = async () => {
|
|||
shotScene: form.value.shotScene,
|
||||
categoryName: form.value.categoryName,
|
||||
introImg: form.value.goodImg,
|
||||
richText: form.value.richText,
|
||||
bookingDateAddRequestList: toRaw(form.value.bookingDateAddRequestList)
|
||||
})
|
||||
console.log(res.data);
|
||||
|
@ -150,44 +145,26 @@ const onSubmit = async () => {
|
|||
return;
|
||||
}
|
||||
}
|
||||
//图片上传请求 此请求只要选择了图片,就会默认上传
|
||||
const handleChange = async (file: any, flag: number) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
// 取出formData对象中的file
|
||||
file: formData.get("file")
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
form.value.goodImg =res.data.data
|
||||
//三元运算 当flag为0时,赋值给商品图片 flag为1时,赋值给详情图片
|
||||
// flag ? form.value.detailImg = res.data.data : form.value.goodImg = res.data.data
|
||||
}
|
||||
}
|
||||
|
||||
//清除表单
|
||||
const resetForm = () => {
|
||||
resetFormData.value.resetFields()
|
||||
}
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
|
||||
const getRichTextInfo =(info:any)=>{ //子组件富文本传值
|
||||
// console.log('info-->',info);
|
||||
form.value.richText = encode64(info)
|
||||
previewRichText.value = info
|
||||
}
|
||||
|
||||
const getInfo =(info:any)=>{
|
||||
console.log('info-->',info);
|
||||
// timeInfo.value = info
|
||||
form.value.richText = info
|
||||
//字符串转为base64编码
|
||||
function encode64(text: string): string {
|
||||
return btoa(String.fromCharCode(...new TextEncoder().encode(text)))
|
||||
}
|
||||
|
||||
const getDateInfo = ( info:any )=>{ //日期组件传值
|
||||
console.log('info---->',info)
|
||||
form.value.bookingDateAddRequestList = info
|
||||
}
|
||||
|
||||
const getOutfitKind = async ()=> { //获取服装类别
|
||||
|
@ -218,6 +195,12 @@ const maxNum =()=>{
|
|||
}
|
||||
}
|
||||
|
||||
const getInfo = (info: any) => { //富文本赋值
|
||||
// console.log('info', info)
|
||||
previewRichText.value = info
|
||||
form.value.richText = info
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -257,4 +240,9 @@ const maxNum =()=>{
|
|||
.numberSelect {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.titleText {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
|
@ -66,7 +66,7 @@
|
|||
<el-table-column prop="goodImg" label="服装图片">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<img :src="scope.row.introImg" alt="" style="height: 50px;">
|
||||
<img :src="downloadUrl + scope.row.introImg" alt="" style="height: 50px;">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -117,10 +117,10 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="操作" width="250px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="ReviseOrView(scope.$index, scope.row , 0)">
|
||||
<el-button size="small" @click="ReviseOrView( scope.row , 0)">
|
||||
详情
|
||||
</el-button>
|
||||
<el-button size="small" @click="ReviseOrView(scope.$index, scope.row, 1)">
|
||||
<el-button size="small" @click="ReviseOrView(scope.row, 1)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button size="small" @click="handleOff(scope.row)">
|
||||
|
@ -143,71 +143,6 @@
|
|||
:small="null" :disabled="null" :background="null" layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total" />
|
||||
</div>
|
||||
<!-- 编辑/详情表单 -->
|
||||
<el-dialog v-model="DialogVisible" :title="title">
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-form-item label="服装编号">
|
||||
<el-input v-model="editForm.id" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="服装图片">
|
||||
<div v-if="editForm.introImg">
|
||||
<img :src="editForm.introImg" alt="服装图标" class="thumbnail" style="width: 100px; height: 100px;" />
|
||||
</div>
|
||||
<el-upload ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 0)" :on-exceed="Exceed_ProductImg"
|
||||
limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="服装名称">
|
||||
<el-input v-model="editForm.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="单次价格" prop="price">
|
||||
<el-input-number v-model="editForm.price" min="0" :precision="2" :step="0.5" />
|
||||
<p>元</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="服装类别" prop="type" style="width: 240px;">
|
||||
<el-select v-model="editForm.categoryName" placeholder="请选择" @change="(event: any) => loadCategory(event)">
|
||||
<el-option v-for="item in typeList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="拍摄场地" prop="type" style="width: 240px;">
|
||||
<el-select v-model="editForm.shotScene" placeholder="请选择" @change="(event: any) => loadScene(event)">
|
||||
<el-option v-for="item in siteList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最小人数" prop="type">
|
||||
<el-select v-model="editForm.minNumber" style="width: 120px;" @change="minNum()">
|
||||
<el-option v-for="item in minArr" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大人数" prop="type">
|
||||
<el-select v-model="editForm.maxNumber" style="width: 120px;" @change="maxNum()">
|
||||
<el-option v-for="item in maxArr" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="详情图">
|
||||
<div v-if="editForm.detailImg">
|
||||
<img :src="editForm.detailImg" alt="商品图标" class="thumbnail" style="width: 100px; height: 100px;" />
|
||||
</div>
|
||||
<el-upload ref="uploadProductDetail" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 1)" :on-exceed="Exceed_ProductDetail"
|
||||
limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="DialogVisible = false" :disabled="disabled">取消</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 时间段抽屉 -->
|
||||
<el-drawer v-model="drawer" :title="'当前日期:'+drawerDate.specificDate + ' 服装名称:' + outfitName" direction="ltr"
|
||||
@closed="closedDrawer">
|
||||
|
@ -249,13 +184,14 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage , type UploadProps , genFileId ,type UploadRawFile } from 'element-plus';
|
||||
import {ref, onMounted, inject, toRaw} from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import {ref, onMounted, inject} from 'vue';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import outfitCalendarUtil from '@/layout/components/outfitCalendarUtil.vue';
|
||||
import emitter from "@/utils/emitter";
|
||||
import { useRouter } from "vue-router";
|
||||
import {WarnInfo} from "@/utils/messageInfo";
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const router = useRouter(); //路由
|
||||
const total = ref(0); //总页数
|
||||
|
@ -268,16 +204,9 @@ const searchParams: any = ref({ //封装分页
|
|||
})
|
||||
const tableData : any= ref([]);
|
||||
const appointmentDateArr : any = ref([])
|
||||
const disabled = ref(true)
|
||||
const title = ref('') //表单名字
|
||||
const productName = ref('');
|
||||
const DialogVisible = ref(false);
|
||||
const state = ref(''); //根据商品上架状态select栏
|
||||
const editForm : any = ref({});
|
||||
const reload : any = inject("reload") //页面重新刷新
|
||||
const fileSimple = ref()
|
||||
const uploadProductImg : any = ref() //图片上传的ref绑定
|
||||
const uploadProductDetail : any = ref() //图片上传的ref绑定
|
||||
//抽屉变量
|
||||
const drawer = ref(false) //抽屉打开
|
||||
const drawerDate : any = ref({}) //当前日期、时间段人数信息
|
||||
|
@ -292,7 +221,6 @@ const timeAbleArr = ref( //禁用时间段组件
|
|||
const outfitName = ref('') //服装名称
|
||||
const addDateVisible = ref(false) //添加日期弹窗
|
||||
const typeList = ref<String[]>([]) //服装类别数组
|
||||
const siteList = ref<String[]>(['室外','室内','均可']) //场地类型
|
||||
|
||||
onMounted(async () => { //页面加载时获取商品列表和分类页表
|
||||
getOutfitList()
|
||||
|
@ -338,34 +266,7 @@ const getOutfitList = async () => {
|
|||
});
|
||||
}
|
||||
}
|
||||
const saveEdit = async () => { //编辑商品
|
||||
console.log('写真信息--->',editForm.value)
|
||||
const values : any = Object.values(editForm.value);
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
console.log(editForm.value.bookingDateAddRequestList)
|
||||
if (values.some((value:any) => value === null || value === undefined || value === '' || value === 0) ) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '请检查表单数据是否完整填写'
|
||||
})
|
||||
return; //空返回结束函数
|
||||
}
|
||||
const res = await myAxios.post('/photoProducts/update',{...editForm.value})
|
||||
if(res.data.code === 1) {
|
||||
DialogVisible.value = false
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '更新成功'
|
||||
})
|
||||
await getOutfitList()
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请检查字段是否正确填写'
|
||||
})
|
||||
}
|
||||
console.log('服装信息更新结果--->',res.data);
|
||||
}
|
||||
|
||||
const searchByState = (event : any) => { //通过商品是否上架/下架搜索
|
||||
searchParams.value.isShelves = event
|
||||
searchParams.value.current = 1
|
||||
|
@ -381,25 +282,20 @@ const deleteProduct = async (index: number) => {
|
|||
type: 'success',
|
||||
message: '删除成功',
|
||||
})
|
||||
getOutfitList()
|
||||
await getOutfitList()
|
||||
await getAllPhotoProducts()
|
||||
await getSpecialProducts()
|
||||
}
|
||||
}
|
||||
//详情或编辑
|
||||
const ReviseOrView = (index: number, row: any , flag : number) => {
|
||||
// router.push({
|
||||
// name: '服装详情',
|
||||
// params: {
|
||||
// id: row.id,
|
||||
// flag: flag
|
||||
// }
|
||||
// })
|
||||
//flag值不同显示不同内容 disabled开启和关闭
|
||||
flag ? (title.value = "编辑服装" , disabled.value = false) : (title.value = "服装详情" , disabled.value = true)
|
||||
DialogVisible.value = true;
|
||||
editForm.value = JSON.parse(JSON.stringify(row));
|
||||
// console.log('编辑商品--->',editForm.value);
|
||||
const ReviseOrView = (row: any , flag : number) => {
|
||||
router.push({
|
||||
name: '服装详情',
|
||||
params: {
|
||||
id: row.id,
|
||||
flag: flag
|
||||
}
|
||||
})
|
||||
};
|
||||
const getOutfitKind = async ()=> { //获取服装类别
|
||||
const res = await myAxios.post('/photoCategory/list',{})
|
||||
|
@ -407,14 +303,7 @@ const getOutfitKind = async ()=> { //获取服装类别
|
|||
typeList.value.push(res.data.data[key].name)
|
||||
}
|
||||
}
|
||||
//将 服装类别 赋值到表格里
|
||||
const loadCategory = (value: any) => {
|
||||
editForm.value.categoryName = value //三元运算符 flag=1 是关于"商品类别"选项的值 flag=0 是关于“是否为节日限定”选项的值
|
||||
}
|
||||
//将 商品类别 赋值到表格里
|
||||
const loadScene = (value: any) => {
|
||||
editForm.value.shotScene = value //三元运算符 flag=1 是关于"商品类别"选项的值 flag=0 是关于“是否为节日限定”选项的值
|
||||
}
|
||||
|
||||
//下架商品(待优化,有问题,逻辑有问题)
|
||||
const handleOff = async (row: any) => {
|
||||
console.log(row.isShelves);
|
||||
|
@ -443,43 +332,7 @@ const handleCurrentChange = (Current: any) => {
|
|||
const reset = () => {
|
||||
reload()
|
||||
};
|
||||
// 上传图片移除 --逻辑上移除
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
console.log(uploadFile, uploadFiles)
|
||||
}
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files , flag) => { //覆盖服装照片
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
}
|
||||
const Exceed_ProductDetail: UploadProps['onExceed'] = (files) => { //覆盖服装详情图片
|
||||
uploadProductDetail.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductDetail.value!.handleStart(file)
|
||||
}
|
||||
// 图片上传请求 此请求只要选择了图片,就会默认上传
|
||||
const handleChange = async (file: any, flag: number) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: formData.get("file") // 取出formData对象中的file
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
//三元运算 当flag为0时,赋值给商品图片 flag为1时,赋值给详情图片
|
||||
flag ? editForm.value.detailImg = res.data.data : editForm.value.goodImg = res.data.data
|
||||
}
|
||||
}
|
||||
|
||||
const onSearch = (data : String)=>{ //搜索按钮方法
|
||||
searchParams.value.name = data
|
||||
searchParams.value.current = 1
|
||||
|
@ -660,26 +513,6 @@ const submitDate = async ()=> { //提交日期方法
|
|||
appointmentDateAddRequestList.value = []
|
||||
emitter.emit('clear')
|
||||
}
|
||||
const minNum =()=>{ //最小人数不能大于最大人数
|
||||
if(editForm.value.minNumber > editForm.value.maxNumber && editForm.value.maxNumber != 0) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '最小人数不能大于最大人数'
|
||||
})
|
||||
editForm.value.minNumber = 0
|
||||
return;
|
||||
}
|
||||
}
|
||||
const maxNum =()=>{
|
||||
if(editForm.value.maxNumber < editForm.value.minNumber) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '最大人数不能小于最小人数'
|
||||
})
|
||||
editForm.value.maxNumber = 0
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const typeSelect : any = ref(true) //类别下拉选项栏的禁用状态
|
||||
|
|
|
@ -1,221 +1,221 @@
|
|||
<template>
|
||||
<div class="flexCard">
|
||||
<div class="flexCard" >
|
||||
<el-card class="richTextPreview" shadow="never">
|
||||
<div class="titleText">移动端预览</div>
|
||||
<p v-html="detailFrom.richText"></p>
|
||||
<p v-html="previewRichText"></p>
|
||||
</el-card>
|
||||
<!-- 表单 ref 和 prop绑定 用于重置表单 -->
|
||||
<el-card class="form-container" shadow="never">
|
||||
<div class="form">
|
||||
<el-form ref="resetFormData" :model="detailFrom" label-width="auto" size="large" :rules="rules" :disabled="true">
|
||||
<div>
|
||||
<el-form-item label="添加商品图片">
|
||||
<!-- 下面的event的作用,传入当前事件对象 -->
|
||||
<el-upload v-model:file-list="ImgArr" ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 2)" :on-exceed="Exceed_ProductImg"
|
||||
limit="7">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="NamePrice">
|
||||
<el-form-item label="产品名称" prop="name">
|
||||
<el-input v-model="detailFrom.name" maxlength="12" minlength="2" show-word-limit style="width: 260px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品价格" prop="price">
|
||||
<el-input-number v-model="detailFrom.price" min="0" :precision="2" :step="0.5" />
|
||||
<p>元</p>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="IntroInven">
|
||||
<el-form-item label="产品简介" prop="intro">
|
||||
<el-input v-model="detailFrom.intro" type="textarea" placeholder="产品尺寸,服务等" maxlength="30" show-word-limit
|
||||
style="width: 300px;" />
|
||||
</el-form-item>
|
||||
<div>
|
||||
<el-form-item label="库存" prop="inventory">
|
||||
<el-input-number v-model="detailFrom.inventory" min="0" :precision="0" :step="1" :disabled="invInput" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="festivalBox">
|
||||
<el-form-item label="节日名称" prop="festivalName" style="width: 300px;">
|
||||
<el-input v-model="detailFrom.festivalName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品类别" prop="type" style="width: 240px;">
|
||||
<el-select v-model="detailFrom.type" placeholder="请选择" @change="(event: any) => loadForm(event)" :disabled="typeSelect">
|
||||
<el-option v-for="item in typeList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div>
|
||||
<el-checkbox v-model="isqualify" label="定制商品" size="large" border style="margin-left: 10px;" @change="customTag" />
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="商品标签" prop="label">
|
||||
<div v-for="(item, index) in labelList" :key="index">
|
||||
<el-input v-model="labelList[index]" type="text" style="width: 150px;" maxlength="5" show-word-limit
|
||||
@blur="addLabelList" />
|
||||
</div>
|
||||
<el-button type="primary" @click="addLabel">添加</el-button>
|
||||
<el-card class="form-FormContainer" shadow="never" >
|
||||
<el-form ref="resetFormData" :model="form" label-width="auto" size="large" :disabled="disabledRichText">
|
||||
<el-form-item label="添加写真展示图片">
|
||||
<PreviewSingleImgUpload :ImgUrlList="form.introImg" @update:goodImgArr="form.introImg = $event"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="服装名称" prop="name" style="width: 300px;" label-width="70px">
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="价格" prop="price" label-width="70px">
|
||||
<el-input-number v-model="form.price" min="0" :precision="2" :step="0.5" />
|
||||
<p>元</p>
|
||||
</el-form-item>
|
||||
<!-- 拍摄场地:户外、室内、均可 -->
|
||||
<div class="kinds">
|
||||
<el-form-item label="拍摄场地" prop="type" style="width: 240px;" label-width="70px">
|
||||
<el-select v-model="form.shotScene" placeholder="请选择" @change="(event: any) => loadScene(event)" >
|
||||
<el-option v-for="item in siteList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图文" prop="richText">
|
||||
<richTextUtil @richTextContent="getInfo" v-model:disable="disabledRichText"/>
|
||||
<el-form-item label="服装类别" prop="type" style="width: 240px;" label-width="80px">
|
||||
<el-select v-model="form.categoryName" placeholder="请选择" @change="(event: any) => loadCategory(event)" >
|
||||
<el-option v-for="item in typeList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="btnBox">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="saveBtn">更新</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="numberSelect">
|
||||
<el-form-item label="最小人数" prop="type" style="width: 240px;" label-width="70px">
|
||||
<el-select v-model="form.minNumber" @change="minNum()">
|
||||
<el-option v-for="item in minArr" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大人数" prop="type" style="width: 240px;" label-width="80px">
|
||||
<el-select v-model="form.maxNumber" @change="maxNum()">
|
||||
<el-option v-for="item in maxArr" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="效果图" label-width="70px" v-loading="loading">
|
||||
<richTextUtil @richTextContent="getInfo" v-model:disableRich="disabledRichText" v-model:context="previewRichText"/>
|
||||
</el-form-item>
|
||||
<div class="totalButton">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">保存</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, inject, reactive, onBeforeMount } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import {type FormRules, type UploadUserFile} from 'element-plus';
|
||||
import { SuccessInfo, WarnInfo, CommInfo } from '@/utils/messageInfo'; //封装ElMessage提示
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onBeforeMount } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { saveBtn, invInput } from '@/utils/entityProduct/globalVar';
|
||||
import { validateName, validateIntro, validateDetail } from '@/utils/entityProduct/FormRules';
|
||||
import { handleChange, handleRemove, form, Exceed_ProductImg } from '@/utils/entityProduct/picUpload';
|
||||
import richTextUtil from '@/layout/components/richTextUtil.vue';
|
||||
import { useRoute } from "vue-router";
|
||||
import PreviewSingleImgUpload from "@/utils/imgUpload/PreviewSingleImgUpload.vue";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
|
||||
|
||||
const route = useRoute(); //路由
|
||||
const resetFormData = ref()
|
||||
const reload: any = inject("reload") //导入组件刷新
|
||||
const typeList: any = ref([])
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const labelList = ref([''])
|
||||
const isqualify : any = ref(false)
|
||||
const typeSelect : any = ref(false) //类别下拉选项栏的禁用状态
|
||||
const ImgArr: any = ref<UploadUserFile[]>([])
|
||||
const detailFrom : any = ref({
|
||||
name: '', //商品名称
|
||||
price: '', //商品价格
|
||||
intro: '',//产品简介
|
||||
categoryName: '', //服装类别
|
||||
goodImg: '', //商品图片url
|
||||
minNumber: 0,
|
||||
maxNumber: 0,
|
||||
richText: '',
|
||||
shotScene: '' //拍摄场地
|
||||
})
|
||||
const disabledRichText:any = ref(false);
|
||||
const form : any = ref({})
|
||||
//导入组件刷新
|
||||
const typeList = ref<String[]>([]) //服装类别数组
|
||||
const siteList = ref<String[]>(['室外','室内','均可']) //场地类型
|
||||
const minArr = ref<Number[]>([]) //最小人数数组
|
||||
const maxArr= ref<Number[]>([]) //最大人数数组
|
||||
const previewRichText = ref('') //预览富文本
|
||||
const disabledRichText = ref(false)
|
||||
const route = useRoute(); //路由
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
|
||||
onBeforeMount(()=>{ //页面加载最早的生命周期
|
||||
if(route.params.flag === '0'){
|
||||
disabledRichText.value = true;
|
||||
|
||||
onBeforeMount(()=>{
|
||||
if(route.params.flag === '0') {
|
||||
disabledRichText.value = true
|
||||
}
|
||||
getOutfitInfo()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getTypeList() //加载类别列表,渲染在产品列表的select选项里面
|
||||
getProductInfo() //编辑页查询商品信息
|
||||
// console.log('id---->',route.params.id)
|
||||
// console.log('flag---->',typeof (route.params.flag))
|
||||
|
||||
getOutfitKind() //获取服装类别
|
||||
for(let i = 0;i <=50 ; i++) { //初始化人数选择的数组
|
||||
minArr.value[i] = 1+i
|
||||
maxArr.value[i] = 2+i
|
||||
}
|
||||
setTimeout(()=>{
|
||||
loading.value = false
|
||||
},1500)
|
||||
})
|
||||
|
||||
const getProductInfo = async () => {
|
||||
const res = await myAxios.post('/goods/getById',{ id: route.params.id })
|
||||
console.log('后端查询商品--->',res.data.data)
|
||||
const getOutfitInfo = async () => {
|
||||
const res = await myAxios.post('/photoProducts/list/main/id',{ id: route.params.id })
|
||||
console.log('后端返回的数据---->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
detailFrom.value = res.data.data
|
||||
ImgArr.value.splice(0, ImgArr.value.length)
|
||||
labelList.value = res.data.data.label.split(';')
|
||||
var tempArr = res.data.data.goodImg.split(';')
|
||||
tempArr.forEach((item: any) => {
|
||||
ImgArr.value.push({
|
||||
url: item
|
||||
})
|
||||
})
|
||||
form.value = res.data.data
|
||||
previewRichText.value = res.data.data.richText
|
||||
}
|
||||
}
|
||||
|
||||
const getTypeList = async () => { //获取类别列表作为可选项
|
||||
const res = await myAxios.post('/category/list/web', {}) //获取商品列表
|
||||
for(let key in res.data.data) {
|
||||
typeList.value.push(res.data.data[key].typeName)
|
||||
}
|
||||
//将 服装类别 赋值到表格里
|
||||
const loadCategory = (value: any) => {
|
||||
form.value.categoryName = value //三元运算符 flag=1 是关于"商品类别"选项的值 flag=0 是关于“是否为节日限定”选项的值
|
||||
}
|
||||
//将 商品类别 赋值到表格里
|
||||
const loadScene = (value: any) => {
|
||||
form.value.shotScene = value //三元运算符 flag=1 是关于"商品类别"选项的值 flag=0 是关于“是否为节日限定”选项的值
|
||||
}
|
||||
//提交表单
|
||||
const onSubmit = async () => {
|
||||
const values = Object.values(detailFrom.value );
|
||||
console.log('提交前的表单---->',form.value)
|
||||
const values : any = Object.values(form.value);
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
if (values.some((value: any) => value === null || value === undefined || value === '' || value === 0)) {
|
||||
WarnInfo('请检查表单数据是否完整填写')
|
||||
|
||||
if (values.some((value:any) => value === null || value === undefined || value === '' || value === 'PHA+PGJyPjwvcD4=' || value === 0)) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '请检查表单数据是否完整填写'
|
||||
})
|
||||
return; //空返回结束函数
|
||||
}
|
||||
const res = await myAxios.post('/goods/add', { ...detailFrom.value })
|
||||
// console.log(form.value);
|
||||
const res = await myAxios.post('/photoProducts/update', {
|
||||
id: form.value.id,
|
||||
name: form.value.name,
|
||||
price: form.value.price,
|
||||
minNumber: form.value.minNumber,
|
||||
maxNumber: form.value.maxNumber,
|
||||
shotScene: form.value.shotScene,
|
||||
categoryName: form.value.categoryName,
|
||||
introImg: form.value.introImg,
|
||||
richText: form.value.richText
|
||||
})
|
||||
// console.log(res.data);
|
||||
if (res.data.code === 1) {
|
||||
SuccessInfo('提交成功')
|
||||
detailFrom.value = {} //12.18改
|
||||
reload() //上传完后重置表单
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: "提交成功"
|
||||
})
|
||||
router.replace('/OutfitManagementCenter')
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
ElMessage.error("服务错误")
|
||||
return;
|
||||
}
|
||||
}
|
||||
//将 商品类别 赋值到表格里
|
||||
const loadForm = (value: any) => {
|
||||
detailFrom.value.type = value //三元运算符 flag=1 是关于"商品类别"选项的值 flag=0 是关于“是否为节日限定”选项的值
|
||||
}
|
||||
|
||||
//清除表单
|
||||
const resetForm = () => {
|
||||
resetFormData.value.resetFields()
|
||||
}
|
||||
const rules = reactive<FormRules<typeof form>>({ //表单校验规则
|
||||
name: [{ validator: validateName, trigger: 'blur' }],
|
||||
intro: [{ validator: validateIntro, trigger: 'blur' }],
|
||||
introDetail: [{ validator: validateDetail, trigger: 'blur' }]
|
||||
})
|
||||
const addLabel = () => { //添加商品标签按钮的方法
|
||||
if (labelList.value[labelList.value.length - 1] === '') {
|
||||
WarnInfo('请填写完')
|
||||
return;
|
||||
}
|
||||
if (labelList.value.length < 4) {
|
||||
labelList.value.push('')
|
||||
|
||||
|
||||
const getOutfitKind = async ()=> { //获取服装类别
|
||||
const res = await myAxios.post('/photoCategory/list',{})
|
||||
for(let key in res.data.data) {
|
||||
typeList.value.push(res.data.data[key].name)
|
||||
}
|
||||
}
|
||||
|
||||
const addLabelList = () => { //格式化商品标签
|
||||
var string = ''
|
||||
if (!labelList.value.some((item: any) => item === '')) {
|
||||
string = labelList.value.join(';')
|
||||
} else return;
|
||||
detailFrom.value.label = string
|
||||
}
|
||||
const customTag = (e:any)=>{ //点击定制
|
||||
if(e) {
|
||||
detailFrom.value.inventory = 1
|
||||
invInput.value = true
|
||||
typeSelect.value = true
|
||||
detailFrom.value.type = '定制'
|
||||
} else {
|
||||
detailFrom.value.inventory = 0
|
||||
invInput.value = false
|
||||
typeSelect.value = false
|
||||
detailFrom.value.type = ''
|
||||
const minNum =()=>{ //最小人数不能大于最大人数
|
||||
if(form.value.minNumber > form.value.maxNumber && form.value.maxNumber != 0) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '最小人数不能大于最大人数'
|
||||
})
|
||||
form.value.minNumber = 0
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const maxNum =()=>{
|
||||
if(form.value.maxNumber < form.value.minNumber) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '最大人数不能小于最小人数'
|
||||
})
|
||||
form.value.maxNumber = 0
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const getInfo = (info: any) => { //富文本赋值
|
||||
console.log('info', info)
|
||||
detailFrom.value.richText = info
|
||||
previewRichText.value = info
|
||||
form.value.richText = encode64(info)
|
||||
}
|
||||
|
||||
//字符串转为base64编码
|
||||
function encode64(text: string): string {
|
||||
return btoa(String.fromCharCode(...new TextEncoder().encode(text)))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.form-FormContainer {
|
||||
width: 600px;
|
||||
height: 800px;
|
||||
overflow: auto;
|
||||
/* margin: 0 auto; */
|
||||
}
|
||||
|
||||
.form-RichTextContainer {
|
||||
width: 550px;
|
||||
}
|
||||
|
||||
.flexCard {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
@ -229,29 +229,22 @@ const getInfo = (info: any) => { //富文本赋值
|
|||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
width: 700px;
|
||||
/* margin: 0 auto; */
|
||||
.kinds {
|
||||
display: flex;
|
||||
}
|
||||
.form {
|
||||
/* width: 500px; */
|
||||
|
||||
.totalButton {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
/* 盒子里面水平分隔开 */
|
||||
}
|
||||
|
||||
.numberSelect {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.titleText {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.NamePrice {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.IntroInven {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.festivalBox {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
</style>
|
|
@ -75,7 +75,7 @@
|
|||
<el-col :span="6" class="table-cell-title">服装价格</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="6" class="table-cell-product"><img :src="photoProductsSnapshot.introImg"
|
||||
<el-col :span="6" class="table-cell-product"><img :src="downloadUrl + photoProductsSnapshot.introImg"
|
||||
style="height: 70px; width: 70px;" alt=""></el-col>
|
||||
<el-col :span="6" class="table-cell-product">{{ photoProductsSnapshot.name }}</el-col>
|
||||
<el-col :span="6" class="table-cell-product">{{ photoProductsSnapshot.categoryName }}</el-col>
|
||||
|
@ -94,6 +94,7 @@ import { onMounted, ref } from "vue";
|
|||
import myAxios from "@/api/myAxios";
|
||||
import { SuccessInfo, ErrorInfo } from "@/utils/messageInfo";
|
||||
import { useRoute } from "vue-router";
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const route = useRoute();
|
||||
const orderObj: any = ref({}) //订单对象
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { ref,onMounted} from 'vue'
|
||||
import {ElMessage, type UploadProps} from "element-plus";
|
||||
import {ElMessage} from "element-plus";
|
||||
import myAxios from "@/api/myAxios";
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
:header-cell-style="{ 'text-align': 'center' }">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="name" label="优惠券名称"></el-table-column>
|
||||
<el-table-column prop="content" label="简介"></el-table-column>
|
||||
<!-- <el-table-column prop="content" label="简介"></el-table-column>-->
|
||||
<el-table-column prop="standardAmount" label="满减价格"></el-table-column>
|
||||
<el-table-column prop="conditionAmount" label="优惠价格"></el-table-column>
|
||||
<el-table-column prop="requirePoints" label="兑换积分"></el-table-column>
|
||||
|
@ -110,7 +110,7 @@
|
|||
<script lang="ts" setup>
|
||||
import {inject, onMounted, ref} from "vue";
|
||||
import myAxios from "@/api/myAxios";
|
||||
import {ElMessage, type UploadProps} from "element-plus";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
onMounted(() => {
|
||||
getCouponsList()
|
||||
|
|
|
@ -138,6 +138,7 @@ const getDashBoard = async () => {
|
|||
margin-top: 40px;
|
||||
margin-left: 120px;
|
||||
margin-right: 120px;
|
||||
min-width: 800px;
|
||||
}
|
||||
|
||||
.total-layout {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<div class="table_page">
|
||||
<div style="margin-bottom: 20px">
|
||||
<el-input style="width: 250px; height: 30px; margin-right: 10px; font-size: 14px" suffix-icon="Search"
|
||||
placeholder="请输入订单编号" v-model="orderNumber"></el-input>
|
||||
|
@ -27,7 +28,7 @@
|
|||
<el-table-column label="商品图片" prop="goodSnapshot.goodImg" width="200">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<img :src="scope.row.goodSnapshot.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
<img :src=" downloadUrl + scope.row.goodSnapshot.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -49,7 +50,6 @@
|
|||
<!-- <el-table-column label="优惠券信息" width="50">-->
|
||||
<!-- <el-table-column prop="couponSnapshot.name" label="优惠卷名称" />-->
|
||||
<el-table-column prop="couponSnapshot.conditionAmount" label="优惠金额" />
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column prop="totalAmount" label="订单实付金额"></el-table-column>
|
||||
<el-table-column prop="orderStatus" label="订单状态"></el-table-column>
|
||||
<el-table-column prop="trackingNumber" label="快递单号"></el-table-column>
|
||||
|
@ -82,6 +82,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 分页器 -->
|
||||
<div style="padding: 10px 0">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
|
@ -175,6 +176,7 @@ import { onMounted, ref } from "vue";
|
|||
import myAxios from "@/api/myAxios";
|
||||
import { ElMessage } from "element-plus";
|
||||
import {SuccessInfo, ErrorInfo, WarnInfo} from "@/utils/messageInfo";
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
const tableData: any = ref([]); //表单展示数据
|
||||
const total = ref(0);
|
||||
const title = ref('')
|
||||
|
@ -300,10 +302,13 @@ const cancelOrder = async (row: any) => { //取消订单的方法(未支付能
|
|||
const successfulTransaction = async (oid: any) => {
|
||||
// console.log('当前订单信息---->',oid)
|
||||
// loading.value = true
|
||||
const res = await myAxios.post('',{})
|
||||
const res = await myAxios.post('/order/update/all/orderStatus',{
|
||||
id: oid,
|
||||
orderStatus: '交易完成'
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
SuccessInfo('订单完成')
|
||||
getOrderList()
|
||||
await getOrderList()
|
||||
loading.value = false
|
||||
} else {
|
||||
WarnInfo('更新失败')
|
||||
|
@ -325,4 +330,8 @@ const successfulTransaction = async (oid: any) => {
|
|||
font-family: 'Arial', sans-serif;
|
||||
/* 设置字体 */
|
||||
}
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<div class="table_page">
|
||||
<div style="margin-bottom: 20px;">
|
||||
<div style="display: flex; justify-content: space-around; align-items: center">
|
||||
<div>
|
||||
|
@ -34,7 +35,7 @@
|
|||
<el-table-column prop="goodImg" label="商品图片" width="100">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<img :src="scope.row.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
<img :src=" downloadUrl + scope.row.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -78,8 +79,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 分页器 -->
|
||||
<div style="padding: 10px 0">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
|
@ -111,11 +112,9 @@
|
|||
<el-form-item label="预估支付金额" style="width: 250px">
|
||||
<el-input v-model="editForm.itemTotalAmount" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="订单明细状态" style="width: 250px">
|
||||
<el-input v-model="editForm.orderItemStatus" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <div style="display: flex">-->
|
||||
<!-- <el-form-item label="下单时间" style="width: 300px;">-->
|
||||
<!-- <el-input v-model="editForm.createTime" autocomplete="off"></el-input>-->
|
||||
|
@ -156,7 +155,8 @@ import { SuccessInfo, ErrorInfo } from "@/utils/messageInfo";
|
|||
import DatePicker from "@/layout/components/DatePicker.vue";
|
||||
import TimePicker from "@/layout/components/TimePicker.vue";
|
||||
import emitter from "@/utils/emitter";
|
||||
import { checkObjectProperties } from "@/layout/js/validUtils";
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const tableData: any = ref([]); //表单展示数据
|
||||
const totalPage = ref(0);
|
||||
const title = ref('')
|
||||
|
@ -323,4 +323,8 @@ const cancelOrder = async (row: any) => { //取消订单的方法(未支付能
|
|||
/* 设置字体 */
|
||||
}
|
||||
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<div class="table_page">
|
||||
<div style="margin-bottom: 20px">
|
||||
<el-input style="width: 250px; height: 30px; margin-right: 10px; font-size: 14px" suffix-icon="Search" placeholder="请输入订单编号"
|
||||
v-model="orderNumber"></el-input>
|
||||
|
@ -26,7 +27,7 @@
|
|||
<el-table-column label="商品图片" prop="goodSnapshot.goodImg" width="200">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<img :src="scope.row.goodSnapshot.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
<img :src="downloadUrl + scope.row.goodSnapshot.goodImg.split(';')[0]" alt="" style="height: 50px;">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -77,6 +78,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 分页器 -->
|
||||
<div style="padding: 10px 0">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
|
@ -91,7 +93,8 @@ import { onMounted, ref } from "vue";
|
|||
import myAxios from "@/api/myAxios";
|
||||
import { ElMessage } from "element-plus";
|
||||
import {SuccessInfo, ErrorInfo, WarnInfo} from "@/utils/messageInfo";
|
||||
import emitter from "@/utils/emitter";
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const tableData: any = ref([]); //表单展示数据
|
||||
const total = ref(0);
|
||||
const orderNumber = ref('')
|
||||
|
@ -191,4 +194,8 @@ const successfulTransaction = async (oid: any) => { //订单完成方法
|
|||
font-weight: bold; /* 设置字体加粗 */
|
||||
font-family: 'Arial', sans-serif; /* 设置字体 */
|
||||
}
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -1,70 +1,64 @@
|
|||
<template>
|
||||
<div>
|
||||
<div style="margin: 10px 0">
|
||||
<el-input style="width: 200px; height: 30px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入图片名称" v-model="simpleList.name"></el-input>
|
||||
<el-button class="ml-5" type="primary" @click="onSearch" style="height: 25px;">搜索</el-button>
|
||||
<el-button type="warning" @click="reset" style="height:25px">重置</el-button>
|
||||
</div>
|
||||
<div style="margin: 15px 0">
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="InfoFilled"
|
||||
icon-color="red"
|
||||
title="您确定批量删除这些数据吗?"
|
||||
@confirm=""
|
||||
width=180
|
||||
>
|
||||
<template #reference>
|
||||
<el-button style="height: 25px" type="danger" slot="reference">批量删除 <el-icon style="margin-left: 5px;"><Remove /></el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
<el-table :data="simpleList" border stripe header-cell-class-name="headerBg" :cell-style="{textAlign: 'center'}"
|
||||
@selection-change="handleSelectionChange" :header-cell-style="{'text-align': 'center'}">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="id" label="图片序号" width="50"></el-table-column>
|
||||
<el-table-column prop="imgUrl" label="图片">
|
||||
<template #default="scope"><img :src="scope.row.imgUrl" alt="" style="height: 50px;"></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="商品图片" ></el-table-column>
|
||||
<el-table-column prop="tips" label="对应商品"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="success" @click="editCarouse(scope.row)">编辑<i class="el-icon-edit"></i></el-button>
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="el-icon-info"
|
||||
icon-color="red"
|
||||
title="您确定删除吗?"
|
||||
@confirm="deleteCarouse"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="padding: 10px 0">
|
||||
<!-- 分页器 -->
|
||||
<el-pagination
|
||||
:current-page="searchParams.current"
|
||||
:page-size="searchParams.pageSize"
|
||||
:page-sizes="[2, 5, 10, 20]"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:small="null"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
/>
|
||||
</div>
|
||||
<div class="table_page">
|
||||
<div style="margin-bottom: 15px">
|
||||
<el-button type="primary" slot="reference" @click="addCarouse">添加图片</el-button>
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="InfoFilled"
|
||||
icon-color="red"
|
||||
title="您确定批量删除这些数据吗?"
|
||||
@confirm=""
|
||||
width=180
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="danger" slot="reference">批量删除 <el-icon style="margin-left: 5px;"><Remove /></el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
<el-table :data="tableData" border stripe header-cell-class-name="headerBg" :cell-style="{textAlign: 'center'}"
|
||||
@selection-change="handleSelectionChange" :header-cell-style="{'text-align': 'center'}">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="id" label="图片序号" width="50"></el-table-column>
|
||||
<el-table-column prop="url" label="图片">
|
||||
<template #default="scope"><img :src="downloadUrl + scope.row.url" alt="" style="height: 50px;"></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="success" @click="editCarouse(scope.row)">编辑<i class="el-icon-edit"></i></el-button>
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="el-icon-info"
|
||||
icon-color="red"
|
||||
title="您确定删除吗?"
|
||||
@confirm="deleteCarouse(scope.row.id)"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div style="padding: 10px 0">
|
||||
<!-- 分页器 -->
|
||||
<el-pagination
|
||||
:current-page="searchParams.current"
|
||||
:page-size="searchParams.pageSize"
|
||||
:page-sizes="[2, 5, 10, 20]"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:small="null"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
/>
|
||||
</div>
|
||||
<!-- 编辑/详情表单 -->
|
||||
<el-dialog v-model="DialogVisible" title="轮播图编辑">
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-dialog v-model="DialogVisible" :title="title" >
|
||||
<el-form label-width="100px" :disabled="disabled" v-loading="loading">
|
||||
<el-form-item label="轮播图">
|
||||
<el-upload
|
||||
v-model:file-list="carouseImg"
|
||||
|
@ -82,51 +76,29 @@
|
|||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片名称">
|
||||
<el-input v-model="editForm.productImg" style="width: 200px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="对应商品" prop="price">
|
||||
<el-select v-model="editForm.prdouctName" @change="(event: any) => loadForm(event)" style="width: 120px;">
|
||||
<el-option v-for="item in goodList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer >
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="DialogVisible = false" :disabled="disabled">取消</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
|
||||
<el-button @click="restForm" :disabled="loading">取消</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="loading">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type UploadProps , type UploadUserFile , genFileId ,type UploadRawFile } from 'element-plus';
|
||||
import { type UploadProps } from 'element-plus';
|
||||
import myAxios from '@/api/myAxios';
|
||||
import {ref, onMounted , inject} from 'vue'
|
||||
import { WarnInfo, SuccessInfo , ErrorInfo, CommInfo } from '@/utils/messageInfo';
|
||||
const simpleList : any = ref([
|
||||
{
|
||||
id: '1', //图片id
|
||||
name: '样例1', //图片名称
|
||||
imgUrl: 'https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FgGwBQzmm-cxz.png', //图片样例
|
||||
grade: '等级1', //图片级别
|
||||
correspondingGoods: '非遗发簪' //对应商品
|
||||
},
|
||||
{
|
||||
id: '2', //图片id
|
||||
name: '样例2', //图片名称
|
||||
imgUrl: 'https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FgGwBQzmm-cxz.png', //图片样例
|
||||
grade: '等级2', //图片级别
|
||||
correspondingGoods: '非遗螺钿' //对应商品
|
||||
}
|
||||
])
|
||||
const goodList = ref([]) //商品名称
|
||||
import {ref, onMounted, inject } from 'vue'
|
||||
import { WarnInfo, SuccessInfo } from '@/utils/messageInfo';
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const DialogVisible = ref(false); //表单显示
|
||||
const disabled = ref(false)
|
||||
const editForm : any= ref({})
|
||||
const uploadImg : any = ref() //图片上传的ref绑定
|
||||
const carouseImg: any = ref<UploadUserFile[]>([]) //给商品中心页面编辑商品使用
|
||||
const carouseImg: any = ref([]) //给商品中心页面编辑商品使用
|
||||
const reload : any = inject("reload") //页面重新刷新
|
||||
const tableData = ref([]) //获取的所有数据
|
||||
const total = ref(0) //筛选条数
|
||||
const fileSimple = ref() //单个文件
|
||||
|
@ -135,16 +107,31 @@ const searchParams: any = ref({
|
|||
//当前页码
|
||||
current: 1,
|
||||
//每页显示条数
|
||||
pageSize: 5
|
||||
pageSize: 5,
|
||||
//轮播图类别
|
||||
type: '服务类'
|
||||
})
|
||||
//导入组件刷新
|
||||
const reload : any = inject("reload")
|
||||
|
||||
const title : any = ref('编辑表单')
|
||||
const loading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
getCourseList()
|
||||
})
|
||||
//重置按钮
|
||||
const reset =()=>{
|
||||
reload()
|
||||
|
||||
const getCourseList = async () => {
|
||||
const res = await myAxios.post('/banner/query/web',{
|
||||
current: searchParams.value.current,
|
||||
pageSize: searchParams.value.pageSize,
|
||||
type: searchParams.value.type
|
||||
})
|
||||
// console.log('分页后端返回---->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
tableData.value = res.data.data.records
|
||||
total.value = parseInt(res.data.data.total)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectionChange = (val:any)=>{
|
||||
console.log(val)
|
||||
}
|
||||
|
@ -158,57 +145,109 @@ const handleCurrentChange = (Current:any) => {
|
|||
searchParams.value.current = Current //新的当前页面
|
||||
//重新发起请求
|
||||
};
|
||||
//搜索按钮方法
|
||||
const onSearch = (data : String)=>{
|
||||
searchParams.value.name = data
|
||||
searchParams.value.current = 1
|
||||
//重新发请求
|
||||
|
||||
const restForm =()=> {
|
||||
DialogVisible.value = false
|
||||
carouseImg.value.splice(0,1)
|
||||
editForm.value.url = ''
|
||||
}
|
||||
const deleteCarouse = async (index: number,row: any) =>{ //删除单个轮播图
|
||||
simpleList.value.splice(index,1)
|
||||
|
||||
const deleteCarouse = async (id: number) =>{ //删除单个轮播图
|
||||
const res = await myAxios.post('/banner/delete',{ id: id })
|
||||
if(res.data.code === 1) {
|
||||
SuccessInfo('删除图片成功')
|
||||
await getCourseList()
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
}
|
||||
}
|
||||
|
||||
const editCarouse = async (obj: any) =>{
|
||||
title.value = '编辑轮播图'
|
||||
carouseImg.value.splice(0,carouseImg.value.length)
|
||||
carouseImg.value.push({ //编辑展示
|
||||
url: obj.imgUrl
|
||||
url: downloadUrl + obj.url
|
||||
})
|
||||
editForm.value = obj
|
||||
editForm.value = JSON.parse(JSON.stringify(obj))
|
||||
DialogVisible.value = true
|
||||
}
|
||||
const saveEdit = ()=>{ //保存表单
|
||||
|
||||
const saveEdit = async ()=>{ //保存表单
|
||||
if(editForm.value.url === '') {
|
||||
WarnInfo('图片不能为空')
|
||||
return
|
||||
}
|
||||
DialogVisible.value = false
|
||||
if(editForm.value.id == undefined) {
|
||||
const res = await myAxios.post('/banner/add',{
|
||||
type: '服务类',
|
||||
url: editForm.value.url
|
||||
})
|
||||
if(res.data.code === 1) {
|
||||
DialogVisible.value = false
|
||||
await getCourseList()
|
||||
reload()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
const res = await myAxios.post('/banner/update',{ ...editForm.value })
|
||||
if(res.data.code === 1) {
|
||||
DialogVisible.value = false
|
||||
await getCourseList()
|
||||
reload()
|
||||
SuccessInfo('更新成功')
|
||||
return
|
||||
}
|
||||
}
|
||||
WarnInfo('服务错误')
|
||||
}
|
||||
|
||||
const removePic : UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFile表示当前删除的图片,uploadFiles是还剩余的图片信息
|
||||
carouseImg.value.splice(0,1)
|
||||
editForm.value.url = ''
|
||||
}
|
||||
//将 等级选项 赋值到表格里
|
||||
const loadForm = (value: any) => {
|
||||
editForm.value.grade = value
|
||||
}
|
||||
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('请移除之前的再上传')
|
||||
}
|
||||
|
||||
const handleChange = async (file: any ) => {
|
||||
loading.value = true
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
// const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
// url: '/file/uploadFile',
|
||||
// method: 'post',
|
||||
// headers: {
|
||||
// 'content-Type': 'multipart/form-data'
|
||||
// },
|
||||
// data: {
|
||||
// biz: "test",
|
||||
// // 取出formData对象中的file
|
||||
// file: formData.get("file")
|
||||
// }
|
||||
// })
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
// 取出formData对象中的file
|
||||
file: formData.get("file")
|
||||
}
|
||||
})
|
||||
if(res.data.code === 1) {
|
||||
editForm.value.url = res.data.data
|
||||
loading.value = false
|
||||
SuccessInfo('图片上传成功')
|
||||
}
|
||||
}
|
||||
|
||||
//添加轮播图
|
||||
const addCarouse = async () => {
|
||||
restForm()
|
||||
title.value = '添加轮播图'
|
||||
DialogVisible.value = true
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.headerBg{
|
||||
background-color: #eee !important;
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -1,70 +1,64 @@
|
|||
<template>
|
||||
<div>
|
||||
<div style="margin: 10px 0">
|
||||
<el-input style="width: 200px; height: 30px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入图片名称" v-model="simpleList.name"></el-input>
|
||||
<el-button class="ml-5" type="primary" @click="onSearch" style="height: 25px;">搜索</el-button>
|
||||
<el-button type="warning" @click="reset" style="height:25px">重置</el-button>
|
||||
</div>
|
||||
<div style="margin: 15px 0">
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="InfoFilled"
|
||||
icon-color="red"
|
||||
title="您确定批量删除这些数据吗?"
|
||||
@confirm=""
|
||||
width=180
|
||||
>
|
||||
<template #reference>
|
||||
<el-button style="height: 25px" type="danger" slot="reference">批量删除 <el-icon style="margin-left: 5px;"><Remove /></el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
<el-table :data="simpleList" border stripe header-cell-class-name="headerBg" :cell-style="{textAlign: 'center'}"
|
||||
@selection-change="handleSelectionChange" :header-cell-style="{'text-align': 'center'}">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="id" label="图片序号" width="50"></el-table-column>
|
||||
<el-table-column prop="imgUrl" label="图片">
|
||||
<template #default="scope"><img :src="scope.row.imgUrl" alt="" style="height: 50px;"></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="商品图片" ></el-table-column>
|
||||
<el-table-column prop="tips" label="对应商品"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="success" @click="editCarouse(scope.row)">编辑<i class="el-icon-edit"></i></el-button>
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="el-icon-info"
|
||||
icon-color="red"
|
||||
title="您确定删除吗?"
|
||||
@confirm="deleteCarouse"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="padding: 10px 0">
|
||||
<!-- 分页器 -->
|
||||
<el-pagination
|
||||
:current-page="searchParams.current"
|
||||
:page-size="searchParams.pageSize"
|
||||
:page-sizes="[2, 5, 10, 20]"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:small="null"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
/>
|
||||
</div>
|
||||
<div class="table_page">
|
||||
<div style="margin-bottom: 15px">
|
||||
<el-button type="primary" slot="reference" @click="addCarouse">添加图片</el-button>
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="InfoFilled"
|
||||
icon-color="red"
|
||||
title="您确定批量删除这些数据吗?"
|
||||
@confirm=""
|
||||
width=180
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="danger" slot="reference">批量删除 <el-icon style="margin-left: 5px;"><Remove /></el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
<el-table :data="tableData" border stripe header-cell-class-name="headerBg" :cell-style="{textAlign: 'center'}"
|
||||
@selection-change="handleSelectionChange" :header-cell-style="{'text-align': 'center'}">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="id" label="图片序号" width="50"></el-table-column>
|
||||
<el-table-column prop="url" label="图片">
|
||||
<template #default="scope"><img :src="downloadUrl + scope.row.url" alt="" style="height: 50px;"></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="success" @click="editCarouse(scope.row)">编辑<i class="el-icon-edit"></i></el-button>
|
||||
<el-popconfirm
|
||||
confirm-button-text='确定'
|
||||
cancel-button-text='取消'
|
||||
icon="el-icon-info"
|
||||
icon-color="red"
|
||||
title="您确定删除吗?"
|
||||
@confirm="deleteCarouse(scope.row.id)"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="padding: 10px 0">
|
||||
<!-- 分页器 -->
|
||||
<el-pagination
|
||||
:current-page="searchParams.current"
|
||||
:page-size="searchParams.pageSize"
|
||||
:page-sizes="[2, 5, 10, 20]"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:small="null"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 编辑/详情表单 -->
|
||||
<el-dialog v-model="DialogVisible" title="轮播图编辑">
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-dialog v-model="DialogVisible" :title="title" >
|
||||
<el-form label-width="100px" :disabled="disabled" v-loading="loading">
|
||||
<el-form-item label="轮播图">
|
||||
<el-upload
|
||||
v-model:file-list="carouseImg"
|
||||
|
@ -82,51 +76,29 @@
|
|||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片名称">
|
||||
<el-input v-model="editForm.productImg" style="width: 200px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="对应商品" prop="price">
|
||||
<el-select v-model="editForm.prdouctName" @change="(event: any) => loadForm(event)" style="width: 120px;">
|
||||
<el-option v-for="item in goodList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer >
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="DialogVisible = false" :disabled="disabled">取消</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
|
||||
<el-button @click="restForm" :disabled="loading">取消</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="loading">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type UploadProps , type UploadUserFile , genFileId ,type UploadRawFile } from 'element-plus';
|
||||
import { type UploadProps } from 'element-plus';
|
||||
import myAxios from '@/api/myAxios';
|
||||
import {ref, onMounted , inject} from 'vue'
|
||||
import { WarnInfo, SuccessInfo , ErrorInfo, CommInfo } from '@/utils/messageInfo';
|
||||
const simpleList : any = ref([
|
||||
{
|
||||
id: '1', //图片id
|
||||
name: '样例1', //图片名称
|
||||
imgUrl: 'https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FgGwBQzmm-cxz.png', //图片样例
|
||||
grade: '等级1', //图片级别
|
||||
correspondingGoods: '非遗发簪' //对应商品
|
||||
},
|
||||
{
|
||||
id: '2', //图片id
|
||||
name: '样例2', //图片名称
|
||||
imgUrl: 'https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FgGwBQzmm-cxz.png', //图片样例
|
||||
grade: '等级2', //图片级别
|
||||
correspondingGoods: '非遗螺钿' //对应商品
|
||||
}
|
||||
])
|
||||
const goodList = ref([]) //商品名称
|
||||
import {ref, onMounted, inject } from 'vue'
|
||||
import { WarnInfo, SuccessInfo } from '@/utils/messageInfo';
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const DialogVisible = ref(false); //表单显示
|
||||
const disabled = ref(false)
|
||||
const editForm : any= ref({})
|
||||
const uploadImg : any = ref() //图片上传的ref绑定
|
||||
const carouseImg: any = ref<UploadUserFile[]>([]) //给商品中心页面编辑商品使用
|
||||
const carouseImg: any = ref([]) //给商品中心页面编辑商品使用
|
||||
const reload : any = inject("reload") //页面重新刷新
|
||||
const tableData = ref([]) //获取的所有数据
|
||||
const total = ref(0) //筛选条数
|
||||
const fileSimple = ref() //单个文件
|
||||
|
@ -135,16 +107,31 @@ const searchParams: any = ref({
|
|||
//当前页码
|
||||
current: 1,
|
||||
//每页显示条数
|
||||
pageSize: 5
|
||||
pageSize: 5,
|
||||
//轮播图类别
|
||||
type: '实体类'
|
||||
})
|
||||
//导入组件刷新
|
||||
const reload : any = inject("reload")
|
||||
|
||||
const title : any = ref('编辑表单')
|
||||
const loading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
getCourseList()
|
||||
})
|
||||
//重置按钮
|
||||
const reset =()=>{
|
||||
reload()
|
||||
|
||||
const getCourseList = async () => {
|
||||
const res = await myAxios.post('/banner/query/web',{
|
||||
current: searchParams.value.current,
|
||||
pageSize: searchParams.value.pageSize,
|
||||
type: searchParams.value.type
|
||||
})
|
||||
console.log('分页后端返回---->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
tableData.value = res.data.data.records
|
||||
total.value = parseInt(res.data.data.total)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectionChange = (val:any)=>{
|
||||
console.log(val)
|
||||
}
|
||||
|
@ -158,57 +145,109 @@ const handleCurrentChange = (Current:any) => {
|
|||
searchParams.value.current = Current //新的当前页面
|
||||
//重新发起请求
|
||||
};
|
||||
//搜索按钮方法
|
||||
const onSearch = (data : String)=>{
|
||||
searchParams.value.name = data
|
||||
searchParams.value.current = 1
|
||||
//重新发请求
|
||||
|
||||
const restForm =()=> {
|
||||
DialogVisible.value = false
|
||||
carouseImg.value.splice(0,1)
|
||||
editForm.value.url = ''
|
||||
}
|
||||
const deleteCarouse = async (index: number,row: any) =>{ //删除单个轮播图
|
||||
simpleList.value.splice(index,1)
|
||||
|
||||
const deleteCarouse = async (id: number) =>{ //删除单个轮播图
|
||||
const res = await myAxios.post('/banner/delete',{ id: id })
|
||||
if(res.data.code === 1) {
|
||||
SuccessInfo('删除图片成功')
|
||||
await getCourseList()
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
}
|
||||
}
|
||||
|
||||
const editCarouse = async (obj: any) =>{
|
||||
title.value = '编辑轮播图'
|
||||
carouseImg.value.splice(0,carouseImg.value.length)
|
||||
carouseImg.value.push({ //编辑展示
|
||||
url: obj.imgUrl
|
||||
url: downloadUrl + obj.url
|
||||
})
|
||||
editForm.value = obj
|
||||
editForm.value = JSON.parse(JSON.stringify(obj))
|
||||
DialogVisible.value = true
|
||||
}
|
||||
const saveEdit = ()=>{ //保存表单
|
||||
|
||||
const saveEdit = async ()=>{ //保存表单
|
||||
if(editForm.value.url === '') {
|
||||
WarnInfo('图片不能为空')
|
||||
return
|
||||
}
|
||||
DialogVisible.value = false
|
||||
if(editForm.value.id == undefined) {
|
||||
const res = await myAxios.post('/banner/add',{
|
||||
type: '实体类',
|
||||
url: editForm.value.url
|
||||
})
|
||||
if(res.data.code === 1) {
|
||||
DialogVisible.value = false
|
||||
await getCourseList()
|
||||
reload()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
const res = await myAxios.post('/banner/update',{ ...editForm.value })
|
||||
if(res.data.code === 1) {
|
||||
DialogVisible.value = false
|
||||
await getCourseList()
|
||||
reload()
|
||||
SuccessInfo('更新成功')
|
||||
return
|
||||
}
|
||||
}
|
||||
WarnInfo('服务错误')
|
||||
}
|
||||
|
||||
const removePic : UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFile表示当前删除的图片,uploadFiles是还剩余的图片信息
|
||||
carouseImg.value.splice(0,1)
|
||||
editForm.value.url = ''
|
||||
}
|
||||
//将 等级选项 赋值到表格里
|
||||
const loadForm = (value: any) => {
|
||||
editForm.value.grade = value
|
||||
}
|
||||
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('请移除之前的再上传')
|
||||
}
|
||||
|
||||
const handleChange = async (file: any ) => {
|
||||
loading.value = true
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
// const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
// url: '/file/uploadFile',
|
||||
// method: 'post',
|
||||
// headers: {
|
||||
// 'content-Type': 'multipart/form-data'
|
||||
// },
|
||||
// data: {
|
||||
// biz: "test",
|
||||
// // 取出formData对象中的file
|
||||
// file: formData.get("file")
|
||||
// }
|
||||
// })
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
// 取出formData对象中的file
|
||||
file: formData.get("file")
|
||||
}
|
||||
})
|
||||
if(res.data.code === 1) {
|
||||
editForm.value.url = res.data.data
|
||||
loading.value = false
|
||||
SuccessInfo('图片上传成功')
|
||||
}
|
||||
}
|
||||
|
||||
//添加轮播图
|
||||
const addCarouse = async () => {
|
||||
restForm()
|
||||
title.value = '添加轮播图'
|
||||
DialogVisible.value = true
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.headerBg{
|
||||
background-color: #eee !important;
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -6,27 +6,10 @@
|
|||
<el-form :model="festivalForm" label-width="auto" style="max-width: 600px" v-loading="loading">
|
||||
<el-form-item label="添加节日缩略图">
|
||||
<!-- 下面的event的作用,传入当前事件对象 -->
|
||||
<el-upload
|
||||
v-model:file-list="festivalImg"
|
||||
action="#"
|
||||
ref="uploadProductImg"
|
||||
list-type="picture-card"
|
||||
:auto-upload="false"
|
||||
multiple="true"
|
||||
:on-remove="handleRemove"
|
||||
@change="(event: any) => handleChange(event)"
|
||||
:on-exceed="Exceed_ProductImg"
|
||||
limit="1">
|
||||
<el-icon>
|
||||
<Plus/>
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<ImgSingleUpload @update:goodImgArr="festivalForm.url = $event"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="节日名称">
|
||||
<!-- <el-input v-model="festivalForm.name" @input="changeInput"/>-->
|
||||
<el-select v-model="form.festivalName" placeholder="请选择" >
|
||||
<el-option v-for="item in festivalArr" :key="item" :label="item.name" :value="item.name" />
|
||||
</el-select>
|
||||
<el-input v-model="festivalForm.name" @input="changeInput"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer #default="{ row, $index }">
|
||||
|
@ -38,14 +21,13 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<div class="table_page">
|
||||
<!-- 数据展示层 -->
|
||||
<el-table :data="tableData" border style="width: 100%;" :header-cell-style="{ 'text-align': 'center' }"
|
||||
@selection-change="handleSelectionChange" :cell-style="{ 'text-align': 'center', 'font-size': '16px' }">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="url" label="节日图片">
|
||||
<!-- 插槽,拿到父组件的值typeUrl -->
|
||||
<!-- scope 提供了关于当前行的信息 -->
|
||||
<template #default="scope"><img :src="scope.row.url" alt="" style="height: 50px;"></template>
|
||||
<template #default="scope"><img :src="downloadUrl + scope.row.url" alt="" style="height: 50px;"></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="节日名称"></el-table-column>
|
||||
<el-table-column prop="operation" label="操作">
|
||||
|
@ -60,22 +42,22 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ElMessage, type UploadProps, type UploadUserFile,type UploadFile, genFileId, type UploadRawFile} from 'element-plus';
|
||||
import {ElMessage, type UploadUserFile} from 'element-plus';
|
||||
import {ErrorInfo, SuccessInfo, WarnInfo} from '@/utils/messageInfo';
|
||||
import {onMounted, ref} from 'vue'
|
||||
import myAxios from '@/api/myAxios';
|
||||
import {form} from "@/utils/entityProduct/picUpload";
|
||||
import {downloadUrl} from '@/utils/formatImgUpload'
|
||||
import ImgSingleUpload from "@/utils/imgUpload/ImgSingleUpload.vue";
|
||||
|
||||
const fileSimple = ref() //单个文件
|
||||
const selectedItems = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const submitable = ref(true) //提交按钮禁用状态
|
||||
const loading = ref(false) //加载
|
||||
const festivalImg: any = ref<UploadUserFile[]>([]) //商品类别图片
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
//表单数据
|
||||
const festivalForm = ref({
|
||||
id: 0,
|
||||
|
@ -97,52 +79,14 @@ onMounted(() => {
|
|||
//获取类别列表
|
||||
const getFestivalList = async () => {
|
||||
const res = await myAxios.get('/festival/get')
|
||||
console.log('表格数据--->',res.data)
|
||||
if (res.data.code === 1) {
|
||||
tableData.value = res.data.data
|
||||
} else {
|
||||
ElMessage.error('获取类别列表失败,请检查服务')
|
||||
}
|
||||
}
|
||||
//上传图片,一张图片,不需要flag值
|
||||
const handleChange = async (file: any) => {
|
||||
fileSimple.value = file
|
||||
loading.value = true
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: formData.get("file") // 取出formData对象中的file
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
loading.value = false
|
||||
SuccessInfo('上传成功')
|
||||
submitable.value = false
|
||||
tempImgUrl.value = res.data.data
|
||||
} else {
|
||||
ErrorInfo(res.data.message)
|
||||
}
|
||||
}
|
||||
//上传图片移除
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
console.log(uploadFile, uploadFiles)
|
||||
// typeForm.value.typeUrl = ''
|
||||
festivalImg.value.splice(0, festivalImg.value.length) //移除展示即可
|
||||
submitable.value = true //再禁止上传
|
||||
}
|
||||
//图片上限警告
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
}
|
||||
|
||||
//新增节日
|
||||
const showForm = async () => {
|
||||
resetForm()
|
||||
|
@ -151,30 +95,33 @@ const showForm = async () => {
|
|||
dialogVisible.value = true;
|
||||
flag.value = 0
|
||||
}
|
||||
|
||||
//取消
|
||||
const cancel = () => {
|
||||
dialogVisible.value = false
|
||||
resetForm()
|
||||
}
|
||||
|
||||
//新增类别
|
||||
const addOrUpdateFestival = async () => {
|
||||
//判空
|
||||
// if (festivalForm.value.name?.indexOf(' ') !== -1 ||
|
||||
// festivalForm.value.name == '' || tempImgUrl.value == '') {
|
||||
// ElMessage({
|
||||
// type: 'warning',
|
||||
// message: '不能为空格/空字符串'
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
if (festivalForm.value.name?.indexOf(' ') !== -1 ||
|
||||
festivalForm.value.name == '') {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '不能为空格/空字符串'
|
||||
})
|
||||
return
|
||||
}
|
||||
//取消展示表单
|
||||
dialogVisible.value = false;
|
||||
console.log('添加的类别--->',festivalForm.value)
|
||||
const res = await myAxios.post('/festival/add', {
|
||||
name: festivalForm.value.name,
|
||||
url: '12321234123453124',
|
||||
url: festivalForm.value.url,
|
||||
//对齐后端请求体
|
||||
})
|
||||
console.log('后端返回的--->',res.data)
|
||||
if (res.data.code === 1) {
|
||||
//提交成功后,之间重置表格
|
||||
SuccessInfo('添加类别成功')
|
||||
|
@ -182,7 +129,6 @@ const addOrUpdateFestival = async () => {
|
|||
} else {
|
||||
ElMessage.error('提交失败')
|
||||
}
|
||||
|
||||
await getFestivalList()
|
||||
}
|
||||
//重置表单
|
||||
|
@ -212,4 +158,10 @@ const changeInput = () => { //当输入栏变化时解除禁用提交按钮
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<!-- 修改前请注释以前的 -->
|
||||
<!-- 搜索 -->
|
||||
<div class="table_page">
|
||||
<div>
|
||||
<el-input style="width: 240px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入商户单号"
|
||||
v-model="outTradeNo" size="default"></el-input>
|
||||
|
@ -9,9 +8,7 @@
|
|||
<el-button type="warning" @click="reset" size="default">重置</el-button>
|
||||
</div>
|
||||
<div style="margin: 15px 0">
|
||||
|
||||
</div>
|
||||
<!-- 数据展示 -->
|
||||
<el-table :data="tableData" border stripe header-cell-class-name="headerBg"
|
||||
:cell-style="{ 'text-align': 'center', 'font-size': '16px' }" @selection-change="handleSelectionChange"
|
||||
:header-cell-style="{ 'text-align': 'center' }">
|
||||
|
@ -30,8 +27,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间"></el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 分页器 -->
|
||||
<div style="padding: 10px 0">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
|
@ -39,15 +36,12 @@
|
|||
:small="null" :disabled="null" :background="null" layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total" />
|
||||
</div>
|
||||
<!-- 编辑/详情表单 -->
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage , type UploadProps , genFileId ,type UploadRawFile } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { ref, onMounted, inject } from 'vue';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { handleChange, removePic, handleRemove,Exceed_ProductImg, ImgArr ,editForm} from '@/utils/entityProduct/picUpload';
|
||||
const total = ref(0); //总页数
|
||||
const outTradeNo = ref('');
|
||||
const searchParams: any = ref({ //封装分页
|
||||
|
@ -82,8 +76,6 @@ const getProductList = async () => {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//详情或编辑
|
||||
|
||||
//处理行数大小变化
|
||||
|
@ -111,7 +103,8 @@ const handleSelectionChange =()=>{}
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.headerBg {
|
||||
background-color: #eee !important;
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -2,22 +2,15 @@
|
|||
<div class="flexCard">
|
||||
<el-card class="richTextPreview" shadow="never">
|
||||
<div class="titleText">移动端预览</div>
|
||||
<p v-html="form.richText"></p>
|
||||
<p v-html="previewRichText"></p>
|
||||
</el-card>
|
||||
<!-- 表单 ref 和 prop绑定 用于重置表单 -->
|
||||
<el-card class="form-FormContainer" shadow="never">
|
||||
<el-form ref="resetFormData" :model="form" label-width="auto" size="large">
|
||||
<el-form-item label="添加课程展示图片">
|
||||
<!-- 下面的event的作用,传入当前事件对象 -->
|
||||
<el-upload ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 0)"
|
||||
:on-exceed="Exceed_ProductImg" limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<el-form ref="resetFormData" :model="form" size="large">
|
||||
<el-form-item label="添加课程展示图片" label-width="auto">
|
||||
<ImgSingleUpload @update:goodImgArr="form.goodImg = $event"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="体验课名称" prop="name" style="width: 250px">
|
||||
<el-form-item label="体验课名称" prop="name" style="width: 250px" >
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品价格" prop="price">
|
||||
|
@ -30,8 +23,8 @@
|
|||
<el-form-item label="商品标签" prop="label">
|
||||
<el-input v-model="form.label" type="textarea" placeholder="使用英文;分隔符分开" style="width: 250px;" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<richTextUtil @richTextContent="getInfo"></richTextUtil>
|
||||
<el-form-item label="课程详情">
|
||||
<richTextUtil @richTextContent="getRichTextInfo"></richTextUtil>
|
||||
</el-form-item>
|
||||
<div class="totalButton">
|
||||
<el-form-item>
|
||||
|
@ -44,7 +37,7 @@
|
|||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="form-RichTextContainer" shadow="never">
|
||||
<calendarUtil @calendar-info="getInfo"></calendarUtil>
|
||||
<calendarUtil @calendar-info="getDateInfo"></calendarUtil>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
|
@ -52,13 +45,12 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, inject, toRaw } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { ElMessage, type UploadFile, type UploadProps, genFileId, type UploadRawFile } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import calendarUtil from '@/layout/components/calendarUtil.vue';
|
||||
import richTextUtil from '@/layout/components/richTextUtil.vue';
|
||||
import ImgSingleUpload from '@/utils/imgUpload/ImgSingleUpload.vue'
|
||||
|
||||
const fileSimple = ref() //单个文件
|
||||
const resetFormData = ref()
|
||||
const form = ref({
|
||||
name: '',
|
||||
|
@ -71,19 +63,19 @@ const form = ref({
|
|||
})
|
||||
//导入组件刷新
|
||||
const reload: any = inject("reload")
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const previewRichText = ref('') //预览富文本
|
||||
|
||||
onMounted(() => {
|
||||
// console.log(myDate.getHours()); //打印当前小时数
|
||||
})
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
console.log(uploadFile, uploadFiles)
|
||||
}
|
||||
|
||||
//提交表单
|
||||
const onSubmit = async () => {
|
||||
console.log('上传前--->',form.value)
|
||||
const values = Object.values(form.value);
|
||||
// 使用some()方法来检查是否有任何值为空
|
||||
console.log(form.value.appointmentDateAddRequestList)
|
||||
if (values.some(value => value === null || value === undefined || value === '') || form.value.appointmentDateAddRequestList.length == 0 ) {
|
||||
if (values.some(value => value === null || value === undefined || value === '' || value === 'PHA+PGJyPjwvcD4=') || form.value.appointmentDateAddRequestList.length == 0 ) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '请检查表单数据是否完整填写'
|
||||
|
@ -96,7 +88,7 @@ const onSubmit = async () => {
|
|||
price: form.value.price,
|
||||
goodImg: form.value.goodImg,
|
||||
intro: form.value.intro,
|
||||
richTetx: form.value.richText,
|
||||
richText: form.value.richText,
|
||||
label: form.value.label,
|
||||
appointmentDateAddRequestList: toRaw(form.value.appointmentDateAddRequestList)
|
||||
})
|
||||
|
@ -112,58 +104,49 @@ const onSubmit = async () => {
|
|||
return;
|
||||
}
|
||||
}
|
||||
//图片上传请求 此请求只要选择了图片,就会默认上传
|
||||
const handleChange = async (file: any, flag: number) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
// 取出formData对象中的file
|
||||
file: formData.get("file")
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
//三元运算 当flag为0时,赋值给商品图片 flag为1时,赋值给详情图片
|
||||
form.value.goodImg = res.data.data
|
||||
}
|
||||
}
|
||||
|
||||
//清除表单
|
||||
const resetForm = () => {
|
||||
resetFormData.value.resetFields()
|
||||
}
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
}
|
||||
const getInfo =(info:any)=>{
|
||||
console.log('info-->',info);
|
||||
|
||||
const getRichTextInfo =(info:any)=>{
|
||||
// console.log('info-->',info);
|
||||
form.value.richText = info
|
||||
form.value.richText = encode64(info)
|
||||
previewRichText.value = info
|
||||
}
|
||||
|
||||
//字符串转为base64编码
|
||||
function encode64(text: string): string {
|
||||
return btoa(String.fromCharCode(...new TextEncoder().encode(text)))
|
||||
}
|
||||
|
||||
const getDateInfo =(info: any)=> {
|
||||
console.log('info-->',info);
|
||||
form.value.appointmentDateAddRequestList = info
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.form-FormContainer {
|
||||
width: 450px;
|
||||
width: 600px;
|
||||
height: 800px;
|
||||
overflow: auto;
|
||||
min-width: 600px;
|
||||
/* margin: 0 auto; */
|
||||
}
|
||||
|
||||
.form-RichTextContainer {
|
||||
width: 550px;
|
||||
min-width: 550px;
|
||||
}
|
||||
|
||||
.flexCard {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
min-width: 1000px;
|
||||
}
|
||||
|
||||
.richTextPreview {
|
||||
|
@ -172,6 +155,7 @@ const getInfo =(info:any)=>{
|
|||
word-break: break-all;
|
||||
width: 400px;
|
||||
margin-right: 10px;
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
.totalButton {
|
||||
|
@ -179,5 +163,8 @@ const getInfo =(info:any)=>{
|
|||
justify-content: space-evenly;
|
||||
/* 盒子里面水平分隔开 */
|
||||
}
|
||||
|
||||
.titleText {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<!-- 修改前请注释以前的 -->
|
||||
<!-- 搜索 -->
|
||||
<div class="table_page">
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-input style="width: 200px; height: 30px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入课程名称"
|
||||
v-model="productName"></el-input>
|
||||
|
@ -38,7 +37,7 @@
|
|||
<el-table-column prop="goodImg" label="课程图片">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<img :src="scope.row.goodImg" alt="" style="height: 50px;">
|
||||
<img :src="downloadUrl + scope.row.goodImg" alt="" style="height: 50px;">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -114,57 +113,7 @@
|
|||
:small="null" :disabled="null" :background="null" layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total" />
|
||||
</div>
|
||||
<!-- 编辑/详情表单 -->
|
||||
<el-dialog v-model="DialogVisible" :title="title">
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-form-item label="商品编号">
|
||||
<el-input v-model="editForm.id" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图片">
|
||||
<div v-if="editForm.goodImg">
|
||||
<img :src="editForm.goodImg" alt="商品图标" class="thumbnail" style="width: 100px; height: 100px;" />
|
||||
</div>
|
||||
<el-upload ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 0)" :on-exceed="Exceed_ProductImg"
|
||||
limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称">
|
||||
<el-input v-model="editForm.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品价格" prop="price">
|
||||
<el-input-number v-model="editForm.price" min="0" :precision="2" :step="0.5" />
|
||||
<p>元</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品标签">
|
||||
<el-input v-model="editForm.label"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图文">
|
||||
<div v-if="editForm.detailImg">
|
||||
<img :src="editForm.detailImg" alt="商品图标" class="thumbnail" style="width: 100px; height: 100px;" />
|
||||
</div>
|
||||
<el-upload ref="uploadProductDetail" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 1)" :on-exceed="Exceed_ProductDetail"
|
||||
limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品描述">
|
||||
<el-input type="textarea" v-model="editForm.introDetail"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="DialogVisible = false" :disabled="disabled">取消</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<!-- 时间段抽屉 -->
|
||||
<el-drawer
|
||||
v-model="drawer"
|
||||
|
@ -228,11 +177,12 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage , type UploadProps , genFileId ,type UploadRawFile } from 'element-plus';
|
||||
import {ref, onMounted, inject, toRaw} from 'vue';
|
||||
import {ref, onMounted, inject} from 'vue';
|
||||
import myAxios from "@/api/myAxios";
|
||||
import calendarUtil from '@/layout/components/calendarUtil.vue';
|
||||
import emitter from "@/utils/emitter";
|
||||
import { useRouter } from "vue-router";
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
|
||||
const router = useRouter(); //路由
|
||||
const total = ref(0); //总页数
|
||||
|
@ -245,16 +195,9 @@ const searchParams: any = ref({ //封装分页
|
|||
})
|
||||
const tableData : any= ref([]);
|
||||
const appointmentDateArr : any = ref([])
|
||||
const disabled = ref(true)
|
||||
const title = ref('') //表单名字
|
||||
const productName = ref('');
|
||||
const DialogVisible = ref(false);
|
||||
const state = ref(''); //根据商品上架状态select栏
|
||||
const editForm : any = ref({});
|
||||
const reload : any = inject("reload") //页面重新刷新
|
||||
const fileSimple = ref()
|
||||
const uploadProductImg : any = ref() //图片上传的ref绑定
|
||||
const uploadProductDetail : any = ref() //图片上传的ref绑定
|
||||
//抽屉变量
|
||||
const drawer = ref(false) //抽屉打开
|
||||
const drawerDate : any = ref({}) //当前日期、时间段人数信息
|
||||
|
@ -313,22 +256,7 @@ const getProductList = async () => {
|
|||
});
|
||||
}
|
||||
}
|
||||
const saveEdit = async () => { //编辑商品
|
||||
const res = await myAxios.post('/goods/service/single/update',{...editForm.value})
|
||||
if(res.data.code === 1) {
|
||||
DialogVisible.value = false
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '更新成功'
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请检查字段是否正确填写'
|
||||
})
|
||||
}
|
||||
console.log(res.data);
|
||||
}
|
||||
|
||||
const searchByState = (event : any) => { //通过商品是否上架/下架搜索
|
||||
searchParams.value.isShelves = event
|
||||
searchParams.value.current = 1
|
||||
|
@ -356,11 +284,9 @@ const ReviseOrView = (index: number, row: any , flag : number) => {
|
|||
flag: flag
|
||||
}
|
||||
})
|
||||
//flag值不同显示不同内容 disabled开启和关闭
|
||||
flag ? (title.value = "编辑商品" , disabled.value = false) : (title.value = "商品详情" , disabled.value = true)
|
||||
editForm.value = JSON.parse(JSON.stringify(row));
|
||||
};
|
||||
//下架商品(待优化,有问题,逻辑有问题)
|
||||
|
||||
//下架商品
|
||||
const handleOff = async (row: any) => {
|
||||
console.log(row.isShelves);
|
||||
const res = await myAxios.post('/goods/service/shelves',{id: row.id})
|
||||
|
@ -385,45 +311,8 @@ const handleCurrentChange = (Current: any) => {
|
|||
//重置按钮
|
||||
const reset = () => {
|
||||
reload()
|
||||
};
|
||||
// 上传图片移除 --逻辑上移除
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
console.log(uploadFile, uploadFiles)
|
||||
}
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files , flag) => { //覆盖商品照片
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
}
|
||||
const Exceed_ProductDetail: UploadProps['onExceed'] = (files) => { //覆盖商品详情图片
|
||||
uploadProductDetail.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductDetail.value!.handleStart(file)
|
||||
}
|
||||
// 图片上传请求 此请求只要选择了图片,就会默认上传
|
||||
const handleChange = async (file: any, flag: number) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: formData.get("file") // 取出formData对象中的file
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
//三元运算 当flag为0时,赋值给商品图片 flag为1时,赋值给详情图片
|
||||
flag ? editForm.value.detailImg = res.data.data : editForm.value.goodImg = res.data.data
|
||||
console.log('res--->',res.data.data)
|
||||
}
|
||||
}
|
||||
|
||||
const onSearch = (data : String)=>{ //搜索按钮方法
|
||||
searchParams.value.name = data
|
||||
searchParams.value.current = 1
|
||||
|
@ -635,7 +524,8 @@ const submitDate = async ()=> { //提交日期方法
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.headerBg {
|
||||
background-color: #eee !important;
|
||||
.table_page {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -2,22 +2,16 @@
|
|||
<div class="flexCard">
|
||||
<el-card class="richTextPreview" shadow="never">
|
||||
<div class="titleText">移动端预览</div>
|
||||
<p v-html="detailFrom.richText"></p>
|
||||
<p v-html="previewRichText"></p>
|
||||
</el-card>
|
||||
<!-- 表单 ref 和 prop绑定 用于重置表单 -->
|
||||
<el-card class="form-container" shadow="never">
|
||||
<div class="form">
|
||||
<el-form ref="resetFormData" :model="detailFrom" label-width="auto" size="large" :rules="rules" :disabled="true">
|
||||
<el-form ref="resetFormData" :model="detailFrom" label-width="auto" size="large" :disabled="disabledRichText" >
|
||||
<div>
|
||||
<el-form-item label="添加商品图片">
|
||||
<!-- 下面的event的作用,传入当前事件对象 -->
|
||||
<el-upload v-model:file-list="ImgArr" ref="uploadProductImg" action="#" list-type="picture-card" :auto-upload="false" multiple="true"
|
||||
:on-remove="handleRemove" @change="(event: any) => handleChange(event, 2)" :on-exceed="Exceed_ProductImg"
|
||||
limit="7">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<PreviewSingleImgUpload :ImgUrlList="previewImgUrl" @update:goodImgArr="detailFrom.goodImg = $event"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="NamePrice">
|
||||
|
@ -31,12 +25,12 @@
|
|||
</div>
|
||||
<div class="IntroInven">
|
||||
<el-form-item label="课程简介" prop="intro">
|
||||
<el-input v-model="detailFrom.intro" type="textarea" placeholder="产品尺寸,服务等" maxlength="30" show-word-limit
|
||||
<el-input v-model="detailFrom.intro" type="textarea" placeholder="产品尺寸,服务等" maxlength="60" show-word-limit
|
||||
style="width: 300px;" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="课程详情图" prop="richText">
|
||||
<richTextUtil @richTextContent="getInfo" v-model:disableRich="disabledRichText"/>
|
||||
<el-form-item label="课程详情图" prop="richText" v-loading="loading">
|
||||
<richTextUtil @richTextContent="getInfo" v-model:disableRich="disabledRichText" v-model:context="previewRichText"/>
|
||||
</el-form-item>
|
||||
<div class="btnBox">
|
||||
<el-form-item>
|
||||
|
@ -53,21 +47,18 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, inject, reactive , onBeforeMount} from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import {type FormRules, type UploadUserFile} from 'element-plus';
|
||||
import { SuccessInfo, WarnInfo, CommInfo } from '@/utils/messageInfo'; //封装ElMessage提示
|
||||
import { ref, onMounted , onBeforeMount} from 'vue';
|
||||
import { type UploadUserFile} from 'element-plus';
|
||||
import { SuccessInfo, WarnInfo } from '@/utils/messageInfo'; //封装ElMessage提示
|
||||
import myAxios from "@/api/myAxios";
|
||||
import { saveBtn, invInput } from '@/utils/entityProduct/globalVar';
|
||||
import { validateName, validateIntro, validateDetail } from '@/utils/entityProduct/FormRules';
|
||||
import { handleChange, handleRemove, form, Exceed_ProductImg } from '@/utils/entityProduct/picUpload';
|
||||
import { saveBtn } from '@/utils/entityProduct/globalVar';
|
||||
import richTextUtil from '@/layout/components/richTextUtil.vue';
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRoute ,useRouter } from "vue-router";
|
||||
import PreviewSingleImgUpload from "@/utils/imgUpload/PreviewSingleImgUpload.vue";
|
||||
|
||||
|
||||
const route = useRoute(); //路由
|
||||
const resetFormData = ref()
|
||||
const reload: any = inject("reload") //导入组件刷新
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const ImgArr: any = ref<UploadUserFile[]>([])
|
||||
const detailFrom : any = ref({
|
||||
name: '', //商品名称
|
||||
|
@ -80,25 +71,32 @@ const detailFrom : any = ref({
|
|||
inventory: '', //库存
|
||||
richText: ''
|
||||
})
|
||||
|
||||
const previewImgUrl = ref('') //预览图字符串
|
||||
const previewRichText = ref('')
|
||||
const disabledRichText:any = ref(false);
|
||||
const loading = ref(true)
|
||||
const router = useRouter()
|
||||
|
||||
onBeforeMount(()=>{
|
||||
if(route.params.flag === '0'){
|
||||
disabledRichText.value = true;
|
||||
}
|
||||
getServiceInfo() //编辑页查询商品信息
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getServiceInfo() //编辑页查询商品信息
|
||||
// console.log('id---->',route.params.id)
|
||||
// console.log('flag---->',route.params.flag)
|
||||
setTimeout(()=>{
|
||||
loading.value = false
|
||||
},1500)
|
||||
})
|
||||
|
||||
const getServiceInfo = async () => {
|
||||
const res = await myAxios.post("/goods/service/list/id",{ id: route.params.id })
|
||||
console.log('res--->',res.data)
|
||||
if(res.data.code == 1){
|
||||
previewImgUrl.value = res.data.data.goodImg
|
||||
detailFrom.value = res.data.data
|
||||
previewRichText.value = res.data.data.richText
|
||||
ImgArr.value.splice(0,ImgArr.value.length)
|
||||
var tempArr = res.data.data.goodImg.split(';')
|
||||
tempArr.forEach((item: any) => {
|
||||
|
@ -119,12 +117,11 @@ const onSubmit = async () => {
|
|||
WarnInfo('请检查表单数据是否完整填写')
|
||||
return; //空返回结束函数
|
||||
}
|
||||
const res = await myAxios.post('/goods/add', { ...detailFrom.value })
|
||||
const res = await myAxios.post('/goods/service/single/update', { ...detailFrom.value })
|
||||
// console.log(res.data);
|
||||
if (res.data.code === 1) {
|
||||
SuccessInfo('提交成功')
|
||||
detailFrom.value = {} //12.18改
|
||||
reload() //上传完后重置表单
|
||||
await router.replace('/ProductCenter')
|
||||
} else {
|
||||
WarnInfo('服务错误')
|
||||
return;
|
||||
|
@ -135,14 +132,16 @@ const onSubmit = async () => {
|
|||
const resetForm = () => {
|
||||
resetFormData.value.resetFields()
|
||||
}
|
||||
const rules = reactive<FormRules<typeof form>>({ //表单校验规则
|
||||
name: [{ validator: validateName, trigger: 'blur' }],
|
||||
intro: [{ validator: validateIntro, trigger: 'blur' }],
|
||||
introDetail: [{ validator: validateDetail, trigger: 'blur' }]
|
||||
})
|
||||
|
||||
// const rules = reactive<FormRules<typeof form>>({ //表单校验规则
|
||||
// name: [{ validator: validateName, trigger: 'blur' }],
|
||||
// intro: [{ validator: validateIntro, trigger: 'blur' }],
|
||||
// introDetail: [{ validator: validateDetail, trigger: 'blur' }]
|
||||
// })
|
||||
|
||||
const getInfo = (info: any) => { //富文本赋值
|
||||
console.log('info', info)
|
||||
// console.log('info', info)
|
||||
previewRichText.value = info
|
||||
detailFrom.value.richText = info
|
||||
}
|
||||
</script>
|
||||
|
@ -158,11 +157,15 @@ const getInfo = (info: any) => { //富文本赋值
|
|||
overflow-y: auto;
|
||||
word-break: break-all;
|
||||
width: 400px;
|
||||
min-width: 400px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
width: 700px;
|
||||
min-width: 700px;
|
||||
height: 800px;
|
||||
overflow: auto;
|
||||
/* margin: 0 auto; */
|
||||
}
|
||||
.form {
|
||||
|
@ -186,4 +189,9 @@ const getInfo = (info: any) => { //富文本赋值
|
|||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.titleText {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
|
@ -1,112 +1,72 @@
|
|||
<template>
|
||||
<div class="detail-container">
|
||||
<div class="detail-container">
|
||||
<el-card shadow="hover">
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-form-item label="头像">
|
||||
<el-upload v-model:file-list="ImgArr" ref="uploadProductImg" action="#" list-type="picture-card"
|
||||
:auto-upload="false" multiple="true" :on-remove="removePic" @change="(event: any) => handleChange(event)"
|
||||
:on-exceed="Exceed_ProductImg" limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="账号">
|
||||
<el-input v-model="userForm.userAccount"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="userForm.userPassword" type="password" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="userForm.userName" />
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-form-item label="头像">
|
||||
<PreviewSingleImgUpload :ImgUrlList="userForm.userAvatar" @update:goodImgArr="userForm.userAvatar = $event"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码">
|
||||
<el-input v-model="userForm.phone" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="账号">
|
||||
<el-input v-model="userForm.userAccount"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="userForm.userPassword" type="password" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="userForm.userName" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="积分">
|
||||
<el-input v-model="userForm.points"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="积分">
|
||||
<el-input v-model="userForm.points"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<div style="display: flex;">
|
||||
<el-button @click="changeStatus">{{ btnText }}</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage, type UploadProps, type UploadUserFile,type UploadFile, genFileId, type UploadRawFile } from 'element-plus';
|
||||
import myAxios from '@/api/myAxios';
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ErrorInfo, SuccessInfo, WarnInfo } from '@/utils/messageInfo';
|
||||
import { ref, onBeforeMount } from 'vue'
|
||||
import { SuccessInfo, WarnInfo } from '@/utils/messageInfo';
|
||||
import { useRoute } from "vue-router";
|
||||
import PreviewSingleImgUpload from "@/utils/imgUpload/PreviewSingleImgUpload.vue";
|
||||
|
||||
|
||||
const ImgArr: any = ref<UploadUserFile[]>([]) //给商品中心页面编辑商品使用
|
||||
const disabled = ref(true) //表单是否禁用
|
||||
const userForm: any = ref({}) //用户表单
|
||||
const fileSimple = ref() //单个文件
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const tempAvatar = ref('') //暂存的用户头像
|
||||
const btnText = ref('编辑') //编辑按钮
|
||||
const route = useRoute()
|
||||
|
||||
onMounted(()=>{
|
||||
onBeforeMount(()=>{
|
||||
if(route.params.flag === '1') {
|
||||
disabled.value = false
|
||||
}
|
||||
getUserInfo()
|
||||
console.log('用户id---->',route.params.id)
|
||||
console.log('标识--->',route.params.flag)
|
||||
})
|
||||
|
||||
//获取当前登陆用户信息
|
||||
const getUserInfo = async () => {
|
||||
const res = await myAxios.get('/user/get/web/login')
|
||||
// console.log(res.data.data)
|
||||
userForm.value = res.data.data
|
||||
ImgArr.value.push({
|
||||
url: res.data.data.userAvatar
|
||||
})
|
||||
}
|
||||
//图片上限警告
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
}
|
||||
|
||||
//上传图片方法
|
||||
const handleChange = async (file: any) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: formData.get("file") // 取出formData对象中的file
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
tempAvatar.value = res.data.data
|
||||
console.log('后端返回---->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
userForm.value = res.data.data
|
||||
}
|
||||
}
|
||||
|
||||
//移除图片方法
|
||||
const removePic: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFile表示当前删除的图片,uploadFiles是还剩余的图片信息
|
||||
userForm.value.userAvatar = ''
|
||||
}
|
||||
|
||||
const saveEdit = async ()=>{ //保存用户信息
|
||||
const res = await myAxios.post('/user/update',{
|
||||
id: userForm.value.id,
|
||||
userPassword: userForm.value.userPassword,
|
||||
userName: userForm.value.userName,
|
||||
userAvatar: tempAvatar.value,
|
||||
userAvatar: userForm.value.userAvatar,
|
||||
phone: userForm.value.phone,
|
||||
userRole: userForm.value.userRole
|
||||
})
|
||||
|
@ -118,25 +78,14 @@ const saveEdit = async ()=>{ //保存用户信息
|
|||
WarnInfo('更新失败')
|
||||
}
|
||||
}
|
||||
|
||||
const changeStatus = async ()=> {
|
||||
if(btnText.value === '编辑') {
|
||||
tempAvatar.value = userForm.value.userAvatar
|
||||
btnText.value = '取消'
|
||||
disabled.value = false
|
||||
} else {
|
||||
btnText.value = '编辑'
|
||||
disabled.value = true
|
||||
//还差一步数据回显
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.detail-container {
|
||||
width: 80%;
|
||||
padding: 20px 20px 20px 20px;
|
||||
margin: 20px auto;
|
||||
width: 80%;
|
||||
padding: 20px 20px 20px 20px;
|
||||
margin: 20px auto;
|
||||
min-width: 1000px;
|
||||
}
|
||||
</style>
|
91
src/views/User/SingleUserDetail.vue
Normal file
91
src/views/User/SingleUserDetail.vue
Normal file
|
@ -0,0 +1,91 @@
|
|||
<template>
|
||||
<div class="detail-container">
|
||||
<el-card shadow="hover">
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-form-item label="头像">
|
||||
<PreviewSingleImgUpload :ImgUrlList="userForm.userAvatar" @update:goodImgArr="userForm.userAvatar = $event"/>
|
||||
</el-form-item>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="账号">
|
||||
<el-input v-model="userForm.userAccount"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="userForm.userPassword" type="password" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="userForm.userName" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="积分">
|
||||
<el-input v-model="userForm.points"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<div style="display: flex;">
|
||||
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import myAxios from '@/api/myAxios';
|
||||
import { ref, onBeforeMount } from 'vue'
|
||||
import { SuccessInfo, WarnInfo } from '@/utils/messageInfo';
|
||||
import { useRoute } from "vue-router";
|
||||
import PreviewSingleImgUpload from "@/utils/imgUpload/PreviewSingleImgUpload.vue";
|
||||
|
||||
|
||||
const disabled = ref(true) //表单是否禁用
|
||||
const userForm: any = ref({}) //用户表单
|
||||
const tempAvatar = ref('') //暂存的用户头像
|
||||
const route = useRoute()
|
||||
|
||||
onBeforeMount(()=>{
|
||||
if(route.params.flag === '1') {
|
||||
disabled.value = false
|
||||
}
|
||||
getUserInfo()
|
||||
console.log('用户id---->',route.params.id)
|
||||
console.log('标识--->',route.params.flag)
|
||||
})
|
||||
|
||||
//获取当前登陆用户信息
|
||||
const getUserInfo = async () => {
|
||||
const res = await myAxios.post('/user/query/id',{ id: route.params.id })
|
||||
console.log('后端返回---->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
userForm.value = res.data.data
|
||||
}
|
||||
}
|
||||
|
||||
const saveEdit = async ()=>{ //保存用户信息
|
||||
const res = await myAxios.post('/user/update',{
|
||||
id: userForm.value.id,
|
||||
userPassword: userForm.value.userPassword,
|
||||
userName: userForm.value.userName,
|
||||
userAvatar: userForm.value.userAvatar,
|
||||
phone: userForm.value.phone,
|
||||
userRole: userForm.value.userRole
|
||||
})
|
||||
console.log('更新信息--->',res.data)
|
||||
if (res.data.code === 1) {
|
||||
disabled.value = true
|
||||
SuccessInfo('更新成功')
|
||||
} else {
|
||||
WarnInfo('更新失败')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.detail-container {
|
||||
width: 80%;
|
||||
padding: 20px 20px 20px 20px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
</style>
|
|
@ -1,61 +0,0 @@
|
|||
<template>
|
||||
<el-upload
|
||||
ref="uploadProductImg"
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
:auto-upload="false"
|
||||
multiple="true"
|
||||
:on-remove="handleRemove"
|
||||
@change="(event: any) => handleChange(event, 0)"
|
||||
:on-exceed="Exceed_ProductImg"
|
||||
limit="1" >
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<div>图片url: {{ imgUrl }}</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted , inject} from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { ElMessage, type UploadFile , type UploadProps , genFileId , type UploadRawFile} from 'element-plus';
|
||||
import myAxios from "@/api/myAxios";
|
||||
const fileSimple = ref() //单个文件
|
||||
const uploadProductImg : any = ref() //图片上传的ref绑定
|
||||
const imgUrl = ref('')
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
console.log(uploadFile, uploadFiles)
|
||||
}
|
||||
const handleChange = async (file: any, flag: number) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
// 取出formData对象中的file
|
||||
file: formData.get("file")
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
//三元运算 当flag为0时,赋值给商品图片 flag为1时,赋值给详情图片
|
||||
imgUrl.value = res.data.data
|
||||
}
|
||||
}
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -15,19 +15,17 @@
|
|||
</el-table-column>
|
||||
<el-table-column prop="userName" label="用户昵称"></el-table-column>
|
||||
<el-table-column prop="userAvatar" label="头像">
|
||||
<template #default="scope"><img :src="scope.row.userAvatar" alt="" style="height: 50px;"></template>
|
||||
<template #default="scope"><img :src="downloadUrl + scope.row.userAvatar" alt="" style="height: 50px;"></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="userRole" label="身份">
|
||||
<template #default="scope">
|
||||
{{ scope.row.userRole === 'boss' ? '管理员' : '小程序用户' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="phone" label="手机号"></el-table-column>
|
||||
<!-- <el-table-column prop="isDelete" label="是否封禁"></el-table-column>-->
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="checkDetail(scope.row)">详情</el-button>
|
||||
<el-button size="small" type="primary" @click="editUser(scope.row)">编辑</el-button>
|
||||
<el-button size="small" @click="checkDetail(scope.row,0)">详情</el-button>
|
||||
<el-button size="small" type="primary" @click="checkDetail(scope.row,1)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -37,53 +35,15 @@
|
|||
@size-change="handleSizeChange" @current-change="handleCurrentChange" :small="null" background
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="total" />
|
||||
</div>
|
||||
<!-- 单个用户表单 -->
|
||||
<el-dialog v-model="DialogVisible" :title="title">
|
||||
<el-form label-width="100px" :disabled="disabled">
|
||||
<el-form-item label="头像">
|
||||
<el-upload v-model:file-list="ImgArr" ref="uploadProductImg" action="#" list-type="picture-card"
|
||||
:auto-upload="false" multiple="true" :on-remove="removePic" @change="(event: any) => handleChange(event)"
|
||||
:on-exceed="Exceed_ProductImg" limit="1">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="账号">
|
||||
<el-input v-model="userForm.userAccount" style="width: 200px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="userForm.userPassword" type="password"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="userForm.userName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码">
|
||||
<el-input v-model="userForm.phone" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<el-form-item label="积分">
|
||||
<el-input v-model="userForm.points"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="DialogVisible = false" :disabled="disabled">取消</el-button>
|
||||
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage, type UploadProps, type UploadUserFile,type UploadFile, genFileId, type UploadRawFile } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import myAxios from '@/api/myAxios';
|
||||
import { downloadUrl } from '@/utils/formatImgUpload'
|
||||
import { ref, onMounted, inject } from 'vue'
|
||||
import { ErrorInfo, SuccessInfo, WarnInfo } from '@/utils/messageInfo';
|
||||
const ImgArr: any = ref<UploadUserFile[]>([]) //给商品中心页面编辑商品使用
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
//获取的所有数据
|
||||
const tableData = ref([])
|
||||
//筛选条数
|
||||
|
@ -96,13 +56,8 @@ const searchParams: any = ref({
|
|||
pageSize: 5
|
||||
})
|
||||
const reload: any = inject("reload") //导入组件刷新
|
||||
const DialogVisible = ref(false) //是否显示表格
|
||||
const title = ref('编辑用户') //表单标题
|
||||
const disabled = ref(false) //表单是否禁用
|
||||
const userForm: any = ref({}) //用户表单
|
||||
const fileSimple = ref() //单个文件
|
||||
const uploadProductImg: any = ref() //图片上传的ref绑定
|
||||
const tempAvatar = ref('') //暂存此行的用户头像
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(() => {
|
||||
getUserList()
|
||||
})
|
||||
|
@ -111,37 +66,7 @@ const username = ref('')
|
|||
const reset = () => {
|
||||
reload()
|
||||
}
|
||||
//上传图片方法
|
||||
const handleChange = async (file: any) => {
|
||||
fileSimple.value = file
|
||||
let formData = new FormData() //这一步很重要 创建一个FormData对象
|
||||
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw 才是文件主体 将其以文件的格式插入formData
|
||||
const res = await myAxios({ //编写请求,与以前的请求不同,这一次要指定好头部类型和文件类型
|
||||
url: '/file/uploadFile',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: formData.get("file") // 取出formData对象中的file
|
||||
}
|
||||
})
|
||||
if (res.data.code === 1) {
|
||||
tempAvatar.value = res.data.data
|
||||
}
|
||||
}
|
||||
//移除图片方法
|
||||
const removePic: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFile表示当前删除的图片,uploadFiles是还剩余的图片信息
|
||||
userForm.value.userAvatar = ''
|
||||
}
|
||||
//图片上限警告
|
||||
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
uploadProductImg.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadProductImg.value!.handleStart(file)
|
||||
}
|
||||
|
||||
//用户信息列表
|
||||
const getUserList = async () => {
|
||||
//为什么要用展开表达式({...}),因为是POST请求,如果直接对象.value,传的是Object类型
|
||||
|
@ -180,46 +105,17 @@ const onSearch = (data: String) => {
|
|||
searchParams.value.current = 1
|
||||
getUserList()
|
||||
}
|
||||
const checkDetail = (obj: any) => { //查看详情方法
|
||||
title.value = '查看用户'
|
||||
ImgArr.value.splice(0, ImgArr.value.length)
|
||||
ImgArr.value.push({
|
||||
url: obj.userAvatar
|
||||
const checkDetail = (obj: any, flag : any) => { //查看详情方法
|
||||
console.log('用户对象--->',obj)
|
||||
router.push({
|
||||
name: '用户详情',
|
||||
params: {
|
||||
id: obj.id,
|
||||
flag: flag
|
||||
}
|
||||
})
|
||||
disabled.value = true
|
||||
DialogVisible.value = true
|
||||
userForm.value = obj
|
||||
}
|
||||
const editUser = (obj: any) => { //编辑方法
|
||||
userForm.value = JSON.parse(JSON.stringify(obj)) //深浅拷贝
|
||||
tempAvatar.value = userForm.value.userAvatar //暂存
|
||||
disabled.value = false
|
||||
title.value = '编辑用户'
|
||||
ImgArr.value.splice(0, ImgArr.value.length)
|
||||
ImgArr.value.push({
|
||||
url: obj.userAvatar
|
||||
})
|
||||
DialogVisible.value = true
|
||||
}
|
||||
const saveEdit = async () => { //更新用户信息
|
||||
console.log('编辑后的信息--->', userForm.value);
|
||||
const res = await myAxios.post('/user/update', {
|
||||
id: userForm.value.id,
|
||||
userPassword: userForm.value.userPassword,
|
||||
userName: userForm.value.userName,
|
||||
userAvatar: tempAvatar.value,
|
||||
phone: userForm.value.phone,
|
||||
userRole: userForm.value.userRole
|
||||
})
|
||||
console.log('后端返回--->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
SuccessInfo('更新成功')
|
||||
DialogVisible.value = false
|
||||
getUserList()
|
||||
} else {
|
||||
ErrorInfo('更新失败')
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -1,128 +1,94 @@
|
|||
<template>
|
||||
<el-container class="layout-container-demo" style="height: 500px">
|
||||
<el-aside width="200px">
|
||||
<el-scrollbar>
|
||||
<el-menu :default-openeds="['1', '3']">
|
||||
<el-sub-menu index="1">
|
||||
<template #title>
|
||||
<el-icon><message /></el-icon>Navigator One
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<template #title>Group 1</template>
|
||||
<el-menu-item index="1-1">Option 1</el-menu-item>
|
||||
<el-menu-item index="1-2">Option 2</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-menu-item-group title="Group 2">
|
||||
<el-menu-item index="1-3">Option 3</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-sub-menu index="1-4">
|
||||
<template #title>Option4</template>
|
||||
<el-menu-item index="1-4-1">Option 4-1</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="2">
|
||||
<template #title>
|
||||
<el-icon><icon-menu /></el-icon>Navigator Two
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<template #title>Group 1</template>
|
||||
<el-menu-item index="2-1">Option 1</el-menu-item>
|
||||
<el-menu-item index="2-2">Option 2</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-menu-item-group title="Group 2">
|
||||
<el-menu-item index="2-3">Option 3</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-sub-menu index="2-4">
|
||||
<template #title>Option 4</template>
|
||||
<el-menu-item index="2-4-1">Option 4-1</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="3">
|
||||
<template #title>
|
||||
<el-icon><setting /></el-icon>Navigator Three
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<template #title>Group 1</template>
|
||||
<el-menu-item index="3-1">Option 1</el-menu-item>
|
||||
<el-menu-item index="3-2">Option 2</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-menu-item-group title="Group 2">
|
||||
<el-menu-item index="3-3">Option 3</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-sub-menu index="3-4">
|
||||
<template #title>Option 4</template>
|
||||
<el-menu-item index="3-4-1">Option 4-1</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</el-sub-menu>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
</el-aside>
|
||||
<el-upload
|
||||
v-model:file-list="ImgList"
|
||||
:action="uploadUrl"
|
||||
list-type="picture-card"
|
||||
:http-request="customUpload"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="ExceedImg"
|
||||
limit="7"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
|
||||
<el-container>
|
||||
<el-header style="text-align: right; font-size: 12px">
|
||||
<div class="toolbar">
|
||||
<el-dropdown>
|
||||
<el-icon style="margin-right: 8px; margin-top: 1px">
|
||||
<setting />
|
||||
</el-icon>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>View</el-dropdown-item>
|
||||
<el-dropdown-item>Add</el-dropdown-item>
|
||||
<el-dropdown-item>Delete</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<span>Tom</span>
|
||||
</div>
|
||||
</el-header>
|
||||
|
||||
<el-main>
|
||||
<el-scrollbar>
|
||||
<el-table :data="tableData">
|
||||
<el-table-column prop="date" label="Date" width="140" />
|
||||
<el-table-column prop="name" label="Name" width="120" />
|
||||
<el-table-column prop="address" label="Address" />
|
||||
</el-table>
|
||||
</el-scrollbar>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<el-image :src="dialogImageUrl"/>
|
||||
</el-dialog>
|
||||
<el-button type="primary" @click="submitForm">看看删除后的图片</el-button>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { Menu as IconMenu, Message, Setting } from '@element-plus/icons-vue'
|
||||
import myAxios from '@/api/myAxios'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import type { UploadProps, UploadUserFile } from 'element-plus'
|
||||
import { uploadUrl, downloadUrl } from '@/utils/formatImgUpload'
|
||||
import { WarnInfo } from "@/utils/messageInfo";
|
||||
|
||||
const item = {
|
||||
date: '2016-05-02',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
const goodImgStr = ref('') //图片字符串
|
||||
const goodImgArr= ref<String[]>([]) //后端数据库返回的图片objectKey
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
getProductInfo()
|
||||
})
|
||||
|
||||
const getProductInfo = async () => {
|
||||
const res = await myAxios.post('/goods/getById',{id: 498})
|
||||
console.log('图片信息--->',res.data.data.goodImg)
|
||||
goodImgArr.value = res.data.data.goodImg.split(';')
|
||||
console.log('图片数组---->',goodImgArr.value)
|
||||
goodImgArr.value.forEach(item => { //回显
|
||||
ImgList.value.push({
|
||||
url: downloadUrl + item
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const ImgList: any = ref([])
|
||||
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //前者是删掉的,后者是删掉后得数组
|
||||
console.log(uploadFile, uploadFiles)
|
||||
let deleteObjKey = uploadFile.url?.substring(downloadUrl.length)
|
||||
goodImgArr.value = goodImgArr.value.filter(item => item !== deleteObjKey)
|
||||
}
|
||||
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const submitForm = ()=>{ //测试格式化后的
|
||||
goodImgStr.value = goodImgArr.value.join(';')
|
||||
console.log('提交表单的goodImgStr',goodImgStr.value)
|
||||
}
|
||||
|
||||
const ExceedImg: UploadProps['onExceed'] = (files) => { //覆盖商品照片 'onExceed'当文件个数超过限制时,做出的判断
|
||||
WarnInfo('最多只能上传七张图片!')
|
||||
}
|
||||
//图片上传方法
|
||||
const customUpload = async (e:any) => {
|
||||
loading.value = true
|
||||
const res = await myAxios({
|
||||
url: e.action,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: {
|
||||
biz: "test",
|
||||
file: e.file
|
||||
}
|
||||
})
|
||||
console.log('图片上传结果--->',res.data)
|
||||
if(res.data.code === 1) {
|
||||
goodImgArr.value.push(res.data.data)
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
const tableData = ref(Array.from({ length: 20 }).fill(item))
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.layout-container-demo .el-header {
|
||||
position: relative;
|
||||
background-color: var(--el-color-primary-light-7);
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
.layout-container-demo .el-aside {
|
||||
color: var(--el-text-color-primary);
|
||||
background: var(--el-color-primary-light-8);
|
||||
}
|
||||
.layout-container-demo .el-menu {
|
||||
border-right: none;
|
||||
}
|
||||
.layout-container-demo .el-main {
|
||||
padding: 0;
|
||||
}
|
||||
.layout-container-demo .toolbar {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
right: 20px;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": ["env.d.ts", "src/**/*"],
|
||||
"include": ["env.d.ts", "src/**/*","src/**/*.ts"],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
|
|
Loading…
Reference in New Issue
Block a user