商品类别

This commit is contained in:
yuanteng 2024-10-31 11:52:29 +08:00
parent 73e7049b71
commit 6cd9fed39b
4 changed files with 457 additions and 138 deletions

View File

@ -8,21 +8,19 @@ const router = createRouter({
routes, // `routes: routes` 的缩写
})
//路由的请求拦截器
//to 是即将进入的路由对象from 是当前离开的路由对象next 是一个函数,调用它会继续导航。
router.beforeEach((to, from, next) => {
const store = userStore()
if (to.name == 'login') {
//当回到登录页时清空pinia
store.$reset()
next()
return
const store = userStore();
if (to.name === 'login') {
// 当导航到登录页时清空 Pinia 状态
store.$reset();
next();
} else if (store.loginUser.userRole === "notLogin") {
// 如果未登录则重定向到登录页
next({ name: 'login' });
} else {
// 允许已登录用户导航
next();
}
if (store.loginUser.userRole == "notLogin") {
router.back()
return
}
if (store.loginUser.userRole != "notLogin") {
next()
return
}
})
});
export default router

View File

@ -39,5 +39,10 @@ export const routes = [
component: ()=> import("../views/Commodity/TypeManagement.vue")
}
]
}
},
{
path: '/Test',
name:'test',
component: () => import("../views/test.vue")
},
]

View File

@ -1,143 +1,161 @@
<template>
<div style="margin-bottom: 10px;">
<el-button type="success" @click="Add_type">添加类别</el-button>
<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="form" label-width="auto" style="max-width: 600px">
<el-dialog v-model="dialogVisible" title="商品类别" width="500">
<el-form :model="typeForm" label-width="auto" style="max-width: 600px">
<el-form-item label="类别图标">
<!-- <img src="https://s21.ax1x.com/2024/10/24/pAdzjZ6.png" alt="" @click="handleFileUpload"> -->
<div v-if="form.img">
<img :src="form.img" alt="类别图标" class="thumbnail" style="width: 100px; height: 100px;"/>
<div v-if="typeForm.typeUrl">
<img :src="typeForm.typeUrl" alt="类别图标" class="thumbnail" style="width: 100px; height: 100px;" />
</div>
<input type="file" @change="handleFileUpload" accept="image/*" />
<!-- <el-upload action="#" v-model:file-list="uploadedFiles" list-type="picture-card" :auto-upload="false" multiple="true">
<el-icon><Plus /></el-icon> -->
<!-- 上传文件 -->
<!-- <template #file="{ file }">
<div>
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<el-icon><zoom-in /></el-icon>
</span>
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<el-icon><Delete /></el-icon>
</span>
</span>
</div>
</template> -->
<!-- </el-upload> -->
</el-form-item>
<el-form-item label="类别名">
<el-input v-model="form.type_name" />
<el-input v-model="typeForm.typeName" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.tips" />
<el-input v-model="typeForm.typeIntro" />
</el-form-item>
</el-form>
<template #footer>
<template #footer #default="{ row, $index }">
<div class="dialog-footer">
<el-button @click="cancel" >取消</el-button>
<el-button type="primary" @click="dialogVisible = false">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="addOrUpdateType">
提交
</el-button>
</div>
</template>
</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'}">
<!-- 数据展示层 -->
<el-table :data="tableData" border style="width: 100%;" :header-cell-style="{ 'text-align': 'center' }"
@selection-change="handleSelectionChange" :cell-style="{ 'text-align': 'center', 'font-size': '16px' }">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="img" label="类别图片" width="300">
<template #default="scope"><img :src="scope.row.img" alt="" style="height: 50px;"></template>
<el-table-column prop="typeUrl" label="类别图片" width="300">
<!-- 插槽拿到父组件的值typeUrl -->
<!-- scope 提供了关于当前行的信息 -->
<template #default="scope"><img :src="scope.row.typeUrl" alt="" style="height: 50px;"></template>
</el-table-column>
<el-table-column prop="type_name" label="类别名称" width="150" ></el-table-column>
<el-table-column prop="tips" label="备注" ></el-table-column>
<el-table-column prop="operation" label="操作" >
<el-table-column prop="typeName" label="类别名称" width="150"></el-table-column>
<el-table-column prop="typeIntro" label="备注"></el-table-column>
<el-table-column prop="operation" label="操作">
<template #default="scope">
<el-button type="success" @click="Edit_type(scope.$index,scope.row)">修改类别</el-button>
<el-button type="danger" @click="Delete_type">删除类别</el-button>
<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>
<template #reference>
<el-button style="height: 25px" class="ml-5" type="danger">删除类别</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { userStore } from '../../store/userStore';
import { ElMessage } from 'element-plus';
import { onMounted, ref } from 'vue'
import myAxios from '@/api/myAxios';
const store = userStore()
const dialogImageUrl = ref('');
const disabled = ref(false);
const imageUrl = ref('')
const selectedItems = ref([])
const dialogVisible = ref(false)
const form = ref({
img: '',
type_name: '',
tips: ''
//
const typeForm = ref({
id: 0,
typeName: '',
typeUrl: '',
typeIntro: ''
})
const tableData = ref([
{
img: 'https://s21.ax1x.com/2024/10/24/pAdzjZ6.png',
type_name: '材料包',
tips: '提供用户自定义DIY',
}
])
//
const tableData = ref([])
// (0) (1)
const flag = ref(0)
const Add_type =()=>{
dialogVisible.value = true;
if(form.value.type_name) {
form.value = {
img: '',
type_name: '',
tips: ''
//
onMounted(() => {
getTypeList()
})
//
const getTypeList = async () => {
const res = await myAxios.post('/category/list')
// console.log(res.data.data)
if (res.data.code === 1) {
tableData.value = res.data.data
}
}
tableData.value.push(form.value)
}
//
const showForm = async () => {
dialogVisible.value = true;
flag.value = 0
}
//
const cancel = () => {
dialogVisible.value = false
resetForm();
resetForm()
}
//
const addOrUpdateType = async () => {
//
if (typeForm.value.typeName?.indexOf(' ') !== -1 ||
typeForm.value.typeName == '' || typeForm.value.typeUrl == '') {
ElMessage({
type: 'warning',
message: '不能为空格/空字符串'
})
return
}
//
dialogVisible.value = false;
if (flag.value === 0) {
const res = await myAxios.post('/category/add', {
//
typeName: typeForm.value.typeName,
typeUrl: typeForm.value.typeUrl.substring(0, 10),
typeIntro: typeForm.value.typeIntro
})
if (res.data.code === 1) {
//
resetForm()
} else {
ElMessage.error('提交失败')
}
}
if( flag.value === 1 ) {
const res = await myAxios.post('/category/update',{
id : typeForm.value.id,
typeName: typeForm.value.typeName,
typeUrl: typeForm.value.typeUrl,
typeIntro: typeForm.value.typeIntro
})
if (res.data.code === 1) {
//
ElMessage({
type: 'success',
message: '更新成功'
})
} else {
ElMessage.error('更新失败')
}
}
getTypeList()
}
//
const resetForm = () => {
form.value = {
img: '',
type_name: '',
tips: ''
typeForm.value = {
id: 0,
typeName: '',
typeUrl: '',
typeIntro: ''
}
};
// const handleClose = (done: () => void) => {
// ElMessageBox.confirm('?')
// .then(() => {
// done()
// })
// .catch(() => {
// // catch error
// })
// }
const handleSelectionChange = (row: any) => {
selectedItems.value = JSON.parse(JSON.stringify(row))
}
//
const handleFileUpload = (event: Event) => {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
@ -145,25 +163,31 @@ const handleFileUpload = (event: Event) => {
const reader = new FileReader();
reader.onload = (e) => {
if (e.target?.result) {
form.value.img = e.target.result as string; // URL
typeForm.value.typeUrl = e.target.result as string; // URL
}
};
reader.readAsDataURL(file); // Data URL
}
};
const Edit_type =(index: number, row: any)=>{
const editShowForm = (index: number, row: any) => {
dialogVisible.value = true
console.log(index,row)
form.value = row
typeForm.value = row
flag.value = 1
console.log(row)
}
const Delete_type =()=>{
}
const handleEdit = (index: number, row: any) => {
console.log(index, row)
// id
const Delete_type = async (index: number) => {
console.log(typeof index)
const res = await myAxios.post('/category/delete', { id: index })
console.log(res)
if (res.data.code === 1) {
ElMessage({
type: 'success',
message: '删除成功',
})
}
getTypeList()
}
</script>
<style scoped>
</style>
<style scoped></style>

292
src/views/test.vue Normal file
View File

@ -0,0 +1,292 @@
<template>
<el-form :model="formData" ref="formRef" label-width="auto" :rules="rules">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名" style="width: 800px" />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-select
v-model="formData.sex"
placeholder="请选择性别"
filterable
size="large"
style="width: 800px"
clearable
>
<el-option
v-for="item in sexOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
{{ item.label }}
</el-option>
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input-number
v-model="formData.age"
placeholder="请输入年龄"
style="width: 800px"
></el-input-number>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input
v-model="formData.address"
placeholder="请输入地址"
style="width: 800px"
></el-input>
</el-form-item>
</el-form>
<div class="mb-3">
<div class="font-bold text-16px">新增家庭信息</div>
</div>
<!-- 添加家庭信息 -->
<el-form ref="familyInfoRef">
<el-table :data="familyInfo" border>
<template #empty>
<div class="flex flex-row justify-center items-center space-x-2">
<span>点击 + 按钮新增家庭成员</span>
</div>
</template>
<el-table-column prop="relation" label="关系" align="center">
<template #default="{ row, $index }">
<el-input
v-if="$index === editingIndex"
v-model="row.relation"
placeholder="请输入关系"
size="small"
>
</el-input>
<span v-else>{{ row.relation }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" min-width="60px" align="center">
<template #default="{ row, $index }">
<el-input
v-if="$index === editingIndex"
v-model="row.name"
placeholder="请输入姓名"
size="small"
>
</el-input>
<span v-else>{{ row.name }}</span>
</template>
</el-table-column>
<el-table-column prop="sex" label="性别" min-width="100px" align="center">
<template #default="{ row, $index }">
<el-select
v-if="$index === editingIndex"
v-model="row.sex"
filterable
clearable
placeholder="请选择性别"
size="small"
style="width: 100%"
>
<el-option
v-for="item in sexOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span v-else>{{ getSexLabel(row.sex) }}</span>
</template>
</el-table-column>
<el-table-column prop="age" label="年龄" min-width="80px" align="center">
<template #default="{ row, $index }">
<el-input
v-if="$index === editingIndex"
v-model="row.age"
placeholder="请输入年龄"
size="small"
>
</el-input>
<span v-else>{{ row.age }}</span>
</template>
</el-table-column>
<el-table-column prop="address" label="地址" min-width="100px" align="center">
<template #default="{ row, $index }">
<el-input
v-if="$index === editingIndex"
v-model="row.address"
placeholder="请输入地址"
size="small"
>
</el-input>
<span v-else>{{ row.address }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="{ row, $index }">
<div class="flex flex-row justify-center items-center">
<template v-if="$index === editingIndex">
<el-button
type="success"
size="small"
plain
@click="handleSave(row, $index)"
>保存</el-button
>
<el-button
type="info"
size="small"
plain
@click="handleCancel(row, $index)"
>取消</el-button
>
</template>
<template v-else>
<el-button
type="primary"
size="small"
plain
@click="handleEdit(row, $index)"
>
修改
</el-button>
<el-popconfirm
title="是否确认删除?"
@confirm="handleDelete(row, $index)"
style="margin-left: 10px"
>
<template #reference>
<el-button type="danger" size="small" plain>删除</el-button>
</template>
</el-popconfirm>
</template>
</div>
</template>
</el-table-column>
</el-table>
</el-form>
<!-- 添加新行 -->
<div class="flex justify-center mt-[4px]">
<el-icon @click="handleAdd()" class="icon" size="24" color="#fb7a14"
><CirclePlusFilled />
</el-icon>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ElMessage, ElMessageBox, type FormInstance } from 'element-plus'
import { CirclePlusFilled } from '@element-plus/icons-vue'
/* --------------------------------- 用户数据类型 --------------------------------- */
interface User {
name: string
age: number
sex: string
address: string
email: string
}
interface FamilyInfo {
relation: string
name: string
age: number
sex: string
address: string
}
const sexOptions = [
{ value: 1, label: '男' },
{ value: 2, label: '女' }
]
/* ---------------------------------- 表格数据 ---------------------------------- */
const formData = reactive<User>({
name: '',
age: 0,
sex: '',
address: '',
email: ''
})
const formRef = ref<FormInstance>()
const familyInfo = ref<FamilyInfo[]>([])
const familyInfoRef = ref<FormInstance>()
const rules = {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
age: [{ required: true, message: '请选择出生日期', trigger: 'change' }],
sex: [{ required: true, message: '请选择性别', trigger: 'change' }]
}
/* ------------------------------ 当前编辑行下标 ------------------------------ */
const editingIndex = ref<number>(-1)
/* ------------------------------- 编辑行修改前的数据 ------------------------------- */
const beforeEditRow = ref<FamilyInfo>({
relation: '',
name: '',
age: 0,
sex: '',
address: ''
})
/* --------------------------------- 新增行的空数据 -------------------------------- */
const addContractRow: FamilyInfo = {
relation: '',
name: '',
age: 0,
sex: '',
address: ''
}
/* ---------------------------------- 重置编辑行 --------------------------------- */
const resetTable = () => {
editingIndex.value = -1
beforeEditRow.value = { ...addContractRow }
}
/* ---------------------------------- 表格操作 ---------------------------------- */
const handleAdd = () => {
if (editingIndex.value > -1) {
ElMessage.warning('请先完成修改中的行')
return
}
editingIndex.value = familyInfo.value.length
familyInfo.value.push({ ...addContractRow })
}
const handleEdit = (row: FamilyInfo, index: number) => {
if (editingIndex.value > -1) {
ElMessage.warning('请先完成修改中的行')
return
}
beforeEditRow.value = { ...row }
editingIndex.value = index
}
const handleSave = (row: FamilyInfo, index: number) => {
if (!row.relation || !row.name || !row.age || !row.sex) {
ElMessage.warning('请填写所有必填字段再保存')
return
}
familyInfo.value[index] = { ...row }
resetTable()
}
const handleDelete = (row: FamilyInfo, index: number) => {
familyInfo.value.splice(index, 1)
}
const handleCancel = (row: FamilyInfo, index: number) => {
if (Object.values(beforeEditRow.value).some((value) => value !== '')) {
familyInfo.value[index] = { ...beforeEditRow.value }
} else {
familyInfo.value.splice(index, 1)
}
resetTable()
}
const getSexLabel = (value: number) => {
return sexOptions.find((option) => option.value === value)?.label || ''
}
</script>