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