商城后台管理系统 04,商品添加-清空列表

商品添加-清空列表 实现代码如下:
复制代码
1,src/views/Goods/Goods.vue
<template>
	<div class="goods">
		<!-- 1,搜索区域 -->
		<div class="header">
			<!-- 仅在输入框失去焦点或用户按下回车时触发 -->
			<el-input @change="searchInput" v-model="input" placeholder="请输入内容"></el-input>
			<el-button type="primary">查询</el-button>
			<!-- 页面添加 -->
			<el-button type="primary">
				<router-link to="/add-goods" style="color: #fff;">页面添加</router-link>
			</el-button>
			<!-- 弹窗添加 -->
			<el-button type="primary" @click="addGoods">弹框添加</el-button>
		</div>
		<!-- 2, 表格区域 展示视图数据  -->
		<div class="wrapper">
			<el-table :data="tableData" border @selection-change="handleSelectionChange">
				<el-table-column type="selection" width="55">
				</el-table-column>
				<el-table-column prop="id" label="商品ID" width="100">
				</el-table-column>
				<el-table-column prop="title" label="商品名称" width="100" show-overflow-tooltip>
				</el-table-column>
				<el-table-column prop="price" label="商品价格" width="100">
				</el-table-column>
				<el-table-column prop="num" label="商品数量" width="100">
				</el-table-column>
				<el-table-column prop="category" label="规格类目" width="100">
				</el-table-column>
				<el-table-column prop="image" label="商品图片" show-overflow-tooltip>
				</el-table-column>
				<el-table-column prop="sellPoint" label="商品卖点" show-overflow-tooltip>
				</el-table-column>
				<el-table-column prop="descs" label="商品描述" show-overflow-tooltip>
				</el-table-column>
				<el-table-column label="操作" width="180">
					<template slot-scope="scope">
						<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
						<el-button size="mini" type="danger"
							@click="handleDelete(scope.$index, scope.row)">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
		</div>

		<!-- 3, 分页展示  接收页码-->
		<MyPagination :total="total" :pageSize="pageSize" @changePage="changePage" :currentPage="currentPage" />
		<!-- 4, 显示弹框组件   :dialogVisible="dialogVisible"传值给子组件 GoodsDialog.vue-->
		<!-- 在调动资源的父组件位置 接收一个自定义事件 @changeDialog="changeDialog"-->
		<!--显示弹框组件  操作子组件:1, 父传子  2, children  3,ref -->
		<GoodsDialog :dialogVisible="dialogVisible" @changeDialog="changeDialog" />
		<!-- <GoodsDialog ref='dialog' /> -->
	</div>
</template>

<script>
	import MyPagination from '@/components/MyPagination.vue';
	import GoodsDialog from '@/views/Goods/GoodsDialog.vue';
	export default {
		components: {
			MyPagination,
			GoodsDialog
		},
		data() {
			return {
				// 声明变量
				input: "",
				tableData: [],
				total: 10,
				pageSize: 1,
				type: 1,
				list: [],
				dialogVisible: false,
				currentPage: 1, // 选中的高亮页码
			};
		},
		methods: {
			// 添加商品 -- 出现弹窗
			addGoods() {
				// 当点击 '弹框添加' 时,把变量dialogVisible赋值为true
				this.dialogVisible = true;
				// 修改子组件实例的数据
				// this.$refs.dialog.dialogVisible = true;
			},
			changeDialog() {
				this.dialogVisible = false;
			},
			// 分页的页码  搜索状态的分页
			changePage(num) {
				this.currentPage = num;
				if (this.type == 1) {
					this.http(num); // 商品列表分页
				} else {
					// 搜索分页 1,2,3-- list=[1,2,3,4,5,6,7,8]	0-3 3-6 6-9 9-12
					console.log('搜索的分页处理--', 截取分页的长度);
					// (num-1)*3 num*3  安装一个list容器
					this.tableData = this.list.slice((num - 1) * 3, num * 3);
				}
			},
			// 搜索查询的数据
			searchInput(val) {
				// 当没有搜索时,返回到商品列表页
				if (!val) {
					this.http(1);
					this.currentPage = 1;
					this.type = 1;
					return;
				}
				// console.log('搜索---', val);
				this.$api.getSearch({
					search: val
				}).then((res) => {
					console.log('搜索---', res.data);
					// 初始化为 1
					this.currentPage = 1;
					if (res.data.status === 200) {
						// 获取搜索总数据的条数---数据分割
						this.list = res.data.result;
						// 让前台匹配数据,这个数据就先不要赋值了
						// this.tableData = res.data.result;
						// 假设需要分页----我们处理分页
						// 1, 获取总数据
						this.total = res.data.result.length;
						// 2, 撤数据 正常情况下都是让后台匹配字段,我们这里让前台匹配
						this.pageSize = 3;
						// 3,赋值截取字段
						this.tableData = res.data.result.slice(0, 3);
						// 4, 搜索分页处理
						this.type = 2;
						// this.currentPage = 1;
						console.log('分页', this.currentPage);
					} else {
						this.tableData = [];
						this.total = 1;
						this.pageSize = 1;
						this.type = 1;
						// this.currentPage = 1;
					}
				})
			},
			// 编辑操作
			handleEdit() {},
			// 删除操作
			handleDelete() {},
			// 选择数据
			handleSelectionChange(val) {
				this.multipleSelection = val;
			},
			// 商品列表的获取 封装http 结构赋值
			http(page) {
				this.$api.getGoodsList({
					page,
				}).then((res) => {
					console.log('获取商品列表数据', res.data);
					if (res.data.status === 200) {
						// 数据列表
						this.tableData = res.data.data;
						this.total = res.data.total;
						this.pageSize = res.data.pageSize;
					}
				});
			},
		},
		// 生命周期函数
		created() {
			this.http(1);
		}
	};
</script>

<style lang="less" scoped>
	.goods {
		margin: 20px;
	}

	.header {
		display: flex;

		button {
			margin-left: 20px;
		}
	}

	.wrapper {
		margin: 20px 0;
	}
</style>









2,src/views/Goods/GoodsDialog.vue

<template>
	<div>
		<!-- 
		title="添加商品" 弹框的标题
		:visible.sync="dialogVisible" 控制弹框的显示与隐藏 boolean true 表示显示
		width="70%" 宽度 大小
		 -->
		<el-dialog title="添加商品" :visible.sync="dialogVisible" width="70%" :before-close="clearForm">
			<!-- 中间弹框内容区域 -->
			<!-- 添加商品表单数据 -->
			<div class="myform">
				<el-form :model="goodsForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
					<el-form-item label="类目选择" prop="category">
						<el-button type="primary" @click="innerVisible=true">类目选择</el-button>
						<span>{{goodsForm.category}}</span>
					</el-form-item>
					<el-form-item label="商品名称" prop="title">
						<el-input v-model="goodsForm.title"></el-input>
					</el-form-item>
					<el-form-item label="商品价格" prop="price">
						<el-input v-model="goodsForm.price"></el-input>
					</el-form-item>
					<el-form-item label="商品数量" prop="num">
						<el-input v-model="goodsForm.num"></el-input>
					</el-form-item>
					<el-form-item label="发布时间" required>
						<el-col :span="11">
							<el-form-item prop="date1">
								<el-date-picker type="date" placeholder="选择日期" v-model="goodsForm.date1"
									style="width: 100%;"></el-date-picker>
							</el-form-item>
						</el-col>
						<el-col class="line" :span="2">-</el-col>
						<el-col :span="11">
							<el-form-item prop="date2">
								<el-time-picker placeholder="选择时间" v-model="goodsForm.date2"
									style="width: 100%;"></el-time-picker>
							</el-form-item>
						</el-col>
					</el-form-item>
					<el-form-item label="商品卖点" prop="sellPoint">
						<el-input v-model="goodsForm.sellPoint"></el-input>
					</el-form-item>
					<el-form-item label="商品图片" prop="image">
						<el-button type="primary" @click="innerVisibleImg=true">上传图片</el-button>
						<img :src="goodsForm.image" height="200px" style="margin-left: 10px;" alt="" />
					</el-form-item>
					<el-form-item label="商品描述" prop="descs">
						<!-- 父组件接收 sendEditor 数据 -->
						<WangEditor ref="myEditor" @sendEditor="sendEditor" />
					</el-form-item>
					<el-form-item label="活动区域" prop="region">
						<el-select v-model="goodsForm.region" placeholder="请选择活动区域">
							<el-option label="区域一" value="shanghai"></el-option>
							<el-option label="区域二" value="beijing"></el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="即时配送" prop="delivery">
						<el-switch v-model="goodsForm.delivery"></el-switch>
					</el-form-item>
					<el-form-item label="活动性质" prop="type">
						<el-checkbox-group v-model="goodsForm.type">
							<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
							<el-checkbox label="地推活动" name="type"></el-checkbox>
							<el-checkbox label="线下主题活动" name="type"></el-checkbox>
							<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
						</el-checkbox-group>
					</el-form-item>
					<el-form-item label="特殊资源" prop="resource">
						<el-radio-group v-model="goodsForm.resource">
							<el-radio label="线上品牌商赞助"></el-radio>
							<el-radio label="线下场地免费"></el-radio>
						</el-radio-group>
					</el-form-item>
					<el-form-item label="活动形式" prop="desc">
						<el-input type="textarea" v-model="goodsForm.desc"></el-input>
					</el-form-item>
					<!-- <el-form-item>
						<el-button type="primary" @click="submitForm('goodsForm')">确定</el-button>
						<el-button @click="resetForm('goodsForm')">重置</el-button>
					</el-form-item> -->
				</el-form>
			</div>
			<!-- 弹框的底部区域 -->
			<span slot="footer" class="dialog-footer">
				<!-- ref -->
				<el-button @click="clearForm">取消</el-button>
				<el-button type="primary" @click="submitForm">确 定</el-button>
				<!-- 父传子 -->
				<!-- <el-button @click="close">取消</el-button>
				<el-button type="primary" @click="close">确 定</el-button> -->
			</span>
			<!-- 1, 内弹框 --类目选择-->
			<el-dialog width="40%" title="类目选择" :visible.sync="innerVisible" append-to-body>
				<!-- 父组件接收 sendTreeData 数据 -->
				<TreeGoods @sendTreeData="sendTreeData" />

				<!-- 弹框的底部区域 -->
				<span slot="footer" class="dialog-footer">
					<!-- ref -->
					<!-- <el-button @click="innerVisible = false">取 消</el-button>
					<el-button type="primary" @click="innerVisible = false">确 定</el-button> -->
					<!-- 父传子 -->
					<el-button @click="close">取消</el-button>
					<el-button type="primary" @click="showTreeData">确 定</el-button>
				</span>
			</el-dialog>
			<!-- 2, 内弹框 --上传图片-->
			<el-dialog width="40%" title="上传图片" :visible.sync="innerVisibleImg" append-to-body>
				<!-- 父组件接收 sendImg 数据 -->
				<UploadImg @sendImg="sendImg" />

				<!-- 弹框的底部区域 -->
				<span slot="footer" class="dialog-footer">
					<!-- ref -->
					<el-button @click="innerVisibleImg = false">取 消</el-button>
					<el-button type="primary" @click="showImg">确 定</el-button>
					<!-- <el-button type="primary" @click="innerVisibleImg = false">确 定</el-button> -->
					<!-- 父传子 -->
					<!-- <el-button @click="close">取消</el-button>
					<el-button type="primary" @click="showTreeData">确 定</el-button> -->
				</span>
			</el-dialog>
		</el-dialog>
	</div>
</template>

<script>
	import TreeGoods from '@/views/Goods/TreeGoods.vue';
	import UploadImg from '@/views/Goods/UploadImg.vue';
	import WangEditor from '@/views/Goods/WangEditor.vue';
	export default {
		components: {
			TreeGoods,
			UploadImg,
			WangEditor
		},
		// 接收父组件(Goods.vue)传值dialogVisible
		props: ['dialogVisible'],
		data() {
			return {
				// dialogVisible: false, // 外弹框
				innerVisible: false, // 内弹框
				innerVisibleImg: false, // 图片弹框
				treeData: {}, // 接收 tree 数据
				imgUrl: '', // 图片地址
				goodsForm: { // 表单容器-对象
					title: '', // 商品的名称
					price: '', // 商品的价格
					num: '', // 商品的数量
					sellPoint: '', // 商品的卖点
					image: '', // 商品的图片
					descs: '', // 商品的描述
					cid: '', // 类目的id
					category: '', // 商品的类目
					// time: '', // 商品发布时间					
					date1: '',
					date2: '',
					// region: '',
					// delivery: false,
					// type: [],
					// resource: '',
					// desc: ''
				},
				rules: { // 效验规则
					title: [{
							required: true,
							message: '请输入商品名称',
							trigger: 'blur'
						},
						{
							min: 2,
							max: 8,
							message: '长度在 2 到 8 个字符',
							trigger: 'blur'
						}
					],
					price: [{
							required: true,
							message: '请输入商品价格',
							trigger: 'blur'
						}
						// {
						// 	min: 3,
						// 	max: 5,
						// 	message: '长度在 3 到 5 个字符',
						// 	trigger: 'blur'
						// }
					],
					num: [{
							required: true,
							message: '请输入商品数量',
							trigger: 'blur'
						}
						// {
						// 	min: 3,
						// 	max: 5,
						// 	message: '长度在 3 到 5 个字符',
						// 	trigger: 'blur'
						// }
					],
					name: [{
							required: true,
							message: '请输入活动名称',
							trigger: 'blur'
						},
						{
							min: 3,
							max: 5,
							message: '长度在 3 到 5 个字符',
							trigger: 'blur'
						}
					],
					region: [{
						// required: true,
						message: '请选择活动区域',
						trigger: 'change'
					}],
					date1: [{
						type: 'date',
						required: true,
						message: '请选择日期',
						trigger: 'change'
					}],
					date2: [{
						type: 'date',
						required: true,
						message: '请选择时间',
						trigger: 'change'
					}],
					type: [{
						type: 'array',
						// required: true,
						message: '请至少选择一个活动性质',
						trigger: 'change'
					}],
					resource: [{
						// required: true,
						message: '请选择活动资源',
						trigger: 'change'
					}],
					desc: [{
						// required: true,
						message: '请填写活动形式',
						trigger: 'blur'
					}]
				}
			};
		},
		methods: {
			// 接收 wangEditor 数据
			sendEditor(val) {
				// 存储
				this.goodsForm.descs = val;
			},
			// 显示图片地址
			sendImg(val) {
				console.log('显示图片地址', val);
				this.imgUrl = val;
			},
			// 显示图片---确定按钮
			showImg() {
				// 让内弹框隐藏
				this.innerVisibleImg = false;
				// 渲染图片到页面
				this.goodsForm.image = this.imgUrl;
			},
			// 显示 tree 的数据
			showTreeData() {
				// 关闭内弹框
				this.innerVisible = false;
				// 显示 tree 数据
				this.goodsForm.category = this.treeData.name;
				this.goodsForm.cid = this.treeData.cid;
			},
			// 获取 tree 数据
			sendTreeData(val) {
				console.log('tree数据', val);
				this.treeData = val;
			},
			// 自定义事件--通知父组件--修改变量 dialogVisible
			close() {
				// 赋值
				// this.$emit('changeDialog', false);
				this.$emit('changeDialog');
			},
			submitForm() {
				this.$refs.ruleForm.validate((valid) => {
					if (valid) {
						console.log('获取输入的信息', this.goodsForm);
						// 结构赋值
						// title cid category sellPoint price num descs paramsInfo image
						let {
							title,
							cid,
							category,
							sellPoint,
							price,
							num,
							descs,
							// paramsInfo,
							image
						} = this.goodsForm;
						this.$api.addGoods({
								title,
								cid,
								category,
								sellPoint,
								price,
								num,
								descs,
								// paramsInfo,
								image
							})
							.then(res => {
								console.log('添加--实现--', res.data);
								if (res.data.status === 200) {
									// 成功 
									this.$parent.http(1); // 2,更新父组件列表数据
									this.$message({ // 3. 消息提示
										message: "恭喜你,添加商品成功",
										type: "success"
									});
									// 清空表单
									this.clearForm();
								} else {
									// 失败
									this.$message.error('错了,这是一条错误的消息');
								}
							})
						// alert('submit!');
					} else {
						console.log('error submit!!');
						return false;
					}
				});
			},
			/**
			 * 清空表单数据列表
			 */
			clearForm() {
				this.dialogVisible = false; // 1,关闭弹框按钮
				// 4,清空表单
				// 4.1 使用 element 里面的重置表单
				// 4.2 自己手动初始化 goodsForm 表格数据
				this.$refs.ruleForm.resetFields();
				// 单独--清空编辑器内容--editor.txt.clear()
				this.$refs.myEditor.editor.txt.clear();
			}

			// resetForm(formName) {
			// 	this.$refs[formName].resetFields();
			// }
		}
	}
</script>

<style lang="less" scoped>
	.myform {
		background: #fff;
		padding: 20px;
		padding-right: 30px;
	}

	.line {
		text-align: center;
	}
</style>









3,src/views/Goods/wangEditor.vue

<template>
	<div id="main">
		<!-- <p>富文本编辑</p> -->
	</div>
</template>

<script>
	import E from 'wangeditor'

	export default {
		data() {
			return {
				// 声明一个editor全局变量,这样我们操作属性就方便使用了
				editor: ''
			}
		},
		mounted() {
			// 创建 wangeditor 实例  通过this.xx去拿值
			this.editor = new E('#main');

			// 取消自动 focus
			this.editor.config.focus = false;

			// 配置 onchange 回调函数 获取当前编辑框编辑输入值的内容
			// 将普通函数改为箭头函数
			this.editor.config.onchange = newHtml => {
				// console.log("change之后最新的html", newHtml);
				// 把获取的富文本编辑内容--传递给弹框组件--父组件
				this.$emit('sendEditor', newHtml);
			};

			// 普通函数如下:
			// this.editor.config.onchange = function(newHtml) {
			// 	console.log("change之后最新的html", newHtml);
			// 	// 把获取的富文本编辑内容--传递给弹框组件--父组件
			// };

			// 配置触发 onchange 的时间频率,默认为 200 ms
			this.editor.config.onchange.Timeout = 500; // 修改为 500ms

			// 配置菜单栏 删减菜单 调整顺序
			// this.editor.config.menus = ["bold", "head", "link", "italic", "underline"];
			this.editor.config.menus = [
				"head",
				"bold",
				"fontSize",
				"fontName",
				"italic",
				"underline",
				"strikeThrough",
				"indent",
				"lineHeight",
				"foreColor",
				"backColor",
				"link",
				"list",
				"todo",
				"justify",
				"quote",
				"emoticon",
				"image",
				"video",
				"table",
				"code",
				"splitLine",
				"undo",
				"redo",
			];

			// 创建菜单
			this.editor.create();
			// 可获取编辑器所有菜单,从中找到自己想要的菜单 key 即可
			// console.log(this.editor.getAllMenuKeys())
		}
	}
</script>

<style>
</style>








4, src/api/base.js
/**
 * 接口的路径配置:
 * 一般文件目录: base.js index.js
 * 	base.js : 放所有路径的配置
 *  index.js: 放所有请求的方法
 */

const base = {
	host: 'http://localhost:8989', // 基础域名
	goodsList: '/api/api/projectList', // 商品列表
	search: '/api/api/search', // 商品的搜索功能
	selectCategory: '/api/api/backend/itemCategory/selectItemCategoryByParentId', // 类目选择
	uploadUrl: '/api/api/upload', // 图片上传  post请求
	addGoods: '/api/api/backend/item/insertTbItem', // 添加商品 
}

export default base;







5, src/api/index.js
/**
 * 所有请求的方法
 */

import axios from "axios";
import base from "./base";
const api = {
	/**
	 * 商品列表方法
	 */
	getGoodsList(params) { // {page:xx}
		return axios.get(base.goodsList, {
			params
		})
	},
	/**
	 * 搜索商品数据方法
	 * search
	 */
	getSearch(params) { // {search: xx}
		return axios.get(base.search, {
			params
		})
	},
	/**
	 * 获取类目选择
	 * {id: cid}
	 */
	getSelectCategory(params) {
		return axios.get(base.selectCategory, {
			params
		})
	},
	/**
	 * 添加商品
	 * 参数: title cid category sellPoint price num desc paramsInfo image
	 */
	addGoods(params) { // = {}
		return axios.get(base.addGoods, {
			params
		})
	},
}

export default api;






6, server/router.js
// 专门放所有的接口  这里只写一部分大约有二十几个接口

// 导入 express 
const express = require('express')
// 使用里面的 Router() 这个方法
const router = express.Router()

// 导入 multer
const multer = require('multer')

// 导入 fs
const fs = require('fs')

// token 
// const jwt = require('jsonwebtoken')

// 秘钥
// const config = require('./secert.js')

// 导入数据库 sqlFn('sql',[],res=>{})
const sqlFn = require('./mysql.js')

// 图片上传支持的模块
// const multer = require('multer')
// const fs = require('fs')


// 测试接口
// router.get('/', (req, res) => {
// 	res.send('hello')
// })

// 路由接口

// 登录接口
/**
 * 语法
 * 如 60,'2 day','10h','7d',expiration time 过期时间
 * jwt.sign({},'秘钥','过期时间',{expiresIn: 20*1,'1 day','1h'})
 */
/**
 * 登录 login
 */
// router.post('/login', (req, res) => {
// 	//
// })

/**
 * 注册接口 /register
 */
// router.post('/register', (req, res) => {
// 	//
// })

/**
 * 商品列表:获取分页 {total: '',arr:[{},{},{}],pagesize:8,}
 * 参数:page 页码
 */
router.get('/projectList', (req, res) => {
	const page = req.query.page || 1;
	const sqlLen = "select * from project where id";
	sqlFn(sqlLen, null, data => {
		let len = data.length;
		const sql = "select * from project order by id desc limit 8 offset" + (page - 1) * 8;
		sqlFn(sql, null, result => {
			if (result.length > 0) {
				res.send({
					status: 200,
					data: result,
					pageSize: 8,
					total: len
				})
			} else {
				res.send({
					status: 200,
					msg: "暂无数据"
				})
			}
		})
	})
})


// router.get('/projectList', (req, res) => {
// 	// 接收页码 可以不传 默认为1
// 	const page = req.query.page || 1;
// 	// 根据 id 去查 project 表
// 	const sqlLen = "select * from project where id";

// 	sqlFn(sqlLen, null, data => {
// 		let len = data.length;
// 		const sql = "select * from project order by id desc limit 8 offset" + (page - 1) * 8;
// 		sqlFn(sql, null, result => {
// 			if (result.length > 0) {
// 				// 返回数据
// 				res.send({
// 					status: 200,
// 					data: result,
// 					pageSize: 8,
// 					total: len
// 				})
// 			} else {
// 				// 返回数据
// 				res.send({
// 					status: 500,
// 					msg: "暂无数据"
// 				})
// 			}
// 		})
// 	})
// })


/**
 * 商品查询接口 search
 * 参数: search
 */
router.get("/search", (req, res) => {
	var search = req.query.search;
	const sql = "select * from project where concat(`title`,`sellPoint`,`descs`) like '%" + search + "%'";
	sqlFn(sql, null, (result) => {
		if (result.length > 0) {
			res.send({
				status: 200,
				data: result
			})
		} else {
			res.send({
				status: 500,
				msg: '暂无数据'
			})
		}
	})
})


/** 类目选择
 * 接口说明:接口不同的参数 cid 返回不同的类目数据,后台接受变量 id
 */
router.get('/backend/itemCategory/selectItemCategoryByParentId', (req, res) => {
	const id = req.query.id || 1;
	const sql = 'select * from category where id=?'
	var arr = [id];
	sqlFn(sql, arr, result => {
		if (result.length > 0) {
			res.send({
				status: 200,
				result
				// data: result
			})
		} else {
			res.send({
				status: 500,
				msg: '暂无数据'
			})
		}
	})
})


/**
 * 类目结构数据获取
 */
router.get('/category/data', (req, res) => {
	var cid = req.query.cid;
	var sql = "select * from params where itemCatId=?";
	sqlFn(sql, [cid], result => {
		if (result.length > 0) {
			res.send({
				status: 200,
				result
				// data: result
			})
		} else {
			res.send({
				status: 500,
				msg: '暂无数据'
			})
		}
	})
})


/**
 * 上传图片 post 请求 upload
 * 说明:
 * 1, 后台安装 multer 图片模块 同时引入 fs 文件模块  
 * 2,router.js 入口文件导入 模块
 *	const fs = require('fs')	//fs是属于nodejs,只需引入即可
 *	const multer=require('multer') // multer是需要安装的
 * 3, 上传图片 可以跨域 需要配置 cors index.js 导入文件,并配置 cors跨域
 * 4, 在服务端 server 根目录下创建 upload 文件夹,专门装图片的文件
 */
var storage = multer.diskStorage({
	destination: function(req, file, cb) {
		cb(null, './upload/')
	},
	filename: function(req, file, cb) {
		cb(null, Date.now() + "-" + file.originalname)
	}
})

var createFolder = function(folder) {
	try {
		fs.accessSync(folder);
	} catch (e) {
		fs.mkdirSync(folder);
	}
}

var uploadFolder = './upload';
createFolder(uploadFolder);
var upload = multer({
	storage: storage
});

router.post('/upload', upload.single('file'), function(req, res, next) {
	var file = req.file;
	console.log('文件类型,%s', file.mimetype);
	console.log('原始文件名,%s', file.originalname);
	console.log('文件大小,%s', file.size);
	console.log('文件保存路径,%s', file.path);
	res.json({
		res_code: '0',
		name: file.originalname,
		url: file.path
	});
});


/**
 * 商品添加接口
 * 参数: title cid category sellPoint price num descs paramsInfo image
 */
router.get('/backend/item/insertTbItem', (req, res) => {
	// 获取参数
	var title = req.query.title || "";
	var cid = req.query.cid || "";
	var category = req.query.category || "";
	var sellPoint = req.query.sellPoint || "";
	var price = req.query.price || "";
	var num = req.query.num || "";
	var desc = req.query.descs || "";
	var paramsInfo = req.query.paramsInfo || "";
	var image = req.query.image || "";

	const sql = "insert into project values (null,?,?,?,?,?,?,?,'',1,'','',?,?)"
	var arr = [title, image, sellPoint, price, cid, category, num, desc, paramsInfo];
	sqlFn(sql, arr, result => {
		if (result.affectedRows > 0) {
			res.send({
				status: 200,
				msg: "添加成功"
			})
		} else {
			res.send({
				status: 500,
				msg: "添加失败"
			})
		}
	})
})


/**
 * 商品删除 接口 id
 */
router.get("/backend/item/deleteItemById", (req, res) => {
	var id = req.query.id;
	const sql = "delete from project where id=?"
	const arr = [id];
	sqlFn(sql, arr, result => {
		if (result.affectedRows > 0) {
			res.send({
				status: 200,
				msg: "删除成功"
			})
		} else {
			res.send({
				status: 500,
				msg: '删除失败'
			})
		}
	})
})


/**
 * 批量删除: batchDelete idArr id 标识
 * sql = "delete from A where in in (1,2,3)"
 */
router.get("/batchDelete", (req, res) => {
	let arr = req.query.idArr; // []数组格式 需要传递数据是 离散的数字格式
	// const sql = 'delete from project where id in (?)';
	let sql = '';

	function fun(arr) { // sql=`delete from project where id in (101,102,103`;
		sql = `delete from project where id in (`
		for (let i = 0; i < arr.length; i++) {
			sql += arr[i] + ',' // 101,102,
		}
		sql = sql.slice(0, -1)
		sql = sql + ')'
		// console.log(sql);
	}
	fun(arr)
	sqlFn(sql, null, result => {
		if (result.affectedRows > 0) {
			res.send({
				status: 200,
				msg: "删除成功"
			})
		} else {
			res.send({
				status: 500,
				msg: "删除失败"
			})
		}
	})



	/**
	 * 修改商品
	 */
	router.get("/backend/item/updateTbItem", (req, res) => {
		var id = req.query.id;
		var title = req.query.title || "";
		var sellPoint = req.query.sellPoint || "";
		var price = req.query.price || "";
		var cid = req.query.cid || "";
		var category = req.query.category || "";
		var num = req.query.num || "";
		var desc = req.query.desc || "";
		var paramsInfo = req.query.paramsInfo || "";
		var image = req.query.image || "";
		var sql =
			"update project set title=?,sellPoint=?,price=?,cid=?,category=?,num=?,descs=?,paramsInfo=?,image=?"
		var arr = [title, sellPoint, price, cid, category, num, desc, paramsInfo, image, id];
		sqlFn(sql, arr, result => {
			if (result.affectedRows > 0) {
				res.send({
					status: 200,
					msg: "修改成功"
				})
			} else {
				res.send({
					status: 500,
					msg: "修改失败"
				})
			}
		})
	})
})


module.exports = router
商品删除 接口 id
复制代码
/**
* 商品删除 接口 id
*/
router.get("/backend/item/deleteItemById", (req,res) => {
	var id = req.query.id;
	const sql = "delete from project where id=?"
	const arr = [id];
	sqlFn(sql,arr,result => {
		if (result.affectedRows > 0) {
			res.send({
				status: 200,
				msg: "删除成功"
			})
		} else {
			res.send({
				status: 500,
				msg: '删除失败'
			})
		}
	})
})
批量删除 接口
复制代码
/**
* 批量删除: batchDelete idArr id 标识
* sql = "delete from A where in in (1,2,3)"
*/
router.get("/batchDelete", (req,res) => {
	let arr = req.query.idArr; // []数组格式 需要传递数据是 离散的数字格式
	// const sql = 'delete from project where id in (?)';
	let sql = '';
	function fun(arr) { // sql=`delete from project where id in (101,102,103`;
		sql = `delete from project where id in (`
		for (let i = 0; i < arr.length; i++) {
			sql += arr[i] + ',' // 101,102,
		}
		sql = sql.slice(0,-1)
		sql = sql + ')'
		// console.log(sql);
	}
	fun(arr)
	sqlFn(sql,null,result => {
		if (result.affectedRows > 0) {
			res.send({
				status: 200,
				msg: "删除成功"
			})
		} else {
			res.send({
				status: 500,
				msg: "删除失败"
			})
		}
	})
})
修改商品接口
复制代码
/**
* 修改商品
*/
router.get("/backend/item/updateTbItem",(req,res) => {
	var id = req.query.id;
	var title = req.query.title || "";
	var sellPoint = req.query.sellPoint || "";
	var price = req.query.price || "";
	var cid = req.query.cid || "";
	var category = req.query.category || "";
	var num = req.query.num || "";
	var desc = req.query.desc || "";
	var paramsInfo = req.query.paramsInfo || "";
	var image = req.query.image || "";
	var sql = "update project set title=?,sellPoint=?,price=?,cid=?,category=?,num=?,descs=?,paramsInfo=?,image=?"
	var arr = [title,sellPoint,price,cid,category,num,desc,paramsInfo,image,id];
	sqlFn(sql,arr,result => {
		if (result.affectedRows > 0) {
			res.send({
				status: 200,
				msg: "修改成功"
			})
		} else {
			res.send({
				status: 500,
				msg: "修改失败"
			})
		}
	})
})

规格参数列表接口

复制代码
/**
 * 规格参数列表  参数 page
 */
router.get("/backend/itemParam/selectItemParamAll", (req, res) => {
	const page = req.query.page || 1;
	const sqlLen = "select * from params where id";
	sqlFn(sqlLen, null, data => {
		let len = data.length;
		const sql = "select * from params order by id desc limit 8 offset" + (page - 1) * 8;
		sqlFn(sql, null, result => {
			if (result.length > 0) {
				res.send({
					status: 200,
					data: result,
					pageSize: 8,
					total: len
				})
			} else {
				res.send({
					status: 500,
					msg: '暂无数据'
				})
			}
		})
	})
})
相关推荐
哆啦A梦15882 小时前
商城后台管理系统 06,类目选择实现
javascript·vue.js·elementui
少年张二狗2 小时前
Vue + Element-UI 图片上传实现拖拽排序功能
前端·vue.js·ui
qingyun9892 小时前
使用递归算法深度收集数据结构中的点位信息
开发语言·javascript·ecmascript
哆啦A梦15882 小时前
【vue实战】商城后台管理系统 01 项目介绍
前端·javascript·vue.js
布茹 ei ai3 小时前
5、基于 GEE 的 Sentinel-1 SAR 地震滑坡变化检测系统:2022 泸定地震案例
javascript·sentinel·遥感·gee·云平台
一字白首3 小时前
Vue Router 进阶,声明式 / 编程式导航 + 重定向 + 404 + 路由模式
前端·javascript·vue.js
d111111111d3 小时前
C语言中static修斯局部变量,全局变量和函数时分别由什么特性
c语言·javascript·笔记·stm32·单片机·嵌入式硬件·学习
GIS好难学3 小时前
0帧起手《Vue零基础教程》,从前端框架到GIS开发系列课程
前端·vue.js·前端框架
李瑞丰_liruifengv3 小时前
使用 Claude Agent SDK 写一个 DeepResearch Agent
javascript·aigc·agent