规格参数配置 实现代码如下
1, src/views/Params/ParamsInfo/Specifications.vue <template> <div class="params"> <!-- 二级菜单 --> <!-- 1, 目录位置 --> <div class="nav"> <el-breadcrumb separator="/"> <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item> <el-breadcrumb-item><a href="/">规格管理</a></el-breadcrumb-item> <el-breadcrumb-item :to="{ path: '/params' }">规格参数</el-breadcrumb-item> <el-breadcrumb-item :to="{ path: '/params/specifications' }">规格包装</el-breadcrumb-item> </el-breadcrumb> </div> <!-- 2, 搜索框 --> <div class="header"> <el-input v-model="inp" /> <el-button type="primary">查看</el-button> <el-button type="primary" @click="showParams">添加</el-button> </div> <!-- 3, 表格区域 展示视图数据 --> <el-table :data="tableData" class="my-table"> <el-table-column prop="itemCatId" label="规格参数ID" width="120"> </el-table-column> <el-table-column prop="id" label="类目ID" width="120"> </el-table-column> <el-table-column prop="specsName" label="规格名称" width="120"> </el-table-column> <el-table-column prop="paramsData" label="规格参数" show-overflow-tooltip> </el-table-column> <!-- <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> <el-table-column prop="email" label="邮件"> </el-table-column> --> <el-table-column label="操作" width="280"> <template slot-scope="scope"> <el-button type="info" size="mini">查看</el-button> <el-button type="primary" size="mini" @click="handleEdit(scope.$index, scope.row)" icon="el-icon-edit">编辑</el-button> <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)" icon="el-icon-delete">删除</el-button> </template> </el-table-column> </el-table> <!-- 4, 分页展示 接收页码- --> <MyPagination :total="total" :pageSize="pageSize" @changePage="changePage" :currentPage="currentPage" /> <!-- 5, 弹框 dialog是页面变量--> <ParamsDialog ref="dialog" /> </div> </template> <script> import MyPagination from '@/components/MyPagination.vue'; import ParamsDialog from '@/views/Params/ParamsInfo/ParamsDialog.vue'; export default { components: { MyPagination, ParamsDialog }, data() { return { inp: '', // 输入框 tableData: [], total: 10, pageSize: 1, currentPage: 1, // tableData: [{ // id: '2016-05-02', // itemCatId: '王小虎', // specsName: '上海市普陀区金沙江路 1518 弄', // paramsData: '2570650096@qq.com' // }, { // id: '2016-05-02', // itemCatId: '王小虎', // specsName: '上海市普陀区金沙江路 1518 弄', // paramsData: '2570650096@qq.com' // }, { // id: '2016-05-02', // itemCatId: '王小虎', // specsName: '上海市普陀区金沙江路 1518 弄', // paramsData: '2570650096@qq.com' // }, { // id: '2016-05-02', // itemCatId: '王小虎', // specsName: '上海市普陀区金沙江路 1518 弄', // paramsData: '2570650096@qq.com' // }], // } }, methods: { // 点击显示弹框--配置规格参数 showParams() { this.$refs.dialog.dialogVisible = true; }, // 点击分页 切换 changePage(num) { this.http(num); }, // 获取规格参数列表 http(page) { this.$api.getParams({ 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> .params { margin: 10px; } .nav { padding: 10px; } .header { display: flex; background: #fff; padding: 10px; border: 1px solid #eee; button { margin-left: 20px; } } .my-table { margin: 10px auto; } </style> 2, src/views/Params/ParamsInfo/ParamsDialog.vue <template> <el-dialog title="添加规格参数" :visible.sync="dialogVisible" width="50%"> <!-- 显示规格类目 --> <TreeGoods @sendTreeData="sendTreeData" /> <!-- 外弹框底部 --> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="innerVisible=true" :disabled="isDisabled">确定并添加分组</el-button> </span> <!-- 二级弹框--嵌套 --> <el-dialog width="45%" title="商品规格参数配置" :visible.sync="innerVisible" append-to-body> <div class="title">当前选中的商品: {{ treeData.name }}</div> <el-button type="primary" @click="addDomain">新增规格列表</el-button> <hr /> <!-- groups = [{title: '',value: '', children:[]},...] --> <!-- 动态增减表单项 start--> <el-form :model="dynamicValidateForm" ref="dynamicValidateForm" label-width="100px" class="demo-dynamic"> <el-form-item v-for="(item, index) in dynamicValidateForm.groups" :label="item.title + index" :key="index" :prop="item.title" :rules="{ required: true, message: '域名不能为空', trigger: 'blur' }"> <div class="item"> <el-input v-model="item.title"></el-input> <el-button type="primary" @click.prevent="addChildDomain(index)">添加子组</el-button> <el-button type="warning" @click.prevent="removeDomain(index)">删除</el-button> </div> <!-- 内层的表单项 --> <el-form-item v-for="(ele, i) in item.children" :label="ele.title + i" :key="i" :prop="ele.title" :rules="{ required: true, message: '域名不能为空', trigger: 'blur' }"> <div class="item"> <el-input v-model="ele.title"></el-input> <el-button type="warning" @click.prevent="removeChildDomain(index,i)">删除</el-button> </div> </el-form-item> </el-form-item> </el-form> <!-- 动态增减表单项 end--> <!-- 内弹框底部 --> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="submitForm('dynamicValidateForm')">确 定</el-button> <el-button @click="resetForm('dynamicValidateForm')">重 置</el-button> </span> </el-dialog> </el-dialog> </template> <script> import TreeGoods from '@/views/Goods/GoodsList/TreeGoods.vue' export default { components: { TreeGoods }, data() { return { dialogVisible: false, innerVisible: false, isDisabled: true, // 默认是不可以点击 treeData: {}, // 接收 tree 数据 dynamicValidateForm: { // 动态表单数据 groups: [], // groups: [{ // value: '', // title: '', // children: [{ // value: '', // title: '', // }] // }, { // value: '', // title: '', // children: [] // }] }, }; }, methods: { // 获取点击 tree 的数据 sendTreeData(val) { console.log('获取 tree 的数据', val); this.treeData = val; this.isDisabled = false; }, // 增加子组 addChildDomain(index) { this.dynamicValidateForm.groups[index].children.push({ value: '', title: '' }) }, // 删除当前组 removeDomain(index) { this.dynamicValidateForm.groups.splice(index, 1) // var index = this.dynamicValidateForm.groups.indexOf(item) // if (index !== -1) { // this.dynamicValidateForm.groups.splice(index, 1) // } }, // 删除子组 removeChildDomain(index, i) { this.dynamicValidateForm.groups[index].children.splice(i, 1); }, // 新增列表---增加大组说明规格配置 addDomain() { this.dynamicValidateForm.groups.push({ value: '', title: '', children: [], }); }, // 提交事件 submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { console.log('提交规格参数', this.dynamicValidateForm.groups); // 参数: itemCatId,content,specsName this.$api.insertItemParams({ itemCatId: this.treeData.cid, specsName: this.treeData.name, content: JSON.stringify(this.dynamicValidateForm.groups), }) .then(res => { console.log('====', res.data); if (res.data.status === 200) { // 添加成功 隐藏弹框 更新规格列表 this.innerVisible = false; this.dialogVisible = false; // 清空数据 this.dynamicValidateForm.groups = []; this.isDisabled = true; this.$parent.http(1); } else { // 最后用弹框 console.log('信息提示失败了--数据库没有去重'); } }) } else { console.log('error submit!!'); return false; } }); }, // 重置 resetForm(formName) { this.$refs[formName].resetFields(); }, }, }; </script> <style lang="less" scoped> .demo-dynamic { margin: 10px; } .item { display: flex; margin-bottom: 10px; button { margin-left: 10px; } } .child_item { display: flex; margin: 10px; } </style> 3, src/views/Goods/GoodsList/TreeGoods.vue <template> <!-- props="props" 渲染的数据 配置选项: label: 'name', // 指定节点标签为节点对象的某个属性值 children: 'zones', // 指定子树为节点对象的某个属性值 isLeaf: 'leaf' // 指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效 :load="loadNode" // 加载子树数据的方法,仅当 lazy 属性为true 时生效 自动执行函数 -- 异步请求数据 lazy // 是否懒加载子节点,需与 load 方法结合使用 show-checkbox> // 节点是否可被选择 选择框 accordion // 是否每次只打开一个同级树节点展开 node-click // 节点被点击时的回调 共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。 --> <el-tree :props="props" :load="loadNode" lazy accordion @node-click="nodeClick"> </el-tree> </template> <script> export default { data() { return { props: { label: 'name', // 指定节点标签为节点对象的某个属性值 children: 'zones', // 指定子树为节点对象的某个属性值 isLeaf: 'leaf' // 指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效 }, }; }, methods: { // 点击 tree 获取数据 nodeClick(data, node) { console.log(data, node); // 传递数据给父组件 this.$emit('sendTreeData', data) }, loadNode(node, resolve) { // resolve() 成功的返回数据结果 // console.log('load--自动执行', node); if (node.level === 0) { // 进入页面 获取第一层的tree数据 // this.$api.getSelectCategory() // .then(res => { // console.log('一级tree', res.data); // return resolve(res.data.result); // }) return resolve([{ name: '家用电器' }, { name: '手机/运营商/数码' }, { name: '电脑/办公' }, { name: '家具/家居' }]); } // 合并 所有级别(level)大于等1 // if (node.level >= 1) { // 合并 // // 请求当前的点击的 tree 下面的数据 // this.$api.getSelectCategory({ // id: node.data.cid // }) // .then(res => { // console.log('二级tree', res.data); // if (res.data.status === 200) { // return resolve(res.data.result); // } else { // return resolve([]) // } // }) // } if (node.level == 1) { // 请求当前的点击的 tree 下面的数据 // this.$api.getSelectCategory({ // 动态从数据库中拿数据 // id: node.data.cid // }) // .then(res => { // console.log('二级tree', res.data); // if (res.data.status === 200) { // return resolve(res.data.result); // } else { // return resolve([]) // } // }) return resolve([{ name: '电视' }, { name: '空调' }, { name: '洗衣机' }, { name: '冰箱' }], [{ name: '手机通讯' }, { name: '运营商' }, { name: '摄影' }, { name: '摄像' }], [{ name: '电脑整机' }, { name: '电脑配件' }, { name: '外设产品' }, { name: '游戏设备' }], [{ name: '厨具' }, { name: '家纺' }, { name: '灯具' }, { name: '家具' }]); } // if (node.level == 2) { // // 请求当前的点击的 tree 下面的数据 // this.$api.getSelectCategory({ // id: node.data.cid; // }) // .then(res => { // console.log('三级tree', res.data); // if (res.data.status === 200) { // return resolve(res.data.result); // } else { // return resolve([]) // } // }) // return resolve([{ // name: '超薄电视' // }, { // name: '全屏电视' // }]); // } } } }; </script> <style> </style> 4, src/router/index.js import Vue from 'vue' import VueRouter from 'vue-router' import Layout from '@/views/Layout/index.vue' import Home from '@/views/Home/index.vue' import Login from '@/views/Login/Login.vue' // 异步 const Goods = () => import('../views/Goods/GoodsList/Goods.vue') const Params = () => import('../views/Params/Params.vue') const Specifications = () => import('../views/Params/ParamsInfo/Specifications.vue') const Advert = () => import('../views/Advert/Advert.vue') const My = () => import('../views/My/My.vue') const Logistics = () => import('../views/Logistics/Logistics.vue') const Order = () => import('../views/Order/index.vue') const OrderList = () => import('../views/Order/OrderList/index.vue') const OrderBack = () => import('../views/Order/OrderBack/index.vue') // 子级路由 const AddGoods = () => import('../views/Goods/GoodsList/AddGoods.vue') Vue.use(VueRouter) const routes = [{ path: '', component: Layout, // 路由的元信息 meta: { isLogin: false }, children: [{ path: '/', name: 'Home', component: Home }, { path: '/goods', name: 'Goods', component: Goods }, { path: '/add-goods', name: 'AddGoods', component: AddGoods }, { path: '/params', name: 'Params', component: Params, redirect: '/params/specifications', children: [{ path: 'specifications', name: 'Specifications', component: Specifications }] }, { path: '/advert', name: 'Advert', component: Advert }, { path: '/my', name: 'My', component: My }, { path: '/logistics', name: 'Logistics', component: Logistics }, { path: '/order', name: 'Order', component: Order, redirect: '/order/order-list', children: [{ path: 'order-list', component: OrderList }, { path: 'order-back', component: OrderBack }] }] }, { path: '/login', name: 'Login', component: Login, } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router 5, 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', // 添加商品 deleteGoods: '/api/api/backend/item/deleteItemById', // 删除商品 updateGoods: '/api/api/backend/item/updateTbItem', // 编辑商品 login: '/api/api/login', // 登录接口 params: '/api/api/backend/itemParam/selectItemParamAll', // 规格参数列表获取 statistical: '/api/api/statistical', // 统计数据 sellTotal: '/api/api/sellTotal', // 统计数据 orderList: '/api/api/order-list', // 订单列表 insertItemParam: '/api/api/backend/itemParam/insertItemParam' // 规格参数的配置--添加 } export default base; 6, src/api/index.js /** * 所有请求的方法 */ import axios from "axios"; import base from "./base"; // node>js const qs = require('querystring'); const api = { /** * 登录接口 */ getLogin(params) { // params={username:'',password:''} // console.log('=====', params, qs.stringify(params)); return axios.post(base.login, qs.stringify(params)) }, /** * 商品列表方法 */ 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 }) }, /** * 删除商品 id */ deleteGoods(params) { return axios.get(base.deleteGoods, { params }) }, /** * 编辑商品 id */ updateGoods(params) { return axios.get(base.updateGoods, { params }) }, /** * 规格参数获取列表 * params: xx */ getParams(params) { return axios.get(base.params, { params }) }, /** * 获取订单数据 * currPage: xx */ orderList(params) { return axios.get(base.orderList, { params }) }, /** * 规格参数 新增 * 参数: itemCatId,content,specsName */ insertItemParams(params) { return axios.get(base.insertItemParam, { params }) } } export default api; 7, server/router.js // 专门放所有的接口 这里只写一部分大约有二十几个接口 // 导入 express const express = require('express') // 使用里面的 Router() 这个方法 const router = express.Router() // token 导入模块 jsonwebtoken 秘钥 const jwt = require('jsonwebtoken') // 秘钥 config.jwtSecert const config = require('./secert.js') // 导入数据库 sqlFn('sql',[],res=>{}) const sqlFn = require('./mysql.js') // 图片上传支持的模块 导入 multer 导入 fs const multer = require('multer') const fs = require('fs') // 导入 mockjs 模块 const Mock = require('mockjs'); // 测试接口 // router.get('/', (req, res) => { // res.send('hello') // }) // 路由接口 // 登录接口 /** * 语法 * 如 60,'2 day','10h','7d',expiration time 过期时间 * jwt.sign({},'秘钥','过期时间',{expiresIn: 20*1,'1 day','1h'}) */ /** * 登录 login * 接收的字段: username password * postman */ router.post('/login', (req, res) => { console.log('获取前端传递的参数', username, password); let { username, password } = req.body // 请求数据库 let sql = "select * from userinfo where username=? and password=?"; let arr = [username, password] console.log(arr); sqlFn(sql, arr, result => { if (result.length > 0) { let token = jwt.sign({ username: result[0].username, id: result[0].id }, config.jwtSecert, { expiresIn: 20 * 1 }) res.send({ status: 200, data: token }) } else { res.send({ status: 404, msg: '信息错误' }) } }) }) // router.post("/login", (req, res) => { // let { // username, // password // } = req.body // // 请求数据库 // let sql = "select * from userinfo where username=? and password=?"; // let arr = [username, password] // sqlFn(sql, arr, result => { // if (result.length > 0) { // let token = jwt.sign({ // username: result[0].username, // id: result[0].id // }, config.jwtSecert, { // expiresIn: 20 * 1 // }) // res.send({ // status: 200, // data: token // }) // } else { // res.send({ // status: 404, // msg: '信息错误' // }) // } // }) // }) /** * 注册接口 /register */ /** * 注册接口 /register */ router.post("/register", (req, res) => { const { username, password } = req.body; const sql = "insert into userinfo values(null,?,?)"; const arr = [username, password]; sqlFn(sql, arr, (result) => { if (result.affectedRows > 0) { res.send({ msg: "注册成功", status: 200 }) } else { res.status(401).json({ errors: "用户名密码错误" }) } }) }) /** * 商品列表:获取分页 {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.descs || ""; 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, descs, 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: '暂无数据' }) } }) }) }) /** * 规格参数 模糊查询 参数; search */ router.get('/params/search', (req, res) => { var search = req.query.search; const sql = "select * from params where concat('paramData') like '%" + search + "%' "; sqlFn(sql, [search], result => { if (result.length > 0) { res.send({ status: 200, result }) } else { res.send({ status: 500, msg: '暂无数据' }) } }) }) /** * 规格参数 添加 * 参数: itemCatId,content,specsName */ router.get('/backend/itemParam/insertItemParam', (req, res) => { var itemCatId = req.query.itemCatId; var paramsContent = req.query.content; var specsName = req.query.specsName; // console.log(itemCatId,paramsContent,specsName); var sql = "insert into params values (null,?,?,?)"; sqlFn(sql, [itemCatId, paramsContent, specsName], result => { if (result.affectedRows > 0) { res.send({ status: 200, msg: '添加成功' }) } else { res.send({ status: 500, msg: '添加失败' }) } }) }) /** * 修改规格参数 cid content id specsnName */ router.get('/update/category', (req, res) => { var cid = req.query.cid; var content = req.query.content; var id = req.query.id; var specsName = req.query.specsName; var sql = "update params set paramData=?,itemCatId=?,specsName=? where id=?"; sqlFn(sql, [content, cid, specsName, id], result => { if (result.affectedRows > 0) { res.send({ status: 200, msg: '修改成功' }) } else { res.send({ status: 500, msg: '修改失败' }) } }) }) /** * 规格参数 删除 */ router.get('/params/delete', (req, res) => { var id = req.query.id; const sql = "delete from params where id=?" const arr = [id]; sqlFn(sql, arr, result => { if (result.affectedRows > 0) { res.send({ status: 200, msg: '删除成功' }) } else { res.send({ status: 500, msg: '删除失败' }) } }) }) /** * 规格参数类目结构数据获取 cid */ 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 }) } else { res.send({ status: 500, msg: '暂无数据' }) } }) }) /** * 内容分类管理 导航 */ router.get('/content/selectContentCategoryByParentId', (req, res) => { const id = req.query.id || 1; const sql = "select * from content where id=?"; sqlFn(sql, [id], result => { if (result.length > 0) { res.send({ status: 200, result }) } else { res.send({ status: 500, msg: '暂无数据' }) } }) }) /** * 统计数据--销售信息 */ router.get('/statistical', (req, res) => { res.send(Mock.mock({ success: true, status: 200, "list|4": [{ 'id|+1': 100, "title|+1": ['总销售额', '访问量', '支付总量', '收藏量'], "current|0-2000": 100, "total|100-999999": 200 }] })) }) /** * 统计 半年 月销量对比数据 * 月度销售额 */ router.get('/sellTotal', (req, res) => { res.send(Mock.mock({ success: true, status: 200, info: { // (property)'id|+1': numer 'id|+1': 100, date: function() { var category = []; var dottedBase = +new Date(); for (var i = 30; i > 0; i--) { var date = new Date((dottedBase -= 1000 * 3600 * 24 * 30)); category.push([date.getFullYear(), date.getMonth() + 1].join()); } return category.slice(0, 6); }, "xResult|3": [{ 'xName|+1': ["家具", "手机", "家电"], "data|6": [{ 'num|100-1000': 10 }] }, ], } })) }) // 测试 mockjs 数据 router.get('/test', (req, res) => { // 使用 mock 生成数据 let data = Mock.mock({ info: '我是一个单纯的对象', status: 200, // 生成list字段:数组类型 内容是6个数据 = {} 就是6个对象 +1 id会累加 "list|6": [{ "id|+1": 100, // id 自增的格式 若 id为100 你的起始值就是100 "flag|1-2": true, // 写成如下对象,表示随机从里面取两个 "province|2": { // 获取两个省份的数据 "310000": "上海市", "320000": "江苏省", "330000": "浙江省", "340000": "安徽省" }, "arr|+1": [ // 依次获取一个数据值,依次获取 数组加1 表示一个一个依次取值 "AMD", "CMD", "UMD", "CLS", "CLEAR", "CLOSE" ], // 随机汉字 "desc": '@cword(20,80)', // 图片 // "imgUrl": '@image()', "imgUrl": '@Image()', // 过滤数据 或者拼接 'foo': 'Syntax Demo', 'name': function() { return this.foo }, // 正则 'regexp': /[a-z][A-Z][0-9]/, // Path 路径 "foo1": "Hello", "nested": { "a": { "b": { "c": "Mock.js" } } }, "absolutePath": "@/foo1 @/nested/a/b/c" // date }], }) res.send(data) }) // ===================== /** * 内容分类管理 内容查询 */ router.get("/content/selectTbContentAllByCategoryId", (req, res) => { const pid = req.query.pid; const sql = "select * from contentinfo where pid=?" sqlFn(sql, [pid], result => { if (result.length > 0) { res.send({ status: 200, result }) } else { res.send({ status: 500, msg: "暂无数据" }) } }) }) module.exports = router
订单接口模拟
/** * 订单列表 */ var MockRandom = Mock.Random; var pageCount = MockRandom.integer(1, 10); // 7 var haseMore = true; // 是否还有更多数据true有数据,false无更多数据 结束分页展示 var ids = 100; // 自增长 id var result = {}; // 数据模板 router.get('/order-list', (req, res) => { var currPage = parseInt(req.query.currPage || 1); // 页码 ids = currPage * 100; if (currPage === pageCount) { // } else { // } // 返回数据 let mockData = Mock.mock(result); if (pageCount >= currPage ) { res.send({ // }) } })
JS里面数据结构操作已经写完,加完以后,点击 '确定' 提交,把这些数据提交到后台接口里面,效验通过,点击 '重置',将他们存入到数据库里面。
![]()
确认事件 方法
:before-close="handleClose" <!-- 内弹框底部 --> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="innerVisible=false">确 定</el-button> </span> handleClose(done) { this.$confirm('确认关闭?') .then(_ => { done(); }) .catch(_ => {}); },
原本事件备份
<el-form-item> <el-button type="primary" @click="submitForm('dynamicValidateForm')">提交</el-button> <el-button @click="addDomain">新增规格列表</el-button> <el-button @click="resetForm('dynamicValidateForm')">重置</el-button> </el-form-item>
![]()
![]()