Merge remote-tracking branch 'origin/gyj'

# Conflicts:
#	src/api/modules/goods.js
This commit is contained in:
2024-10-15 10:27:53 +08:00
4 changed files with 244 additions and 129 deletions
+10 -3
View File
@@ -1,7 +1,7 @@
import service from "../request.js";
const API_BASE_URL = '/goods';
// 客户列表
// 服务项目列表
export function getGoodsList(query) {
return service({
method: "get",
@@ -9,6 +9,8 @@ export function getGoodsList(query) {
data: query,
});
}
// 添加服务项目
export function addGoods(query) {
return service({
method: "post",
@@ -16,6 +18,8 @@ export function addGoods(query) {
data: query,
});
}
// 更新服务项目
export function updateGoods(query) {
return service({
method: "put",
@@ -23,9 +27,12 @@ export function updateGoods(query) {
data: query,
});
}
export function delGoods(id) {
// 删除服务项目
export function delGoods(query) {
return service({
method: "delete",
url: `${API_BASE_URL}/`+id
url: `${API_BASE_URL}/${query}`,
data: query,
});
}
+120 -65
View File
@@ -7,7 +7,7 @@
</el-button>
</el-col>
<el-drawer v-model="drawer" :direction="direction">
<el-drawer v-model="drawer" :direction="direction" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true" :show-close="false">
<template v-if="!drawerEdit" #header>
<h4>创建服务</h4>
</template>
@@ -31,6 +31,16 @@
<el-input type="number" v-model="formData.price" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="状态" prop="formData.isList">
<el-switch
v-model="formData.isList"
inline-prompt
active-text="上架"
inactive-text="下架"
/>
</el-form-item>
<el-form-item label="轮播图">
<el-upload
v-model:file-list="fileBannerList"
@@ -61,7 +71,7 @@
</el-form-item>
<div style="display: flex; justify-content: flex-end; margin-top: 50px">
<el-button @click="drawer = false;drawerEdit = false;">取消</el-button>
<el-button @click="cancelDrawer">取消</el-button>
<el-button type="primary" @click="onSubmit">确认</el-button>
</div>
</el-form>
@@ -72,10 +82,6 @@
<el-card shadow="never">
<el-table
:data="tableData"
:header-cell-style="{ backgroundColor: '#ecf5ff' }"
border
stripe
style="width: 100%"
>
<el-table-column
v-for="item in options"
@@ -84,47 +90,65 @@
:label="item.label"
:width="item.width"
:align="item.align"
show-overflow-tooltip
:fixed="item.fixed"
>
<template v-slot:default="scope" v-if="item.props === 'price'">
{{ formatPrice(scope.row.price) }}
</template>
<template v-slot:default="scope" v-if="item.props === 'carouselImage'">
<el-image
style="width: 600px; height: 50px"
:src="scope.row.carouselImage"
:preview-src-list="[scope.row.carouselImage]"
<template v-slot:default="scope" v-if="item.props === 'isList'">
<el-switch
v-model="scope.row.isList"
inline-prompt
active-text="上架"
inactive-text="下架"
@change="upStatus(scope.row)"
/>
</template>
<template v-slot:default="scope" v-if="item.props === 'carouselImage'">
<view v-for="itemImg in scope.row.carouselImage">
<el-card shadow="never" class="header-card">
<el-col>
<el-image
:src="itemImg.url"
:preview-src-list="[itemImg.url]"
style="width:100%; height: 60px;"
/>
</el-col>
</el-card>
</view>
</template>
<template v-slot:default="scope" v-if="item.props === 'details'">
<el-image
style="width: 600px; height: 50px"
style="width: 300px; height: 50px"
:src="scope.row.details"
:preview-src-list="[scope.row.details]"
/>
</template>
<template v-slot:default="scope" v-if="item.props === 'actions'">
<el-button
type="info"
size="small"
@click="viewItem(scope.row)"
>查看</el-button>
<el-button
type="info"
size="small"
@click="editItem(scope.row)"
>编辑</el-button>
<!-- <el-button-->
<!-- type="info"-->
<!-- size="small"-->
<!-- @click="viewItem(scope.row)"-->
<!-- >查看</el-button>-->
<!-- <el-button-->
<!-- type="info"-->
<!-- size="small"-->
<!-- @click="editItem(scope.row)"-->
<!-- >编辑</el-button>-->
<el-popconfirm
confirm-button-text="确认"
cancel-button-text="取消"
:icon="InfoFilled"
icon-color="#626AEF"
title="确定要删除该服务项目?"
@confirm="deleteItem(scope.$index)"
@confirm="deleteItem(scope.row)"
>
<template #reference>
<el-button type="danger" size="small">删除</el-button>
@@ -154,7 +178,7 @@ import {
Edit,
Delete,
} from '@element-plus/icons-vue'
import { getGoodsList, addGoods, updateGoods } from '../../api/modules/goods.js'
import {getGoodsList, addGoods, updateGoods, delGoods} from '../../api/modules/goods.js'
import { addFile } from '../../api/modules/upload'
import { options } from './options.js'
import { onMounted, reactive, ref } from 'vue'
@@ -176,16 +200,29 @@ const formData = ref({
price: '',
carouselImage: [],
details: '',
isList: false
})
const fileBannerList = ref([]); // 轮播图
const fileDetail = ref(); // 详情图
// 页面初始化
const initData = () => {
getGoodsList(queryData.value).then((res) => {
tableData.value = res.data
let itemData = res.data.map(item => {
try {
// 尝试将字符串转换为 JSON 对象
item.carouselImage = JSON.parse(item.carouselImage);
} catch (error) {
// 设置一个默认值或者保留原来的字符串
item.carouselImage = {}; // 或者保留原来的字符串
}
return item;
});
tableData.value = itemData;
total.value = res.total
})
}
@@ -291,6 +328,33 @@ const handleError = (error, file, fileList) => {
console.error('上传失败:', error, file, fileList);
}
// 上下架处理
const upStatus = (env) => {
let formData = {
id: env.id,
isList: env.isList
};
updateGoods(formData).then((res) => {
if(formData.isList)
{
ElMessage({
message: '上架成功',
type: 'success',
});
}else{
let msg = '';
ElMessage({
message: '下架成功',
type: 'success',
});
}
initData();
});
}
// 格式化价格
const formatPrice = (price) => {
return parseFloat(price).toFixed(2);
@@ -299,7 +363,6 @@ const formatPrice = (price) => {
// 提交表单
const onSubmit = () => {
if (!formData.value.goodsName || !formData.value.price || !formData.value.details || formData.value.carouselImage.length < 1 ) {
ElMessage.error('请填写完整信息');
return;
@@ -338,6 +401,19 @@ const onSubmit = () => {
// }
}
// 点击取消
const cancelDrawer = () => {
drawer.value = false;
drawerEdit.value = false;
formData.value = {
goodsName: '',
price: '',
carouselImage: [],
details: '',
isList: false
}
}
// 分页切换
const handleCurrentChange = (val) => {
queryData.value.page = val
@@ -348,11 +424,6 @@ const handleCurrentChange = (val) => {
const editItem = (item) => {
formData.value = { ...item }
console.log('aaa', formData.value.carouselImage);
console.log('bbb', formData.value.details);
// fileBannerList.value.push(formData.value.carouselImage);
// fileDetail.value.push(formData.value.details);
drawer.value = true;
drawerEdit.value = true;
}
@@ -363,12 +434,21 @@ const viewItem = (item) => {
}
// 删除项
const deleteItem = (index) => {
tableData.value.splice(index, 1)
ElMessage({
message: '删除成功',
type: 'success',
})
const deleteItem = (env) => {
let ItemId = env.id; // 项目ID
// 删除
delGoods(ItemId).then((res) =>{
ElMessage({
message: '删除成功',
type: 'success',
});
initData(); // 重新加载数据
});
}
// 进入页面加载
@@ -378,30 +458,5 @@ onMounted(() => {
</script>
<style lang="scss" scoped>
.header-card {
margin-bottom: 20px;
}
.el-button--text {
margin-right: 15px;
}
.el-select {
width: 300px;
}
.el-input {
width: 300px;
}
.dialog-footer button:first-child {
margin-right: 10px;
}
.mt-4 {
float: right;
text-align: right;
margin-top: 20px;
margin-bottom: 20px;
}
</style>
+5 -1
View File
@@ -11,6 +11,11 @@ export const options = [
props: 'price',
width: '150',
align: 'left'
}, {
label: '状态',
props: 'isList',
width: '150',
align: 'left'
},
{
label: '标题图片',
@@ -23,7 +28,6 @@ export const options = [
props: 'details',
width: 'auto',
align: 'left',
show: true
},
{
label: '操作',
+109 -60
View File
@@ -14,34 +14,37 @@
</template>
<template #default>
<el-input
v-model="input1"
style="max-width: 600px;margin-bottom: 20px"
placeholder="请输入图片排序"
>
<template #prepend>序号</template>
</el-input>
<el-upload
class="upload-demo"
drag
action="https://repair.cpolar.top/file"
multiple
>
<el-icon class="el-icon--upload">
<upload-filled/>
</el-icon>
<div class="el-upload__text">
点击或拖拽上传图片
</div>
<template #tip>
<div class="el-upload__tip">
文件格式jpg/png
</div>
</template>
</el-upload>
<el-form
:model="formData"
label-width="auto" style="max-width: 600px">
<el-form-item label="序号">
<el-input
v-model="formData.sort"
type="number"
style="max-width: 600px;margin-bottom: 20px"
placeholder="请输入图片排序"
>
<template #prepend>序号</template>
</el-input>
</el-form-item>
<el-form-item label="首页图">
<el-upload
v-model:file-list="fileDetail"
list-type="picture-card"
:before-upload="beforeUpload"
:http-request="addUploadDetailFile"
:limit="5"
:on-exceed="handleDetailExceed"
:on-remove="handleDetailRemove"
>
<el-icon><Plus /></el-icon>
</el-upload>
</el-form-item>
</el-form>
<div style="display: flex;justify-content: flex-end;margin-top: 50px">
<el-button @click="cancelClick">取消</el-button>
<el-button @click="drawer = false">取消</el-button>
<el-button type="primary" @click="confirmClick">确认</el-button>
</div>
</template>
@@ -106,6 +109,8 @@ import {nextTick, onMounted, reactive, ref} from 'vue'
import {options} from './options.js'
import {getConfigList} from "../../api/modules/system";
import {addFile} from "../../api/modules/upload";
import {ElMessage} from "element-plus";
const tableData = ref([])
const dataList = ref([])
@@ -126,50 +131,94 @@ const queryData = ref({
size: 10,
})
const formData = ref({
sort: '',
img: ''
});
// 初始化数据
const initData = () => {
tableData.value = columnData.value;
getConfigList(queryData.value).then((res) => {
console.log(res.data)
// total.value = res.data.data.total
tableData.value = res.data
})
}
const itemEditHanld = (item) => {
item.itemEdit = !item.itemEdit
// // console.log(JSON.stringify(item));
// tabclickIndex.value = item;
}
const handleSizeChange = (val) => {
console.log(val)
}
const handleSelectionChange = (val) => {
}
const handleCurrentChange = (val) => {
queryData.value.size = 10
queryData.value.page = val
initData(queryData.value)
}
const handleClose = () => {
}
const dialogVisibleHanle = () => {
console.log('滑动加载')
}
const handleExpand = () => {
isExpand.value = false
tableData.value.forEach((item) => {
table.value.toggleRowExpansion(item, isExpand.value)
tableData.value = res.data[0]
})
}
const handleOpen = () => {
isExpand.value = true
tableData.value.forEach((item) => {
table.value.toggleRowExpansion(item, isExpand.value)
})
// 提交表单
const confirmClick = () => {
if (!formData.value.sort || !formData.value.img ) {
ElMessage.error('请填写完整信息');
return;
}
formData.value.img = JSON.stringify(formData.value.img); // 转为字符串
console.log('formData', formData)
}
// 上传前的钩子
const beforeUpload = (file) => {
const maxSize = 10 * 1024 * 1024; // 最大 2MB
if (file.size > maxSize) {
alert('文件大小不能超过 10MB');
return false;
}
const allowedTypes = ['image/jpeg', 'image/png'];
if (!allowedTypes.includes(file.type)) {
alert('只允许上传 JPEG 或 PNG 图片');
return false;
}
console.log('文件准备上传:', file);
return true;
}
// 详情图片上传限制
const handleDetailExceed= (files, uploadFiles) => {
ElMessage.warning(
`详情图最多可上传1张`
)
}
// 详情图移除
const handleDetailRemove = (file, fileList) => {
formData.value.img = '';
}
// 详情上传
const addUploadDetailFile = (params) => {
const formData = new FormData();
formData.append('files', params.file);
addFile(formData)
.then((response) => {
handleDetailSuccess(response, params.file, params.fileList);
})
.catch((error) => {
if(!error)
{
handleError(error, params.file, params.fileList);
}
});
}
// 处理详情上传成功的回调
const handleDetailSuccess = (response) => {
formData.value.img = response.data[0];
}
// 处理上传失败的回调
const handleError = (error, file, fileList) => {
console.error('上传失败:', error, file, fileList);
}
onMounted(() => {
initData()
})