引入富文本,修改了一些bug

This commit is contained in:
yuanteng 2025-03-11 16:31:52 +08:00
parent 88999cb057
commit 1a336b2dac
21 changed files with 933 additions and 437 deletions

View File

@ -4,8 +4,8 @@ import router from '../router'
const myAxios = axios.create({
withCredentials:true,
// baseURL: 'http://localhost:9092/api'
baseURL: 'http://123.249.108.160:8888/api' //测试服务器
baseURL: 'http://localhost:9092/api'
// baseURL: 'http://123.249.108.160:8888/api' //测试服务器
// baseURL: 'http://154.8.193.216:9092/api', //隋雨霏服务器
// baseURL: 'http://154.8.193.216:9093/api' //隋雨霏服务器测试环境
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -65,7 +65,7 @@
</el-aside>
</template>
<script setup >
<script setup>
import {ref ,computed } from 'vue'
import { defineProps } from 'vue';
import emitter from '@/utils/emitter'
@ -91,7 +91,8 @@ import {
Discount,
Notification,
Tickets,
Money
Money,
Odometer
} from "@element-plus/icons-vue";
defineProps(['send-data'])
@ -120,7 +121,7 @@ emitter.on('Aside', (value) => {
//
const router = useRouter()
console.log('router--->',router.options.routes);
// console.log('router--->',router.options.routes);
//
const iconComponents = {
@ -144,7 +145,8 @@ const iconComponents = {
Discount,
Notification,
Tickets,
Money
Money,
Odometer
//
};
// layout
@ -168,10 +170,10 @@ const menuRoutes = computed(() => {
}
return route;
});
console.log('adj--->',adjustedRoutes);
// console.log('adj--->',adjustedRoutes);
return adjustedRoutes;
});
console.log('menuRoutes--->',menuRoutes.value);
// console.log('menuRoutes--->',menuRoutes.value);
</script>
<style scoped>

View File

@ -146,6 +146,7 @@ const subList =(index: number)=>{
}
}
const saveTime =(index : number)=>{ //periodObj
try{
periodObj.value.timePeriodAddRequestList[index].timeSlot = timePickArr.value[index][0]+'-'+timePickArr.value[index][1]
} catch {

View File

@ -0,0 +1,57 @@
<template>
<div style="border: 1px solid #ccc">
<Toolbar style="border-bottom: 1px solid #ccc; width: 400px;" :editor="editorRef" :defaultConfig="toolbarConfig"
:mode="mode" />
<Editor style="height: 500px; overflow-y: hidden; width: 400px;" v-model="context" :defaultConfig="editorConfig"
:mode="mode" @onChange="handleChange" @onCreated="handleCreated" />
</div>
</template>
<script setup>
import '@wangeditor/editor/dist/css/style.css' // css
import { onBeforeUnmount, ref, shallowRef, onMounted, defineEmits, toRefs } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
// shallowRef
const editorRef = shallowRef()
// HTML
const valueHtml = ref('')
const emit = defineEmits(['richTextContent']) //
const props = defineProps({
context: String
})
// ajax
onMounted(() => {
setTimeout(() => {
if(props.context != undefined) {
valueHtml.value = props.context //访
}
}, 1500)
})
const toolbarConfig = {}
const editorConfig = {
placeholder: '请输入内容...',
MENU_CONF: {
uploadImage: {
server: 'http://localhost:9092/api/file/upload/single', //
fieldName: 'file', //
}
}
}
//
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor) => {
editorRef.value = editor // editor
}
const handleChange = (editor) => { //emit
emit('richTextContent', props.context)
// console.log('html',editor.getHtml());
}
</script>
<style scoped>
</style>

View File

@ -1,52 +1,32 @@
export const constantRoute = [
export const constantRoute = [
{
path: '/',
name:'login',
name: 'login',
component: () => import("@/views/Login.vue"),
meta: {
title: '登录界面',
hidden: true
}
},
// 个人中心页面
//首页
{
path: '/User',
redirect: '/PersonalCenter',
name: 'person',
path: '/HomePage',
name: '首页',
redirect: '/DashBoard',
component: () => import("@/layout/Manage.vue"),
meta: {
title: '用户管理',
icon: 'Menu',
title: '首页',
icon: 'House',
hidden: false
},
children :[
children: [
{
path: '/PersonalCenter',
name:'个人中心',
component: ()=> import("@/views/User/PersonalCenter.vue"),
meta: {
title: '个人中心',
icon: 'User',
hidden: false
}
},
{
path: '/Upload',
name:'文件上传',
component: ()=> import("@/views/User/Upload.vue"),
meta: {
title: '文件上传' ,
icon: 'Upload',
hidden: false
}
},
{
path: '/UserManagement',
name:'用户列表',
component: ()=> import("@/views/User/UserManagement.vue"),
meta: {
title: '用户列表',
icon: 'Postcard',
path: '/DashBoard',
name: '仪表盘',
component: () => import("@/views/HomePage/DashBoard.vue"),
meta: {
title: '仪表盘',
icon: 'Odometer',
hidden: false
}
}
@ -58,7 +38,7 @@ export const constantRoute = [
redirect: '/AddProduct',
component: () => import("@/layout/Manage.vue"),
meta: {
title : '实体类商品管理',
title: '实体类商品管理',
icon: 'TakeawayBox',
hidden: false
},
@ -66,8 +46,8 @@ export const constantRoute = [
{
path: '/AddProduct',
name: '添加商品',
component: ()=> import("@/views/Commodity/AddProduct.vue"),
meta: {
component: () => import("@/views/Commodity/AddProduct.vue"),
meta: {
title: '添加商品',
icon: 'Edit',
hidden: false
@ -76,9 +56,9 @@ export const constantRoute = [
{
path: '/MerchandiseCenter',
name: '商品中心',
component: ()=> import("@/views/Commodity/MerchandiseCenter.vue"),
meta: {
title: '商品中心' ,
component: () => import("@/views/Commodity/MerchandiseCenter.vue"),
meta: {
title: '商品中心',
icon: 'DataAnalysis',
hidden: false
}
@ -86,9 +66,9 @@ export const constantRoute = [
{
path: '/TypeManagement',
name: '类别管理',
component: ()=> import("@/views/Commodity/TypeManagement.vue"),
meta: {
title: '类别管理' ,
component: () => import("@/views/Commodity/TypeManagement.vue"),
meta: {
title: '类别管理',
icon: 'Files',
hidden: false
}
@ -102,16 +82,16 @@ export const constantRoute = [
component: () => import("@/layout/Manage.vue"),
meta: {
title: '服务类商品管理',
icon : 'Calendar',
icon: 'Calendar',
hidden: false
},
children: [
{
path: '/AddServiceProduct',
name: '添加服务类商品',
component: ()=> import("@/views/ServiceType/AddServiceProduct.vue"),
meta: {
title: '添加服务类商品' ,
component: () => import("@/views/ServiceType/AddServiceProduct.vue"),
meta: {
title: '添加服务类商品',
icon: 'Edit',
hidden: false
}
@ -119,9 +99,9 @@ export const constantRoute = [
{
path: '/ProductCenter',
name: '服务类商品管理中心',
component: ()=> import("@/views/ServiceType/ProductCenter.vue"),
meta: {
title: '服务类商品管理中心' ,
component: () => import("@/views/ServiceType/ProductCenter.vue"),
meta: {
title: '服务类商品管理中心',
icon: 'DataBoard',
hidden: false
}
@ -142,9 +122,9 @@ export const constantRoute = [
{
path: '/OrderList',
name: '订单列表',
component: ()=> import("@/views/Orders/OrderList.vue"),
meta: {
title: '实体商品订单列表' ,
component: () => import("@/views/Orders/OrderList.vue"),
meta: {
title: '实体商品订单列表',
icon: 'Box',
hidden: false
}
@ -152,9 +132,9 @@ export const constantRoute = [
{
path: '/ServiceOrderList',
name: '服务类订单列表',
component: ()=> import("@/views/Orders/ServiceOrderList.vue"),
meta: {
title: '服务类订单列表' ,
component: () => import("@/views/Orders/ServiceOrderList.vue"),
meta: {
title: '服务类订单列表',
icon: 'MessageBox',
hidden: false
}
@ -162,9 +142,9 @@ export const constantRoute = [
{
path: '/PendingServiceOrderList',
name: '服务类商品待处理订单',
component: ()=> import("@/views/Orders/PendingServiceOrderList.vue"),
meta: {
title: '服务类商品待处理订单' ,
component: () => import("@/views/Orders/PendingServiceOrderList.vue"),
meta: {
title: '服务类商品待处理订单',
icon: 'Notification',
hidden: false
}
@ -184,20 +164,20 @@ export const constantRoute = [
children: [
{
path: '/AddCoupons',
name:'添加优惠券',
component: ()=> import("@/views/Coupons/AddCoupons.vue"),
meta: {
title: '添加优惠券' ,
name: '添加优惠券',
component: () => import("@/views/Coupons/AddCoupons.vue"),
meta: {
title: '添加优惠券',
icon: 'Edit',
hidden: false
}
},
{
path: '/CouponCenter',
name:'优惠券中心',
component: ()=> import("@/views/Coupons/CouponCenter.vue"),
meta: {
title: '优惠券中心' ,
name: '优惠券中心',
component: () => import("@/views/Coupons/CouponCenter.vue"),
meta: {
title: '优惠券中心',
icon: 'DataAnalysis',
hidden: false
}
@ -218,9 +198,9 @@ export const constantRoute = [
{
path: '/AddCostumes',
name: '添加写真产品',
component: ()=> import("@/views/CostumeAppointments/AddCostumes.vue"),
meta: {
title: '添加写真产品' ,
component: () => import("@/views/CostumeAppointments/AddCostumes.vue"),
meta: {
title: '添加写真产品',
icon: 'Edit',
hidden: false
}
@ -228,9 +208,9 @@ export const constantRoute = [
{
path: '/ClothingGrade',
name: '写真产品类别',
component: ()=> import("@/views/CostumeAppointments/ClothingGrade.vue"),
meta: {
title: '写真产品类别' ,
component: () => import("@/views/CostumeAppointments/ClothingGrade.vue"),
meta: {
title: '写真产品类别',
icon: 'Files',
hidden: false
}
@ -238,9 +218,9 @@ export const constantRoute = [
{
path: '/ManagementCenter',
name: '写真产品中心',
component: ()=> import("@/views/CostumeAppointments/ManagementCenter.vue"),
meta: {
title: '写真产品中心' ,
component: () => import("@/views/CostumeAppointments/ManagementCenter.vue"),
meta: {
title: '写真产品中心',
icon: 'Tickets',
hidden: false
}
@ -248,9 +228,9 @@ export const constantRoute = [
{
path: '/AppointmentOrder',
name: '写真预约订单',
component: ()=> import("@/views/CostumeAppointments/AppointmentOrder.vue"),
meta: {
title: '写真预约订单' ,
component: () => import("@/views/CostumeAppointments/AppointmentOrder.vue"),
meta: {
title: '写真预约订单',
icon: 'MessageBox',
hidden: false
}
@ -258,9 +238,9 @@ export const constantRoute = [
{
path: '/OutfitOrderDetail/:id',
name: '写真预约订单详情',
component: ()=> import("@/views/CostumeAppointments/OutfitOrderDetail.vue"),
meta: {
title: '写真订单详情' ,
component: () => import("@/views/CostumeAppointments/OutfitOrderDetail.vue"),
meta: {
title: '写真订单详情',
hidden: true
}
}
@ -276,22 +256,66 @@ export const constantRoute = [
icon: 'Switch',
hidden: false
},
children:[
children: [
{
path: '/refundManage',
name:'退款管理',
component: ()=> import("@/views/Refund/Refund.vue"),
meta: {
title: '退款管理' ,
name: '退款管理',
component: () => import("@/views/Refund/Refund.vue"),
meta: {
title: '退款管理',
icon: 'Money',
hidden: false
}
},
]
},
// 个人中心页面
{
path: '/User',
redirect: '/PersonalCenter',
name: 'person',
component: () => import("@/layout/Manage.vue"),
meta: {
title: '用户管理',
icon: 'Menu',
hidden: false
},
children: [
{
path: '/UserManagement',
name: '用户列表',
component: () => import("@/views/User/UserManagement.vue"),
meta: {
title: '用户列表',
icon: 'Postcard',
hidden: false
}
},
{
path: '/PersonalCenter',
name: '个人中心',
component: () => import("@/views/User/PersonalCenter.vue"),
meta: {
title: '个人中心',
icon: 'User',
hidden: false
}
},
// {
// path: '/Upload',
// name: '文件上传',
// component: () => import("@/views/User/Upload.vue"),
// meta: {
// title: '文件上传',
// icon: 'Upload',
// hidden: false
// }
// },
]
},
{
path: '/Test',
name:'测试页面',
name: '测试页面',
component: () => import("../views/test.vue")
}
]

View File

@ -1,110 +1,118 @@
<template>
<!-- 修改前请注释以前的 -->
<!-- 搜索 -->
<div>
<el-input style="width: 240px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入商品名称"
v-model="productName"></el-input>
<el-button class="ml-5" type="primary" @click="onSearch(productName)" style="height: 25px; margin-right: 10px;">搜索</el-button>
<el-select v-model="editForm.type" @change="(event: any) => searchByType(event)" placeholder="商品类别" style="width: 240px; margin-right: 10px;">
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value1"/>
</el-select>
<el-select v-model="state" placeholder="商品状态" @change="(event: any) => searchByState(event)" style="width: 240px; margin-right: 10px;">
<el-option label="已上架" value="1" />
<el-option label="已下架" value="0" />
</el-select>
<el-button type="warning" @click="reset" style="height:25px">重置</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="goodImg" label="商品图片">
<template #default="scope">
<div>
<img :src="scope.row.goodImg.split(';')[0]" alt="" style="height: 50px;">
</div>
</template>
</el-table-column>
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="商品价格" width="180">
<template #default="scope">
<div>
{{ scope.row.price }}
</div>
</template>
</el-table-column>
<el-table-column prop="type" label="商品类型"></el-table-column>
<el-table-column prop="inventory" label="商品数量"></el-table-column>
<el-table-column label="商品状态">
<template #default="scope">
<div>
<span style="margin-left: 10px" v-if="scope.row.isShelves == 1">上架</span>
<span style="margin-left: 10px" v-if="scope.row.isShelves == 0">下架</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="250px">
<template #default="scope">
<el-button size="small" @click="ReviseOrView(scope.$index, scope.row , 0)">
详情
</el-button>
<el-button size="small" @click="ReviseOrView(scope.$index, scope.row, 1)">
编辑
</el-button>
<el-button size="small" @click="handleOff(scope.$index, scope.row)">
<div v-if="scope.row.isShelves == 1">下架 </div>
<div v-if="scope.row.isShelves == 0">上架 </div>
</el-button>
<el-popconfirm class="ml-5" confirm-button-text='确定' cancel-button-text='取消' icon="InfoFilled" icon-color="red"
title="是否确认删除" @confirm="deleteProduct(scope.row.id)" width=180>
<!-- 搜索 -->
<div>
<el-input style="width: 240px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入商品名称"
v-model="productName"></el-input>
<el-button class="ml-5" type="primary" @click="onSearch(productName)" style="height: 25px; margin-right: 10px;">
搜索
</el-button>
<el-select v-model="editForm.type" @change="(event: any) => searchByType(event)" placeholder="商品类别"
style="width: 240px; margin-right: 10px;">
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value1"/>
</el-select>
<el-select v-model="state" placeholder="商品状态" @change="(event: any) => searchByState(event)"
style="width: 240px; margin-right: 10px;">
<el-option label="已上架" value="1"/>
<el-option label="已下架" value="0"/>
</el-select>
<el-button type="warning" @click="reset" style="height:25px">重置</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="goodImg" label="商品图片">
<template #default="scope">
<div>
<img :src="scope.row.goodImg.split(';')[0]" alt="" style="height: 50px;">
</div>
</template>
</el-table-column>
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="商品价格" width="180">
<template #default="scope">
<div>
{{ scope.row.price }}
</div>
</template>
</el-table-column>
<el-table-column prop="type" label="商品类型"></el-table-column>
<el-table-column prop="inventory" label="商品数量"></el-table-column>
<el-table-column label="商品状态">
<template #default="scope">
<div>
<span style="margin-left: 10px" v-if="scope.row.isShelves == 1">上架</span>
<span style="margin-left: 10px" v-if="scope.row.isShelves == 0">下架</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="250px">
<template #default="scope">
<el-button size="small" @click="ReviseOrView(scope.$index, scope.row , 0)">
详情
</el-button>
<el-button size="small" @click="ReviseOrView(scope.$index, scope.row, 1)">
编辑
</el-button>
<el-button size="small" @click="handleOff(scope.$index, scope.row)">
<div v-if="scope.row.isShelves == 1">下架</div>
<div v-if="scope.row.isShelves == 0">上架</div>
</el-button>
<el-popconfirm class="ml-5" confirm-button-text='确定' cancel-button-text='取消' icon="InfoFilled"
icon-color="red"
title="是否确认删除" @confirm="deleteProduct(scope.row.id)" width=180>
<template #reference>
<el-button class="ml-5" type="danger">删除</el-button>
<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>
</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>
<!-- 编辑/详情表单 -->
<el-dialog v-model="DialogVisible" :title="title">
<el-form label-width="100px" :disabled="disabled">
<el-form label-width="100px" :disabled="disabled" v-model="editForm">
<el-form-item label="商品编号">
<el-input v-model="editForm.id" disabled style="width: 60px;"></el-input>
</el-form-item>
<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, 0)"
:on-exceed="Exceed_ProductImg"
limit="7" >
<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, 0)"
:on-exceed="Exceed_ProductImg"
limit="7">
<el-icon>
<Plus/>
</el-icon>
@ -114,13 +122,13 @@
<el-input v-model="editForm.name" style="width: 200px;"></el-input>
</el-form-item>
<el-form-item label="产品价格" prop="price">
<el-input-number v-model="editForm.price" min="0.01" :precision="2" :step="0.5" />
<el-input-number v-model="editForm.price" min="0.01" :precision="2" :step="0.5"/>
<p style="margin-left: 5px"></p>
</el-form-item>
<div style="display: flex;">
<el-form-item label="产品类别" prop="type">
<el-select v-model="editForm.type" @change="(event: any) => loadForm(event, 1)" style="width: 120px;">
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value1" />
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value1"/>
</el-select>
</el-form-item>
<!-- <el-form-item label="商品数量">
@ -133,8 +141,8 @@
<div style="display: flex;">
<el-form-item label="是否为限定类产品" prop="festivalOrder">
<el-select v-model="editForm.festivalOrder" @change="(event: any) => loadForm(event, 0)" style="width: 70px;">
<el-option label="是" value="1" />
<el-option label="否" value="0" />
<el-option label="是" value="1"/>
<el-option label="否" value="0"/>
</el-select>
</el-form-item>
<el-form-item label="商品标签">
@ -143,18 +151,18 @@
</div>
<el-form-item label="商品图文">
<div v-if="editForm.detailImg">
<img :src="editForm.detailImg" alt="商品图标" class="thumbnail" style="width: 100px; height: 100px;" />
<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-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>
@ -164,7 +172,7 @@
<el-input type="textarea" v-model="editForm.introDetail"></el-input>
</el-form-item>
</el-form>
<template #footer >
<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>
@ -174,10 +182,17 @@
</template>
<script setup lang="ts">
import { ElMessage , type UploadProps , genFileId ,type UploadRawFile } from 'element-plus';
import { ref, onMounted, inject } from 'vue';
import {ElMessage, type UploadProps, genFileId, type UploadRawFile} from 'element-plus';
import {ref, onMounted, inject} from 'vue';
import myAxios from "@/api/myAxios";
import { handleChange, removePic, handleRemove,Exceed_ProductImg, ImgArr ,editForm} from '@/utils/entityProduct/picUpload';
import {
handleChange,
removePic,
handleRemove,
Exceed_ProductImg,
ImgArr,
editForm
} from '@/utils/entityProduct/picUpload';
// import { handleChange, handleRemove, form, Exceed_ProductImg } from '@/utils/entityProduct/picUpload';
const total = ref(0); //
const idList = ref<Number[]>([]);
@ -193,11 +208,10 @@ const title = ref('') //表单名字
const productName = ref('');
const DialogVisible = ref(false);
const state = ref(''); //select
const tableData : any= ref([]); //
// const editForm : any = ref({}); //
const reload : any = inject("reload") //
const uploadProductImg : any = ref() //ref
const uploadProductDetail : any = ref() //ref
const tableData: any = ref([]); //
const reload: any = inject("reload") //
const uploadProductImg: any = ref() //ref
const uploadProductDetail: any = ref() //ref
const typeList: any = ref([
{
value1: '',
@ -211,8 +225,8 @@ onMounted(() => { //页面加载时获取商品列表和分类页表
})
const getProductList = async () => {
try {
const res = await myAxios.post('/goods/list/page', { ...searchParams.value });
console.log('res--->',res.data)
const res = await myAxios.post('/goods/list/page', {...searchParams.value});
console.log('res--->', res.data)
if (res.data.code === 1) {
tableData.value = res.data.data.records;
total.value = parseInt(res.data.data.total) //
@ -238,8 +252,8 @@ const getTypeList = async () => {
}
}
const saveEdit = async () => { //
const res = await myAxios.post('/goods/update',{...editForm.value})
if( res.data.code === 1 ) {
const res = await myAxios.post('/goods/update', {...editForm.value})
if (res.data.code === 1) {
ElMessage({
type: 'success',
message: '更新成功'
@ -249,12 +263,12 @@ const saveEdit = async () => { //编辑商品
ElMessage.error('更新失败,请检查字段')
}
}
const searchByType =(event : any)=>{ //
const searchByType = (event: any) => { //
searchParams.value.type = event
searchParams.value.current = 1
getProductList()
}
const searchByState = (event : any) => { ///
const searchByState = (event: any) => { ///
searchParams.value.isShelves = event
searchParams.value.current = 1
getProductList()
@ -262,7 +276,7 @@ const searchByState = (event : any) => { //通过商品是否上架/下架搜
//
const deleteProduct = async (index: number) => {
console.log(typeof index)
const res = await myAxios.post('/goods/delete', { id: index })
const res = await myAxios.post('/goods/delete', {id: index})
console.log(res)
if (res.data.code === 1) {
ElMessage({
@ -274,29 +288,29 @@ const deleteProduct = async (index: number) => {
getTypeList()
}
//
const ReviseOrView = (index: number, row: any , flag : number) => {
ImgArr.value.splice(0,ImgArr.value.length)
const ReviseOrView = (index: number, row: any, flag: number) => {
ImgArr.value.splice(0, ImgArr.value.length)
var tempArr = row.goodImg.split(';')
tempArr.forEach((item: any)=>{
tempArr.forEach((item: any) => {
ImgArr.value.push({
url: item
})
})
flag ? (title.value = "编辑商品" , disabled.value = false) : (title.value = "商品详情" , disabled.value = true)
flag ? (title.value = "编辑商品" , disabled.value = false) : (title.value = "商品详情" , disabled.value = true)
DialogVisible.value = true;
editForm.value = row;
};
editForm.value = JSON.parse(JSON.stringify(row))
}
//
const handleOff = async (index: number, row: any) => {
const handleOff = async (index: number, row: any) => {
row.isShelves ? row.isShelves = 0 : row.isShelves = 1 //
editForm.value = row;
const res = await myAxios.post('/goods/update',{...editForm.value})
if(res.data.code === 1) {
const res = await myAxios.post('/goods/update', {...editForm.value})
if (res.data.code === 1) {
ElMessage({
type:'success',
message:'更新成功'
type: 'success',
message: '更新成功'
})
}
}
}
//
const handleSizeChange = (newSize: any) => {
@ -322,19 +336,19 @@ const Exceed_ProductDetail: UploadProps['onExceed'] = (files) => { //覆盖商
const loadForm = (value: any, flag: number) => {
flag ? editForm.value.type = value : editForm.value.festivalOrder = value // flag=1 "" flag=0
}
const onSearch = (data : String)=>{ //
const onSearch = (data: String) => { //
searchParams.value.name = data
searchParams.value.current = 1
getProductList()
}
//
const delBatch = async ()=>{
//
const delBatch = async () => {
console.log(idList.value);
const res = await myAxios.post('/goods/delBatch',{
const res = await myAxios.post('/goods/delBatch', {
idList: idList.value
})
console.log(res.data);
if(res.data.code === 1) {
if (res.data.code === 1) {
ElMessage({
type: 'success',
message: '批量删除成功'
@ -344,10 +358,11 @@ const delBatch = async ()=>{
ElMessage.error('删除失败')
}
}
const handleSelectionChange =()=>{}
const selectChange =(selection: any, row : any)=> { //selctionrow
idList.value.splice(0,idList.value.length) //
selection.forEach((item: any)=> {
const handleSelectionChange = () => {
}
const selectChange = (selection: any, row: any) => { //selctionrow
idList.value.splice(0, idList.value.length) //
selection.forEach((item: any) => {
idList.value.push(item.id)
})
// console.log('idList--->',idList.value);

View File

@ -1,32 +1,32 @@
<template>
<div style="margin-bottom: 10px;">
<el-button type="success" @click="showForm">添加类别</el-button>
<el-button type="danger" @click="">删除类别</el-button>
</div>
<el-dialog v-model="dialogVisible" title="商品类别" width="500">
<el-form :model="typeForm" label-width="auto" style="max-width: 600px" v-loading="loading">
<el-form-item label="添加类别图片">
<!-- 下面的event的作用,传入当前事件对象 -->
<el-upload
v-model:file-list="typeImg"
action="#"
list-type="picture-card"
:auto-upload="false"
multiple="true"
:on-remove="handleRemove"
@change="(event: any) => handleChange(event)"
:on-exceed="ExceedTypeImg"
limit="1" >
<el-upload
v-model:file-list="typeImg"
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 />
<Plus/>
</el-icon>
</el-upload>
</el-form-item>
<el-form-item label="类别名">
<el-input v-model="typeForm.typeName" />
<el-input v-model="typeForm.typeName" @input="changeInput"/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="typeForm.typeIntro" />
<el-input v-model="typeForm.typeIntro" @input="changeInput"/>
</el-form-item>
</el-form>
<template #footer #default="{ row, $index }">
@ -40,7 +40,7 @@
</el-dialog>
<!-- 数据展示层 -->
<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 prop="id" label="类别编号" width="150"></el-table-column>
<el-table-column prop="typeUrl" label="类别图片" width="300">
@ -54,8 +54,9 @@
<template #default="scope">
<el-button type="success" @click="editShowForm(scope.$index, scope.row)">修改类别</el-button>
<!-- scope.$index是当前行 第一行为0 -->
<el-popconfirm class="ml-5" confirm-button-text='确定' cancel-button-text='取消' icon="InfoFilled" icon-color="red"
title="是否确认删除" @confirm="Delete_type(scope.row.id)" width=180>
<el-popconfirm class="ml-5" confirm-button-text='确定' cancel-button-text='取消' icon="InfoFilled"
icon-color="red"
title="是否确认删除" @confirm="Delete_type(scope.row.id)" width=180>
<template #reference>
<el-button style="height: 25px" class="ml-5" type="danger">删除类别</el-button>
</template>
@ -66,17 +67,18 @@
</template>
<script setup lang="ts">
import { ElMessage, type UploadProps, type UploadUserFile} from 'element-plus';
import { ErrorInfo, SuccessInfo } from '@/utils/messageInfo';
import { onMounted, ref } from 'vue'
import {ElMessage, type UploadProps, type UploadUserFile,type UploadFile, genFileId, type UploadRawFile} from 'element-plus';
import {ErrorInfo, SuccessInfo} from '@/utils/messageInfo';
import {onMounted, ref} from 'vue'
import myAxios from '@/api/myAxios';
const fileSimple = ref() //
const selectedItems = ref([])
const selectedItems = ref([])
const dialogVisible = ref(false)
const submitable = ref(true) //
const loading = ref(false) //
const typeImg: any = ref<UploadUserFile[]>([]) //
// const imgMap = new Map() //map
const uploadProductImg: any = ref() //ref
//
const typeForm = ref({
id: 0,
@ -88,7 +90,7 @@ const typeForm = ref({
const tableData = ref([])
// (0) (1)
const flag = ref(0)
const typeList = ref([])
const tempImgUrl = ref('') //URL
//
onMounted(() => {
getTypeList()
@ -120,11 +122,11 @@ const handleChange = async (file: any) => {
file: formData.get("file") // formDatafile
}
})
if ( res.data.code === 1) {
if (res.data.code === 1) {
loading.value = false
SuccessInfo('上传成功')
submitable.value = false
typeForm.value.typeUrl = res.data.data
tempImgUrl.value = res.data.data
} else {
ErrorInfo(res.data.message)
}
@ -133,16 +135,21 @@ const handleChange = async (file: any) => {
const handleRemove: UploadProps['onRemove'] = (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 //
}
const ExceedTypeImg: UploadProps['onExceed'] = (files) => {
//
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { // 'onExceed'
uploadProductImg.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
uploadProductImg.value!.handleStart(file)
}
//
const showForm = async () => {
resetForm()
typeImg.value.splice(0,typeImg.value.length)
tempImgUrl.value = ''
typeImg.value.splice(0, typeImg.value.length)
dialogVisible.value = true;
flag.value = 0
}
@ -151,11 +158,11 @@ const cancel = () => {
dialogVisible.value = false
resetForm()
}
//
//
const addOrUpdateType = async () => {
//(*)
//
if (typeForm.value.typeName?.indexOf(' ') !== -1 ||
typeForm.value.typeName == '' || typeForm.value.typeUrl == '') {
typeForm.value.typeName == '' || tempImgUrl.value == '') {
ElMessage({
type: 'warning',
message: '不能为空格/空字符串'
@ -165,24 +172,26 @@ const addOrUpdateType = async () => {
//
dialogVisible.value = false;
if (flag.value === 0) {
console.log('添加的类别--->',typeForm.value)
const res = await myAxios.post('/category/add', {
//
typeName: typeForm.value.typeName,
typeUrl: typeForm.value.typeUrl,
typeUrl: tempImgUrl.value,
typeIntro: typeForm.value.typeIntro
})
if (res.data.code === 1) {
//
SuccessInfo('添加类别成功')
resetForm()
} else {
ElMessage.error('提交失败')
}
}
if( flag.value === 1 ) {
const res = await myAxios.post('/category/update',{
id : typeForm.value.id,
if (flag.value === 1) {
const res = await myAxios.post('/category/update', {
id: typeForm.value.id,
typeName: typeForm.value.typeName,
typeUrl: typeForm.value.typeUrl,
typeUrl: tempImgUrl.value,
typeIntro: typeForm.value.typeIntro
})
if (res.data.code === 1) {
@ -211,19 +220,19 @@ const handleSelectionChange = (row: any) => {
}
//
const editShowForm = (index: number, row: any) => {
typeImg.value.splice(0,typeImg.value.length) //
tempImgUrl.value = row.typeUrl //
typeImg.value.splice(0, typeImg.value.length) //
typeImg.value.push({
url: row.typeUrl
})
dialogVisible.value = true
typeForm.value = row
typeForm.value = JSON.parse(JSON.stringify(row))
flag.value = 1
console.log('本行--->',row)
}
// id
const Delete_type = async (index: number) => {
console.log(typeof index)
const res = await myAxios.post('/category/delete', { id: index })
const res = await myAxios.post('/category/delete', {id: index})
console.log(res)
if (res.data.code === 1) {
ElMessage({
@ -233,12 +242,8 @@ const Delete_type = async (index: number) => {
}
getTypeList()
}
//
const delBatch = async ()=>{
console.log(typeList.value);
const res = await myAxios.post('/goods/delBatch',{
idList: typeList.value
})
const changeInput = () => { //
submitable.value = false
}
</script>

View File

@ -31,7 +31,7 @@
</div>
<div class="NamePrice">
<div class="name">
<el-form-item label="体验课名称" prop="name">
<el-form-item label="服装名称" prop="name">
<el-input v-model="form.name" />
</el-form-item>
</div>
@ -118,8 +118,8 @@ const maxArr= ref<Number[]>([]) //最大人数数组
onMounted(() => {
getOutfitKind() //
for(let i = 0;i <=50 ; i++) { //
minArr.value[i] = 5+i
maxArr.value[i] = 6+i
minArr.value[i] = 1+i
maxArr.value[i] = 2+i
}
})
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {

View File

@ -18,12 +18,22 @@
<el-table-column prop="orderNumber" label="订单编号" width="300"></el-table-column>
<el-table-column prop="createTime" label="下单时间" width="180"></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="订单状态">
<template #default="scope">
{{ scope.row.orderStatus === '待发货' ? '待消费' : scope.row.orderStatus }}
</template>
</el-table-column>
<el-table-column label="操作" width="220px" fixed="right">
<template #default="scope">
<el-button size="small" @click="showDetail(scope.row)">
详情
</el-button>
<el-popconfirm confirm-button-text='' cancel-button-text='' icon="InfoFilled" icon-color="red"
title="拍摄是否完成?" @confirm="changeOrderStatus(scope.row)" width=180 v-if="['待发货'].includes(scope.row.orderStatus)">
<template #reference>
<el-button size="small" type="primary" plain>拍摄完成</el-button>
</template>
</el-popconfirm>
<el-popconfirm confirm-button-text='确定' cancel-button-text='取消' icon="InfoFilled" icon-color="red"
title="确定要退款吗?" @confirm="deleteOrder(scope.row)" width=180>
<template #reference>
@ -60,7 +70,6 @@ const searchParams: any = ref({ //封装分页
orderType: 'service'
})
const router = useRouter()
const route = useRoute()
const loading = ref(false)
onMounted(() => {
getOrderList() //
@ -106,6 +115,9 @@ const showDetail = (row: any) => {
}
})
};
const changeOrderStatus = async (row: any) => { //
const res = await myAxios.post('',{})
}
const deleteOrder = async (row: any) => { //退
loading.value = true
console.log('row-->', row)

View File

@ -0,0 +1,220 @@
<template>
<div class="app-container">
<span style="font-size: 18px">{{ userName }}欢迎</span>
<div class="total-layout">
<el-row :gutter="20">
<el-col :span="8">
<div class="total-frame">
<img src="../../img/dashBoard/product.png" class="total-icon">
<div class="total-title">今日商品订单</div>
<div class="total-value">数量:{{ entityOrder }}</div>
<div class="total-value">营业额:{{ entityTurnover }}</div>
</div>
</el-col>
<el-col :span="8">
<div class="total-frame">
<img src="../../img/dashBoard/课程表.png" class="total-icon">
<div class="total-title">今日课程订单</div>
<div class="total-value">数量:{{ serviceOrder }}</div>
<div class="total-value">营业额:{{ serviceTurnover }}</div>
</div>
</el-col>
<el-col :span="8">
<div class="total-frame">
<img src="../../img/dashBoard/3.1拍摄.png" class="total-icon">
<div class="total-title">今日拍摄订单</div>
<div class="total-value">数量:{{ photoOrder }}</div>
<div class="total-value">营业额:{{ photoTurnover }}</div>
</div>
</el-col>
</el-row>
</div>
<div class="un-handle-layout">
<div class="layout-title">待处理事务</div>
<div class="un-handle-content">
<el-row :gutter="20">
<el-col :span="6">
<div class="un-handle-item">
<span class="font-medium">待发货订单</span>
<span style="float: right" class="color-danger">{{ waitDeliverOrder }}</span>
</div>
</el-col>
<el-col :span="6">
<div class="un-handle-item">
<span class="font-medium">待付款订单</span>
<span style="float: right" class="color-danger">{{ waitPayOrder }}</span>
</div>
</el-col>
<el-col :span="6">
<div class="un-handle-item">
<span class="font-medium">待拍摄订单</span>
<span style="float: right" class="color-danger">{{ waitPhotoOrder }}</span>
</div>
</el-col>
<el-col :span="6">
<div class="un-handle-item">
<span class="font-medium">待上课订单</span>
<span style="float: right" class="color-danger">{{ waitConsumption }}</span>
</div>
</el-col>
</el-row>
</div>
</div>
<div class="overview-layout">
<el-row :gutter="20">
<el-col :span="12">
<div class="out-border">
<div class="layout-title">商品总览</div>
<div style="padding: 40px">
<el-row class="font-medium">
<el-col :span="8" class="overview-item-title">全部商品</el-col>
<el-col :span="8" class="overview-item-title">已下架</el-col>
<el-col :span="8" class="overview-item-title">已上架</el-col>
</el-row>
<el-row>
<el-col :span="8" class="color-danger overview-item-value">{{ totalProductNum }}</el-col>
<el-col :span="8" class="color-danger overview-item-value">{{ offshelvesNum }}</el-col>
<el-col :span="8" class="color-danger overview-item-value">{{ shelvesNum }}</el-col>
</el-row>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup lang="ts">
import myAxios from '@/api/myAxios'
import {ref, onMounted} from 'vue'
import {userStore} from "@/store/userStore";
let dashBord = new Map() //map
const store = userStore() //
const userName = store.loginUser.userName
const photoTurnover = ref(0) //
const photoOrder = ref(0) //
const entityTurnover = ref(0) //
const entityOrder = ref(0) //
const serviceTurnover = ref(0) //
const serviceOrder = ref(0) //
const totalProductNum = ref(0) //
const shelvesNum = ref(0) //
const offshelvesNum = ref(0) //
const waitPhotoOrder = ref(0) //
const waitDeliverOrder = ref(0) //
const waitPayOrder = ref(0) //
const waitConsumption = ref(0) //
onMounted(() => {
getDashBoard()
})
const getDashBoard = async () => {
const res = await myAxios.post('/global/queryAll', {})
// console.log('',res.data.data);
if (res.data.code === 1) {
dashBord = new Map(Object.entries(res.data.data))
photoTurnover.value = dashBord.get('今日写真预约类订单营业额')
photoOrder.value = dashBord.get('今日写真预约订单数')
entityTurnover.value = dashBord.get('今日实体类商品订单营业额')
entityOrder.value = dashBord.get('今日实体类商品订单数')
serviceTurnover.value = dashBord.get('今日服务类商品订单营业额')
serviceOrder.value = dashBord.get('今日服务类商品订单数')
totalProductNum.value = dashBord.get('全部商品数量')
shelvesNum.value = dashBord.get('全部已上架商品数量')
offshelvesNum.value = dashBord.get('全部已下架商品数量')
waitPhotoOrder.value = dashBord.get('写真预约类待拍摄订单')
waitDeliverOrder.value = dashBord.get('实体类待发货订单')
waitPayOrder.value = dashBord.get('所有待支付订单数量')
waitConsumption.value = dashBord.get('服务类待消费订单')
}
}
</script>
<style scoped>
.app-container {
margin-top: 40px;
margin-left: 120px;
margin-right: 120px;
}
.total-layout {
margin-top: 20px;
}
.total-frame {
border: 1px solid #DCDFE6;
border-radius: 10px;
padding: 20px;
height: 100px;
}
.total-icon {
color: #409EFF;
width: 60px;
height: 60px;
}
.total-title {
position: relative;
font-size: 20px;
color: #909399;
left: 70px;
top: -60px;
}
.total-value {
position: relative;
font-size: 18px;
color: #606266;
left: 70px;
top: -45px;
}
.un-handle-layout {
margin-top: 20px;
border: 1px solid #DCDFE6;
border-radius: 15px;
}
.layout-title {
color: #606266;
padding: 15px 20px;
background: #F2F6FC;
font-weight: bold;
}
.un-handle-content {
padding: 20px 40px;
}
.un-handle-item {
border-bottom: 1px solid #EBEEF5;
padding: 10px;
}
.un-handle-item {
border-bottom: 1px solid #EBEEF5;
padding: 10px;
}
.overview-layout {
margin-top: 20px;
}
.out-border {
border: 1px solid #DCDFE6;
border-radius: 15px;
}
.overview-item-value {
font-size: 24px;
text-align: center;
}
.overview-item-title {
margin-top: 10px;
text-align: center;
}
</style>

View File

@ -66,8 +66,8 @@
SuccessInfo('登陆成功')
//pinia
await store.getLoginUser(res.data.data)
//
await router.replace('/PersonalCenter')
//
await router.replace('/DashBoard')
} else {
WarnInfo(res.data.message)
return; //

View File

@ -2,7 +2,7 @@
<div style="margin-bottom: 20px">
<el-input style="width: 250px; height: 30px; margin-right: 10px; font-size: 14px" suffix-icon="Search"
placeholder="请输入订单编号" v-model="orderNumber"></el-input>
<el-button class="ml-5" type="primary" @click="load" style="height: 30px;">搜索</el-button>
<el-button class="ml-5" type="primary" @click="load(orderNumber)" style="height: 30px;">搜索</el-button>
<el-button type="warning" @click="reset" style="height:30px">重置</el-button>
</div>
<!-- 数据展示层 -->
@ -278,7 +278,11 @@ const deleteOrder = async (row: any) => { //微信退款
const reset = () => { //
orderNumber.value = '';
};
const load = () => { } //
const load = (onum : any) => { //
searchParams.value.orderNumber = onum
searchParams.value.current = 1
getOrderList()
}
const cancelOrder = async (row: any) => { //()
console.log('点击的这一行--->', row);
const res = await myAxios.post('/order/cancel/id', { id: row.id })

View File

@ -1,32 +0,0 @@
<template>
<el-card style="width: 500px">
<el-form label-width="80px" size="small">
<el-form-item label="用户名">
<el-input v-model="form.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="学号">
<el-input v-model="form.nickname" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="form.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="电话">
<el-input v-model="form.phone" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="地址">
<el-input v-model="form.address" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save"> </el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<script>
</script>
<style scoped>
</style>

View File

@ -36,8 +36,9 @@
</el-form-item>
</div>
<div class="price">
<el-form-item label="体验课价格" prop="price">
<el-input v-model="form.price" style="width: 90px;" />
<el-form-item label="产品价格" prop="price">
<el-input-number v-model="form.price" min="0" :precision="2" :step="0.5" />
<p></p>
</el-form-item>
</div>
</div>
@ -103,7 +104,7 @@ const onSubmit = async () => {
const values = Object.values(form.value);
// 使some()
console.log(form.value.appointmentDateAddRequestList)
if (values.some(value => value === null || value === undefined || value === '') || form.value.appointmentDateAddRequestList.length == 0) {
if (values.some(value => value === null || value === undefined || value === ''|| value === 0) || form.value.appointmentDateAddRequestList.length == 0 ) {
ElMessage({
type: 'warning',
message: '请检查表单数据是否完整填写'

View File

@ -348,7 +348,7 @@ const ReviseOrView = (index: number, row: any , flag : number) => {
//flag disabled
flag ? (title.value = "编辑商品" , disabled.value = false) : (title.value = "商品详情" , disabled.value = true)
DialogVisible.value = true;
editForm.value = row;
editForm.value = JSON.parse(JSON.stringify(row));
};
//()
const handleOff = async (row: any) => {

View File

@ -1,11 +1,115 @@
<script setup lang="ts">
</script>
<template>
个人中心
<div class="detail-container">
<el-card shadow="hover">
<el-form label-width="100px" :disabled="disabled">
<el-form-item label="头像">
<el-upload v-model:file-list="ImgArr" ref="uploadProductImg" action="#" list-type="picture-card"
:auto-upload="false" multiple="true" :on-remove="removePic" @change="(event: any) => handleChange(event)"
:on-exceed="Exceed_ProductImg" limit="1">
<el-icon>
<Plus />
</el-icon>
</el-upload>
</el-form-item>
<div style="display: flex;">
<el-form-item label="账号">
<el-input v-model="userForm.userAccount"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="userForm.userPassword" />
</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>
<div style="display: flex;">
<el-button @click="changeStatus">{{ btnText }}</el-button>
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ElMessage, type UploadProps, type UploadUserFile,type UploadFile, genFileId, type UploadRawFile } from 'element-plus';
import myAxios from '@/api/myAxios';
import { ref, onMounted } from 'vue'
import { ErrorInfo, SuccessInfo, WarnInfo } from '@/utils/messageInfo';
const ImgArr: any = ref<UploadUserFile[]>([]) //使
const disabled = ref(true) //
const userForm: any = ref({}) //
const fileSimple = ref() //
const uploadProductImg: any = ref() //ref
const tempAvatar = ref('') //
const btnText = ref('编辑') //
const tempUserObj = ref({}) //
//
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/upload/server/not_login',
method: 'post',
headers: {
'content-Type': 'multipart/form-data'
},
data: {
biz: "test",
file: formData.get("file") // formDatafile
}
})
if (res.data.code === 1) {
tempAvatar.value = res.data.data
}
}
//
const removePic: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFileuploadFiles
userForm.value.userAvatar = ''
}
const saveEdit = async ()=>{ //
}
const changeStatus = async ()=> {
if(btnText.value === '编辑') {
btnText.value = '取消'
disabled.value = false
} else {
btnText.value = '编辑'
disabled.value = true
//
}
}
</script>
<style scoped>
.detail-container {
width: 80%;
padding: 20px 20px 20px 20px;
margin: 20px auto;
}
</style>

View File

@ -1,80 +1,87 @@
<template>
<div>
<div style="margin: 10px 0">
<el-input style="width: 200px; height: 30px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入用户名" v-model="username"></el-input>
<el-button class="ml-5" type="primary" @click="onSearch(username)" style="height: 25px;">搜索</el-button>
<el-button type="warning" @click="reset" style="height:25px">重置</el-button>
</div>
<!-- <div style="margin: 15px 0">-->
<!-- <el-button class="ml-5" type="primary" @click="handleAdd" style="height: 25px;">新增 <el-icon style="margin-left: 5px"><CirclePlus /></el-icon></el-button>-->
<!-- <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" slot="reference">批量删除 <el-icon style="margin-left: 5px;"><Remove /></el-icon></el-button>-->
<!-- </template>-->
<!-- </el-popconfirm>-->
<!-- </div>-->
<el-table :data="tableData" border stripe header-cell-class-name="headerBg" :cell-style="{textAlign: 'center'}"
@selection-change="handleSelectionChange" :header-cell-style="{'text-align': 'center'}">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="id" label="序号" width="50"></el-table-column>
<el-table-column prop="userName" label="用户昵称" ></el-table-column>
<el-table-column prop="userAvatar" label="头像">
<template #default="scope"><img :src="scope.row.userAvatar" alt="" style="height: 50px;"></template>
</el-table-column>
<el-table-column prop="userRole" label="身份"></el-table-column>
<el-table-column prop="phone" label="手机号"></el-table-column>
<el-table-column label="操作">
<!-- <template slot-scope="scope">
<el-button type="success" @click="detail(scope.row)">详情 <i class="el-icon-edit"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确定'
cancel-button-text='取消'
icon="el-icon-info"
icon-color="red"
title="您确定删除吗?"
@confirm="del(scope.row.id)"
>
<el-button type="danger" slot="reference">封禁 <i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
</template> -->
</el-table-column>
</el-table>
<!-- 分页查询 -->
<div style="padding: 10px 0">
<el-pagination
:current-page="searchParams.current"
:page-size="searchParams.pageSize"
:page-sizes="[2, 5, 10, 20]"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:small="null"
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
/>
</div>
<div style="margin: 10px 0">
<el-input style="width: 200px; height: 30px; margin-right: 10px;" suffix-icon="Search" placeholder="请输入用户名"
v-model="username"></el-input>
<el-button class="ml-5" type="primary" @click="onSearch(username)" style="height: 25px;">搜索</el-button>
<el-button type="warning" @click="reset" style="height:25px">重置</el-button>
</div>
<el-table :data="tableData" border stripe header-cell-class-name="headerBg" :cell-style="{ textAlign: 'center' }"
@selection-change="handleSelectionChange" :header-cell-style="{ 'text-align': 'center' }">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="id" label="序号" width="50">
<template #default="{ $index }">
{{ $index + 1 }}
</template>
</el-table-column>
<el-table-column prop="userName" label="用户昵称"></el-table-column>
<el-table-column prop="userAvatar" label="头像">
<template #default="scope"><img :src="scope.row.userAvatar" alt="" style="height: 50px;"></template>
</el-table-column>
<el-table-column prop="userRole" label="身份">
<template #default="scope">
{{ scope.row.userRole === 'boss' ? '管理员' : '小程序用户' }}
</template>
</el-table-column>
<el-table-column prop="phone" label="手机号"></el-table-column>
<el-table-column prop="isDelete" label="是否删除"></el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="checkDetail(scope.row)">详情</el-button>
<el-button size="small" type="primary" @click="editUser(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页查询 -->
<div style="padding: 10px 0">
<el-pagination :current-page="searchParams.current" :page-size="searchParams.pageSize" :page-sizes="[2, 5, 10, 20]"
@size-change="handleSizeChange" @current-change="handleCurrentChange" :small="null" background
layout="total, sizes, prev, pager, next, jumper" :total="total" />
</div>
<!-- 单个用户表单 -->
<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>
<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" />
</el-form-item>
<div style="display: flex;">
<el-form-item label="用户名">
<el-input v-model="userForm.userName" />
</el-form-item>
<el-form-item label="手机号码">
<el-input v-model="userForm.phone" />
</el-form-item>
</div>
<div style="display: flex;">
<el-form-item label="积分">
<el-input v-model="userForm.points"></el-input>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button @click="DialogVisible = false" :disabled="disabled">取消</el-button>
<el-button type="primary" @click="saveEdit" :disabled="disabled">确认</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ElMessage } from 'element-plus';
import { ElMessage, type UploadProps, type UploadUserFile,type UploadFile, genFileId, type UploadRawFile } from 'element-plus';
import myAxios from '@/api/myAxios';
import {ref, onMounted , inject} from 'vue'
import { ref, onMounted, inject } from 'vue'
import { ErrorInfo, SuccessInfo, WarnInfo } from '@/utils/messageInfo';
const ImgArr: any = ref<UploadUserFile[]>([]) //使
//
const tableData = ref([])
//
@ -86,60 +93,135 @@ const searchParams: any = ref({
//
pageSize: 5
})
//
const reload : any = inject("reload")
const reload: any = inject("reload") //
const DialogVisible = ref(false) //
const title = ref('编辑用户') //
const disabled = ref(false) //
const userForm: any = ref({}) //
const fileSimple = ref() //
const uploadProductImg: any = ref() //ref
const tempAvatar = ref('') //
onMounted(() => {
getUserList()
})
const username = ref('')
//
const reset =()=>{
const reset = () => {
reload()
}
//
const handleChange = async (file: any) => {
fileSimple.value = file
let formData = new FormData() // FormData
formData.append("file", fileSimple.value.raw) //fileSimple.value.raw formData
const res = await myAxios({ //
url: '/file/upload/server/not_login',
method: 'post',
headers: {
'content-Type': 'multipart/form-data'
},
data: {
biz: "test",
file: formData.get("file") // formDatafile
}
})
if (res.data.code === 1) {
tempAvatar.value = res.data.data
}
}
//
const removePic: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { //uploadFileuploadFiles
userForm.value.userAvatar = ''
}
//
const Exceed_ProductImg: UploadProps['onExceed'] = (files) => { // 'onExceed'
uploadProductImg.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
uploadProductImg.value!.handleStart(file)
}
//
const getUserList = async () => {
//({...})POST.value,Object
const res = await myAxios.post('/user/list/page/vo',{...searchParams.value})
if(res.data.code === 1) {
console.log(res.data.data)
//
tableData.value = res.data.data.records
//
total.value = parseInt(res.data.data.total)
}else {
ElMessage({
type: 'info',
message: '查询失败',
})
}
const res = await myAxios.post('/user/list/page', { ...searchParams.value })
if (res.data.code === 1) {
console.log(res.data.data)
//
tableData.value = res.data.data.records
//
total.value = parseInt(res.data.data.total)
} else {
ElMessage({
type: 'info',
message: '查询失败',
})
}
}
const handleSelectionChange = (val:any)=>{
const handleSelectionChange = (val: any) => {
console.log(val)
}
//
const handleSizeChange = (newSize:any) => {
const handleSizeChange = (newSize: any) => {
searchParams.value.pageSize = newSize //
getUserList() //
};
//
const handleCurrentChange = (Current:any) => {
const handleCurrentChange = (Current: any) => {
searchParams.value.current = Current //
getUserList() //
};
//
const onSearch = (data : String)=>{
const onSearch = (data: String) => {
searchParams.value.userName = data
searchParams.value.current = 1
getUserList()
}
const checkDetail = (obj: any) => { //
title.value = '查看用户'
ImgArr.value.splice(0, ImgArr.value.length)
ImgArr.value.push({
url: obj.userAvatar
})
disabled.value = true
DialogVisible.value = true
userForm.value = obj
}
const editUser = (obj: any) => { //
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
userForm.value = obj
}
const saveEdit = async () => { //
console.log('编辑后的信息--->', userForm.value);
const res = await myAxios.post('/user/update', {
id: 2,
userPassword: userForm.value.userPassword,
userName: userForm.value.userName,
userAvatar: tempAvatar.value,
phone: userForm.value.phone,
userRole: userForm.value.userRole
})
if(res.data.code === 1) {
SuccessInfo('更新成功')
DialogVisible.value = false
getUserList()
} else {
ErrorInfo('更新失败')
}
}
</script>
<style scoped>
.headerBg{
.headerBg {
background-color: #eee !important;
}
</style>

View File

@ -1,6 +1,6 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"include": ["env.d.ts", "src/**/*"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
@ -10,5 +10,6 @@
"paths": {
"@/*": ["./src/*"]
}
}
},
"moduleResolution" : "node"
}