当前位置: 首页 > news >正文

Vue2 基础八电商后台管理项目——中

代码下载

商品分类页

新商品分类组件 goods/Cate.vue,在router.js中导入子级路由组件 Cate.vue,并设置路由规则。

绘制商品分类基本结构

在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮:

<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>商品分类</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 添加 --><el-button type="primary" @click="showAddCateDialog">添加分类</el-button><!-- 分类列表 --><tree-table class="tree-table" :data="catelist" :columns="columns" :selection-type = "false" :expand-type="false" :show-index="true" :index-text="'#'" border :show-row-hover="false"><template slot="isOk" slot-scope="scope"><i class="el-icon-error" style="color: red;" v-if="scope.row.cat_deleted"></i><i class="el-icon-success" style="color: lightgreen;" v-else></i></template><template slot="order" slot-scope="scope"><el-tag v-if="scope.row.cat_level === 0">一级</el-tag><el-tag type="success" v-else-if="scope.row.cat_level === 1">二级</el-tag><el-tag type="warning" v-else>三级</el-tag></template><template slot="opt" slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini">编辑</el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeCateById(scope.row.cat_id)">删除</el-button></template></tree-table><!-- 分页 --><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="queryInfo.pagenum":page-sizes="[2, 3, 5, 10]":page-size="queryInfo.pagesize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></el-card><!-- 添加分类对话框 --><el-dialog title="添加商品分类" :visible.sync="addCateDialogVisible" width="50%" @close="addCateDialogClosed"><el-form :model="addCateForm" :rules="addCateFormRules" ref="addCateFormRef" label-width="100px"><el-form-item label="分类名称:" prop="cat_name"><el-input v-model="addCateForm.cat_name"></el-input></el-form-item><el-form-item label="父级分类:"><el-cascader v-model="selectedKeys" :options="parentCateList" :props="cascaderProps" @change="parentCateChange" clearable></el-cascader></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="addCateDialogVisible = false">取 消</el-button><el-button type="primary" @click="addCate">确 定</el-button></span></el-dialog></div>
</template>

主要功能实现

<script>
export default {data() {return {catelist: [], queryInfo: {type: 3,pagenum: 1,pagesize: 5},total: 0,columns: [{label: '分类名称',prop: 'cat_name'},{label: '是否有效',// 列类型,可选值有 'template'(自定义列模板)type: 'template',// 列类型为 'template'(自定义列模板) 时,对应的作用域插槽(它可以获取到 row, rowIndex, column, columnIndex)名称template: 'isOk'},{label: '排序',type: 'template',template: 'order'},{label: '操作',type: 'template',template: 'opt'}],addCateDialogVisible: false,addCateForm: {cat_pid: 0,cat_name: '',cat_level: 0},// 添加商品分类表单验证addCateFormRules: {cat_name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }]},parentCateList: [],cascaderProps: {expandTrigger: 'hover',checkStrictly: true,value: 'cat_id',label: 'cat_name',children: 'children'},selectedKeys: []}},created() {this.getCateList()},methods: {async getCateList() {const { data: res } = await this.$http.get('categories', { params: this.queryInfo })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.catelist = res.data.resultthis.total = res.data.totalthis.$msg.success('商品分类获取成功')},handleSizeChange(size) {console.log('size: ', size);this.queryInfo.pagesize = sizeconst maxN = parseInt(this.total / this.queryInfo.pagesize + '') + (this.total % this.queryInfo.pagesize > 0 ? 1 : 0)this.queryInfo.pagenum = this.queryInfo.pagenum > maxN ? maxN : this.queryInfo.pagenumthis.getCateList()},handleCurrentChange(page) {console.log('page: ', page);this.queryInfo.pagenum = pagethis.getCateList()},// 展示添加商品分类对话框async showAddCateDialog() {// 获取父级分类const { data: res } = await this.$http.get('categories', { params: { type: 2 } })if (res.meta.status !== 200) return this.$msg.error(res.meta.error)this.parentCateList = res.datathis.addCateDialogVisible = true},// 关闭添加商品分类对话框addCateDialogClosed() {this.$refs.addCateFormRef.resetFields()this.addCateForm.cat_pid = 0this.addCateForm.cat_level = 0this.addCateForm.cat_name = ''this.selectedKeys = []},// 添加商品分类async addCate() {// 验证表单this.$refs.addFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写正确的分类名称')const { data: res } = await this.$http.post('categories', this.addCateForm)if (res.meta.status !== 201) return this.$msg.error(res.meta.msg)this.$msg.success('添加商品分类成功')this.getCateList()// 关闭对话框,重置数据this.addCateDialogVisible = false})},parentCateChange(v) {console.log('change: ', v);// 处理父分类id和分类级别if (this.selectedKeys.length > 0) {this.addCateForm.cat_pid = this.selectedKeys[this.selectedKeys.length - 1]this.addCateForm.cat_level = this.selectedKeys.length} else {this.addCateForm.cat_pid = 0this.addCateForm.cat_level = 0}},async removeCateById(uid) {const confirm = await this.$confirm('此操作将永久删除该分类, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).catch(e => e);// 如果用户确认删除,则返回值为字符串 confirm;如果用户取消了删除,则返回值为字符串 cancelconsole.log('confirm: ', confirm);if (confirm !== 'confirm') returnconst { data: res } = await this.$http.delete('categories/' + uid)if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('删除商品分类成功')if (this.queryInfo.pagenum > 1 && this.catelist.length === 1) this.queryInfo.pagenum -= 1this.getCateList()}}
}
</script>

1、请求分类数据,请求分类数据并将数据保存在data中

2、使用插件展示数据,使用第三方插件 vue-table-with-tree-grid 展示分类数据:

  • 在vue 控制台中点击依赖->安装依赖->运行依赖->输入vue-table-with-tree-gird->点击安装
  • 打开main.js,导入vue-table-with-tree-grid import TreeTable from 'vue-table-with-tree-grid',并全局注册组件 Vue.component('tree-table', TreeTable)

3、自定义数据列,使用vue-table-with-tree-grid定义模板列并添加自定义列

4、完成分页功能

5、完成添加分类,添加级联菜单显示父级分类。先导入Cascader组件,并注册;然后添加使用级联菜单组件

参数管理页

只允许给三级分类内容设置参数,参数分为动态参数和静态参数属性。

添加 goods/Params.vue 子组件,并在router.js中引入该组件并设置路由规则。

绘制参数管理基本结构

完成Params.vue组件的基本布局,其中警告提示信息使用了el-alert,在element.js引入该组件并注册:

<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>参数列表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><el-alert title="注意:只允许为第三级分类设置相关参数!" type="warning" show-icon :closable="false"></el-alert><!-- 商品分类 --><div class="cat_opt"><span>请选择商品分类:</span><el-cascader v-model="selectedCateKeys" :options="cateList" :props="cateProps"  @change="handleChange" clearable></el-cascader></div><el-tabs v-model="activeName" @tab-click="handleTabClick"><el-tab-pane label="动态参数" name="many"><el-button type="primary" size="mini" :disabled="selectedCateKeys.length!==3" @click="addDialogVisible = true">添加参数</el-button><!-- 动态参数列表 --><el-table :data="manyTableData" style="width: 100%" border stripe><el-table-column type="expand"><template slot-scope="scope"><el-tag v-for="(v, i) in scope.row.attr_vals" :key="i" closable @close="handleClose(scope.row, i)">{{v}}</el-tag><el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"></el-input><el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button></template></el-table-column><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="attr_name" label="属性名称"></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.attr_id)">编辑</el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParams(scope.row.attr_id)">删除</el-button></template></el-table-column></el-table></el-tab-pane><el-tab-pane label="静态属性" name="only"><el-button type="primary" size="mini" :disabled="selectedCateKeys.length!==3" @click="addDialogVisible = true">添加属性</el-button><!-- 静态属性列表 --><el-table :data="onlyTableData" style="width: 100%" border stripe><el-table-column type="expand"><template slot-scope="scope"><el-tag v-for="(v, i) in scope.row.attr_vals" :key="i" closable @close="handleClose(scope.row, i)">{{v}}</el-tag><el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"></el-input><el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button></template></el-table-column><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="attr_name" label="属性名称"></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.attr_id)">编辑</el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParams(scope.row.attr_id)">删除</el-button></template></el-table-column></el-table></el-tab-pane></el-tabs></el-card><!-- 添加参数对话框 --><el-dialog :title="'添加' + titleText" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed"><el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px"><el-form-item :label="titleText" prop="attr_name"><el-input v-model="addForm.attr_name"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="addDialogVisible = false">取 消</el-button><el-button type="primary" @click="addParams">确 定</el-button></span></el-dialog><!-- 编辑参数对话框 --><el-dialog :title="'编辑' + titleText" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed"><el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="100px"><el-form-item :label="titleText" prop="attr_name"><el-input v-model="editForm.attr_name"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="editDialogVisible = false">取 消</el-button><el-button type="primary" @click="editParams">确 定</el-button></span></el-dialog></div>
</template>

主要功能实现

<script>
export default {data() {return {cateList: [],selectedCateKeys: [],cateProps: {expandTrigger: 'hover',value: 'cat_id',label: 'cat_name',children: 'children'},// 被激活的标签页名activeName: 'many',// 动态参数数据manyTableData: [],// 静态属性数据onlyTableData: [],// 是否展示添加参数对话框addDialogVisible: false,// 添加参数对话框数据addForm: {attr_name: ''},// 添加参数对话框验证规则addFormRules: {attr_name: [{ required: true, message: '请输入参数名称', trigger: 'blur' }]},// 是否展示编辑参数对话框editDialogVisible: false,// 编辑参数对话框数据editForm: {attr_name: ''},// 编辑参数对话框验证规则editFormRules: {attr_name: [{ required: true, message: '请输入参数名称', trigger: 'blur' }]}}},created() {this.getCateList()},methods: {// 获取分类数据async getCateList() {const { data: res } = await this.$http.get('categories', { params: { type: 3 } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取商品分类成功')this.cateList = res.data},// 获取参数列表数据async getParamsData() {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes`, { params: { sel: this.activeName } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取参数列表成功')// 将 attr_vals 转换为数组res.data.forEach(item => {item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []item.inputVisible = falseitem.inputValue = ''});if (this.activeName === 'many') this.manyTableData = res.datathis.onlyTableData = res.data},// 分类改变handleChange() {if (this.selectedCateKeys.length !== 3) {this.selectedCateKeys = []this.manyTableData = []this.onlyTableData = []return}console.log('change: ', this.selectedCateKeys);this.getParamsData()},// 点击标签页handleTabClick() {if (this.selectedCateKeys.length === 3) this.getParamsData()},// 关闭添加参数对话框addDialogClosed() {this.$refs.addFormRef.resetFields()},// 添加商品参数addParams() {// 验证表单this.$refs.addFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写正确的参数名称')const { data: res } = await this.$http.post(`categories/${this.cateId}/attributes`, { attr_name: this.addForm.attr_name,attr_sel: this.activeName})if (res.meta.status !== 201) return this.$msg.error(res.meta.msg)this.$msg.success(`添加${this.titleText}成功`)this.addDialogVisible = falsethis.getParamsData()})},// 展示编辑参数对话框async showEditDialog(attrId) {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes/${attrId}`, { params: { attr_sel: this.activeName } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`获取${this.titleText}成功`)this.editForm = res.datathis.editDialogVisible = true},// 关闭编辑参数对话框editDialogClosed() {this.$refs.editFormRef.resetFields()},// 编辑商品参数editParams() {// 验证表单this.$refs.editFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写正确的参数名称')const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${this.editForm.attr_id}`, { attr_name: this.editForm.attr_name,attr_sel: this.activeName})if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`添加${this.titleText}成功`)this.editDialogVisible = falsethis.getParamsData()})},// 删除商品参数async removeParams(attrId) {const confirm = await this.$confirm(`此操作将永久删除该${this.titleText}, 是否继续?`, '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).catch(e => e);// 如果用户确认删除,则返回值为字符串 confirm;如果用户取消了删除,则返回值为字符串 cancelconsole.log('confirm: ', confirm);if (confirm !== 'confirm') returnconst { data: res } = await this.$http.delete(`categories/${this.cateId}/attributes/${attrId}`)if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`删除${this.titleText}成功`)this.getParamsData()},// 保存参数可选项async saveAttrVals(row, attrVals, isAdd) {const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${row.attr_id}`, { attr_name: row.attr_name,attr_sel: this.activeName,attr_vals: attrVals})if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`${isAdd ? '添加' : '删除'}${this.titleText}可选项成功`)this.getParamsData()},// 删除参数可选项handleClose(row, i) {// 删除元素const attrVals = [...row.attr_vals.slice(0, i), ...row.attr_vals.slice(i + 1)].join(' ')console.log('attrVals: ', attrVals, '\ni: ', i);this.saveAttrVals(row, attrVals, false)},// 展示添加参数可选项输入框showInput(row) {row.inputVisible = true// 让文本框自动获得焦点// $nextTick 方法的作用,就是当页面上元素被重新渲染之后,才会指定回调函数中的代码this.$nextTick(_ => {this.$refs.saveTagInput.$refs.input.focus();});},// handleInputConfirm(row) {if (row.inputValue.trim().length === 0) {row.inputVisible = falserow.inputValue = ''return}// 添加元素const attrVals = row.attr_vals.concat(row.inputValue.trim()).join(' ')console.log('attrVals: ', attrVals);this.saveAttrVals(row, attrVals, true)}},// 计算属性computed: {// 选中的分类idcateId() {if (this.selectedCateKeys.length === 3) return this.selectedCateKeys[2]return null},// 动态计算标题的文本titleText() {if (this.activeName === 'many') {return '动态参数'}return '静态属性'}}
}
</script>

1、完成级联选择框,完成商品分类级联选择框

2、展示参数,展示动态参数数据以及静态属性数据

3、添加参数,完成添加参数或属性

4、编辑参数,完成编辑参数或属性

5、删除参数,删除参数或属性

6、动态参数和静态属性管理:

  • 展示动态参数可选项,动态参数可选项展示及操作在获取动态参数的方法中进行处理。
  • 添加/删除动态参数可选项
  • 展示静态属性可选项,静态属性可选项展示及操作在获取动态参数的方法中进行处理。
  • 添加/删除静态属性可选项

注意:当用户在级联选择框中选中了非三级分类时,需要清空表格中数据

商品列表页

添加 goods/List.vue 子组件,并在router.js中引入该组件并设置路由规则

绘制商品列表页基本结构

略,详情参考如下代码:

<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>商品列表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 搜索与添加 --><el-row :gutter="20"><el-col :span="8"><el-input placeholder="请输入内容" v-model.trim="queryInfo.query" clearable @clear="getGoodsList"><el-button slot="append" icon="el-icon-search" @click="queryGoodsList" :disabled="queryInfo.query ? false : true"></el-button></el-input></el-col><el-col :span="4"><el-button type="primary" @click="goAddPage">添加商品</el-button></el-col></el-row><!-- 用户列表 --><el-table :data="goodsList" style="width: 100%" border stripe><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="goods_name" label="商品名称"></el-table-column><el-table-column prop="goods_price" label="商品价格(元)" width="95"></el-table-column><el-table-column prop="goods_weight" label="商品重量" width="70"></el-table-column><el-table-column prop="add_time" label="创建时间" width="140"><template slot-scope="scope">{{scope.row.add_time | dateFormatter}}</template></el-table-column><el-table-column label="操作" width="130"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini"></el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeById(scope.row.goods_id)"></el-button></template></el-table-column></el-table><!-- 分页 --><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="queryInfo.pagenum":page-sizes="[2, 3, 5, 10]" :page-size="queryInfo.pagesize"layout="total, sizes, prev, pager, next, jumper":total="total" background></el-pagination><pre>{{goodsList}}</pre></el-card></div>
</template>

主要功能实现

<script>
export default {data() {return {// 获取商品列表接口参数queryInfo: {query: '', // 搜索内容pagenum: 1, // 页面pagesize: 10 // 每页显示条数},// 商品列表数据goodsList: [],// 商品列表总条数total: 0}},created() {this.getGoodsList()},methods: {// 获取商品列表数据async getGoodsList() {const { data: res } = await this.$http.get('goods', { params: this.queryInfo })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.goodsList = res.data.goodsthis.total = res.data.totalthis.$msg.success('获取商品列表成功')},// 查询商品queryGoodsList() {this.queryInfo.pagenum = 1this.getGoodsList()},// pagesize 改变handleSizeChange(size) {console.log('size: ', size);this.queryInfo.pagesize = sizeconst maxN = parseInt(this.total / this.queryInfo.pagesize + '') + (this.total % this.queryInfo.pagesize > 0 ? 1 : 0)this.queryInfo.pagenum = this.queryInfo.pagenum > maxN ? maxN : this.queryInfo.pagenumthis.getGoodsList()},// 页码值 改变handleCurrentChange(num) {console.log('num: ', num);this.queryInfo.pagenum = numthis.getGoodsList()},// 删除商品async removeById(gid) {const confirm = await this.$confirm('此操作将永久删除该商品, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).catch(e => e);// 如果用户确认删除,则返回值为字符串 confirm;如果用户取消了删除,则返回值为字符串 cancelconsole.log('confirm: ', confirm);if (confirm !== 'confirm') returnconst { data: res } = this.$http.delete('goods/' + gid)if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('删除商品成功')this.getGoodsList()},// 添加商品goAddPage() {console.log('goAddPage');this.$router.push('/home/addGoods')}}
}
</script>

1、数据展示,添加数据表格展示数据以及分页功能的实现,搜索功能的实现。在main.js中添加过滤器:

Vue.filter('dateFormatter', (ov) => {const date = new Date(ov)const y = date.getFullYear()const m = (date.getMonth() + 1 + '').padStart(2, '0')const d = (date.getDate() + '').padStart(2, '0')const hh = (date.getHours() + '').padStart(2, '0')const mm = (date.getHours() + '').padStart(2, '0')const ss = (date.getHours() + '').padStart(2, '0')return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
})

2、实现删除商品

3、添加商品,添加编程式导航,在List.vue中添加编程式导航,并创建添加商品路由组件及规则

添加商品页

添加 goods/Add.vue 子组件,并在router.js中引入该组件并设置路由规则。

绘制添加商品页基本结构

  • 布局过程中需要使用Steps组件,在element.js中引入并注册该组件,并在global.css中给组件设置全局样式
  • 其他略……
<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>添加商品</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 警告 --><el-alerttitle="添加商品信息"type="info"centershow-icon :closable="false"></el-alert><!-- 步骤条 --><el-steps :space="200" :active="activeIndex * 1" align-center finish-status="success"><el-step title="基本信息"></el-step><el-step title="商品参数"></el-step><el-step title="商品属性"></el-step><el-step title="商品图片"></el-step><el-step title="商品内容"></el-step><el-step title="完成"></el-step></el-steps><!-- 标签栏 --><el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px" label-position="top"><el-tabs v-model="activeIndex" tab-position="left" :before-leave="beforeTabLeave" @tab-click="tabClicked"><el-tab-pane label="基本信息" name="0"><el-form-item label="商品名称" prop="goods_name"><el-input v-model="addForm.goods_name"></el-input></el-form-item><el-form-item label="商品价格" prop="goods_price"><el-input v-model="addForm.goods_price" type="number"></el-input></el-form-item><el-form-item label="商品重量" prop="goods_weight"><el-input v-model="addForm.goods_weight" type="number"></el-input></el-form-item><el-form-item label="商品数量" prop="goods_number"><el-input v-model="addForm.goods_number" type="number"></el-input></el-form-item><el-form-item label="商品分类" prop="goods_cat"><el-cascader v-model="addForm.goods_cat" :options="cateList" :props="cateProps"  @change="handleChange" clearable></el-cascader></el-form-item></el-tab-pane><el-tab-pane label="商品参数" name="1"><el-form-item v-for="(v, i) in manyTableData" :key="i" :label="v.attr_name"><el-checkbox-group v-model="v.attr_vals"><el-checkbox v-for="(item, index) in v.attr_vals" :key="index" :label="item" border></el-checkbox></el-checkbox-group></el-form-item><pre>{{manyTableData}}</pre></el-tab-pane><el-tab-pane label="商品属性" name="2"><el-form-item v-for="(v, i) in onlyTableData" :key="i" :label="v.attr_name"><el-input v-model="v.attr_vals"></el-input></el-form-item><pre>{{onlyTableData}}</pre></el-tab-pane><el-tab-pane label="商品图片" name="3"><el-upload action="http://127.0.0.1:8888/api/private/v1/upload":on-preview="handlePreview":on-remove="handleRemove" :headers="headerObj" :on-success="handleSuccess"list-type="picture"><el-button size="small" type="primary">点击上传</el-button></el-upload></el-tab-pane><el-tab-pane label="商品内容" name="4"><quill-editor v-model="addForm.goods_introduce" @blur="onEditorBlur"></quill-editor><el-button class="btnAdd" type="primary" @click="add">添加商品</el-button></el-tab-pane></el-tabs></el-form><!-- 预览对话框 --><el-dialogtitle="图片预览":visible.sync="previewVisible"width="50%"><img class="previewImg" :src="previewPath" alt=""></el-dialog></el-card></div>
</template>

主要功能实现

<script>
import _ from 'lodash';export default {data() {return {activeIndex: '0',addForm: {goods_name: '',goods_price: '',goods_weight: '',goods_number: '',goods_cat: [],// 商品图片pics: [],// 描述goods_introduce: '',// 参数attrs: []},addFormRules: {goods_name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }], goods_price: [{ required: true, message: '请输入商品价格', trigger: 'blur' }], goods_weight: [{ required: true, message: '请输入商品重量', trigger: 'blur' }], goods_number: [{ required: true, message: '请输入商品数量', trigger: 'blur' }],goods_cat: [{ required: true, message: '请选择商品分类', trigger: 'change' }]},// 商品分类cateList: [],cateProps: {expandTrigger: 'hover',value: 'cat_id',label: 'cat_name',children: 'children'},// 动态参数列表manyTableData: [],// 静态属性列表onlyTableData: [],// 请求头headerObj: { Authorization: window.sessionStorage.getItem('token') },// 是否展示预览图previewVisible: false,// 预览图片路径previewPath: ''}},created() {this.getCateList()},methods: {// 获取分类数据async getCateList() {const { data: res } = await this.$http.get('categories', { params: { type: 3 } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取商品分类成功')this.cateList = res.data},// 选择分类handleChange(v) {if (this.addForm.goods_cat.length !== 3) {this.addForm.goods_cat = []return}console.log('handleChange value: ', v);},// 标签页钩子函数beforeTabLeave(ai, oai) {console.log('ai: ', ai, ', oai: ', oai);if (oai === '0' && this.addForm.goods_cat.length !== 3) {this.$msg.error('请选择商品分类')return false}},// 点击标签栏async tabClicked() {if (this.activeIndex === '1') {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes`, { params: { sel: 'many' } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取动态参数成功')res.data.forEach(item => {item.attr_vals = item.attr_vals.length > 0 ? item.attr_vals.split(' ') : []});this.manyTableData = res.data} else if (this.activeIndex === '2') {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes`, { params: { sel: 'only' } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取动态参数成功')this.onlyTableData = res.data}},// 点击预览图片handlePreview(file) {console.log('handlePreview: ', file);this.previewPath = file.response.data.urlthis.previewVisible = true},// 点击删除图片handleRemove(file, fileList) {// console.log('handleRemove:\nfile: ', file, '\nfileList: ', fileList);const index = this.addForm.pics.findIndex(v => v.pic === file.response.data.tmp_path)if (index !== -1) this.addForm.pics.splice(index, 1)console.log('addForm: ', this.addForm);},// 上传文件成功handleSuccess(response, file, fileList) {// console.log('handleSuccess:\nresponse: ', response, '\nfile: ', file, '\nfileList: ', fileList);this.addForm.pics.push({ pic: response.data.tmp_path })console.log('addForm: ', this.addForm);},// 富文本编辑器失去焦点onEditorBlur() {console.log('content: ', this.addForm.goods_introduce);},// 添加商品add() {this.$refs.addFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写必要的表单项')// lodash 深拷贝const addForm = _.cloneDeep(this.addForm)// 处理分类数据addForm.goods_cat = addForm.goods_cat.join(',')// 处理动态参数this.manyTableData.forEach(item => {const newInfo = {attr_id: item.attr_id,attr_value: item.attr_vals.join(' ')}addForm.attrs.push(newInfo)});// 处理静态属性this.onlyTableData.forEach(item => {const newInfo = {attr_id: item.attr_id,attr_value: item.attr_vals}addForm.attrs.push(newInfo)});console.log('addForm: ', addForm);// 发起请求const { data: res } = await this.$http.post('goods', addForm)if (res.meta.status !== 201) this.$msg.error(res.meta.msg)this.$msg.success('添加商品成功')this.$router.push('/home/goods')})}},computed: {cateId() {if (this.addForm.goods_cat.length === 3) return this.addForm.goods_cat[2]return null}}
}
</script>

1、添加tab栏切换验证,也就是说不输入某些内容,无法切换到别的tab栏

2、展示信息,展示商品参数信息、商品属性信息,在商品参数信息展示中使用的el-checkbox,el-checkbox-group组件,打开element.js引入组件并注册组件

3、完成图片上传,使用upload组件完成图片上传,在element.js中引入upload组件,并注册。因为upload组件进行图片上传的时候并不是使用axios发送请求,所以需要手动为上传图片的请求添加token,即为upload组件添加headers属性

4、使用富文本插件,想要使用富文本插件vue-quill-editor,就必须先从依赖安装该插件,引入并注册vue-quill-editor

5、添加商品,完成添加商品的操作,在添加商品之前,为了避免goods_cat数组转换字符串之后导致级联选择器报错需要打开vue控制条,点击依赖,安装lodash,把addForm进行深拷贝

订单列表页

创建订单列表路由组件并添加路由规则。

绘制订单列表页基本结构

略,详情参考如下代码:

<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>订单管理</el-breadcrumb-item><el-breadcrumb-item>订单列表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 搜索与添加 --><el-row :gutter="20"><el-col :span="8"><el-input placeholder="请输入内容" v-model.trim="queryInfo.query" clearable @clear="getOrderList"><el-button slot="append" icon="el-icon-search" @click="queryOrderList" :disabled="queryInfo.query ? false : true"></el-button></el-input></el-col></el-row><!-- 用户列表 --><el-table :data="orderList" style="width: 100%" border stripe><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="order_number" label="订单编号"></el-table-column><el-table-column prop="order_price" label="订单价格"></el-table-column><el-table-column prop="order_pay" label="是否付款"><template slot-scope="scope"><el-tag type="danger" v-if="scope.row.pay_status === '0'">未付款</el-tag><el-tag type="success" v-else>已付款</el-tag></template></el-table-column><el-table-column prop="is_send" label="是否发货"></el-table-column><el-table-column prop="create_time" label="下单时间"><template slot-scope="scope">{{scope.row.create_time | dateFormatter}}</template></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini" @click="addressVisible = true"></el-button><el-button type="success" icon="el-icon-location" size="mini" @click="showProgressBox(scope.row.order_number)"></el-button></template></el-table-column></el-table><!-- 分页 --><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="queryInfo.pagenum":page-sizes="[2, 3, 5, 10]" :page-size="queryInfo.pagesize"layout="total, sizes, prev, pager, next, jumper":total="total" background></el-pagination><pre>{{orderList}}</pre></el-card><!-- 修改地址对话框 --><el-dialog title="添加商品分类" :visible.sync="addressVisible" width="50%" @close="addressDialogClosed"><el-form :model="addressForm" :rules="addressFormRules" ref="addressFormRef" label-width="120px"><el-form-item label="省市区/县:" prop="address1"><el-cascader v-model="addressForm.address1" :options="cityData" clearable></el-cascader></el-form-item><el-form-item label="详细地址:" prop="address2"><el-input v-model="addressForm.address2"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="addressVisible = false">取 消</el-button><el-button type="primary" @click="addressConfirm">确 定</el-button></span></el-dialog><!-- 物流进度对话框 --><el-dialog title="物流进度" :visible.sync="progressVisible" width="50%"><el-timeline><el-timeline-itemv-for="(activity, index) in progressInfo":key="index":color="index === 0 ? '#00ff00' : ''":timestamp="activity.time">{{activity.context}}</el-timeline-item></el-timeline></el-dialog></div>
</template>

主要功能实现

<script>
import cityData from './citydata.js'export default {data() {return {queryInfo: {query: '',pagenum: 1,pagesize: 10},total: 0,// 订单列表orderList: [],// 省市区/县数据cityData,// 级联选择器属性cascaderProps: {expandTrigger: 'hover'},// 修改地址对话框addressVisible: false,addressForm: {address1: [],address2: ''},addressFormRules: {address1: [{ required: true, message: '请选择省市区县', trigger: 'change' }],address2: [{ required: true, message: '请填写详细地址', trigger: 'blur' }]},// 物流进度对话框progressVisible: false,// 物流进度数据progressInfo: []}},created() {this.getOrderList()},methods: {// 获取订单列表async getOrderList() {const { data: res } = await this.$http.get('orders', { params: this.queryInfo })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取订单列表成功')this.orderList = res.data.goodsthis.total = res.data.total},// 查询订单列表queryOrderList() {this.queryInfo.pagenum = 1this.getOrderList()},// pagesize 改变handleSizeChange(size) {console.log('size: ', size);this.queryInfo.pagesize = sizeconst maxN = parseInt(this.total / this.queryInfo.pagesize + '') + (this.total % this.queryInfo.pagesize > 0 ? 1 : 0)this.queryInfo.pagenum = this.queryInfo.pagenum > maxN ? maxN : this.queryInfo.pagenumthis.getOrderList()},// 页码值 改变handleCurrentChange(num) {console.log('num: ', num);this.queryInfo.pagenum = numthis.getOrderList()},// 关闭修改地址对话框addressDialogClosed() {// console.log('addressForm: ', this.addressForm);this.$refs.addressFormRef.resetFields()},// 修改地址addressConfirm() {// console.log('addressForm: ', this.addressForm);this.addressVisible = false},// 展示物流进度对话框async showProgressBox(orderNumber) {// const { data: res } = await this.$http.get('kuaidi/' + orderNumber)// if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)// this.$msg.success('获取物流进度成功')// this.progressInfo = res.dataconst data = `[{"time": "2018-05-10 09:39:00","ftime": "2018-05-10 09:39:00","context": "已签收,感谢使用顺丰,期待再次为您服务","location": ""},{"time": "2018-05-10 08:23:00","ftime": "2018-05-10 08:23:00","context": "[北京市]北京海淀育新小区营业点派件员 顺丰速运 95338正在为您派件","location": ""},{"time": "2018-05-10 07:32:00","ftime": "2018-05-10 07:32:00","context": "快件到达 [北京海淀育新小区营业点]","location": ""},{"time": "2018-05-10 02:03:00","ftime": "2018-05-10 02:03:00","context": "快件在[北京顺义集散中心]已装车,准备发往 [北京海淀育新小区营业点]","location": ""},{"time": "2018-05-09 23:05:00","ftime": "2018-05-09 23:05:00","context": "快件到达 [北京顺义集散中心]","location": ""},{"time": "2018-05-09 21:21:00","ftime": "2018-05-09 21:21:00","context": "快件在[北京宝胜营业点]已装车,准备发往 [北京顺义集散中心]","location": ""},{"time": "2018-05-09 13:07:00","ftime": "2018-05-09 13:07:00","context": "顺丰速运 已收取快件","location": ""},{"time": "2018-05-09 12:25:03","ftime": "2018-05-09 12:25:03","context": "卖家发货","location": ""},{"time": "2018-05-09 12:22:24","ftime": "2018-05-09 12:22:24","context": "您的订单将由HLA(北京海淀区清河中街店)门店安排发货。","location": ""},{"time": "2018-05-08 21:36:04","ftime": "2018-05-08 21:36:04","context": "商品已经下单","location": ""}]`this.progressInfo = JSON.parse(data)this.progressVisible = true}}
}
</script>

1、实现数据展示及分页

2、制作省市区/县联动,制作 citydata.js 数据文件放到到components/order文件夹中,然后导入citydata.js文件

3、制作物流进度对话框,因为使用的是element-ui中提供的Timeline组件,所以需要导入并注册组件

数据统计页

创建数据统计路由组件并添加路由规则。

导入ECharts并使用,具体实现如下:

<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>数据统计</el-breadcrumb-item><el-breadcrumb-item>数据报表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><div id="main" style="width: 750px; height:400px;"></div></el-card></div>
</template><script>
// 只会导出(export default mutations)这个默认的对象返回
// import echarts from 'echarts'// 将 若干export导出的内容组合成一个对象返回
import * as echarts from 'echarts'import _ from 'lodash'export default {data() {return {options: {title: {text: '用户来源'},tooltip: {trigger: 'axis',axisPointer: {type: 'cross',label: {backgroundColor: '#E9EEF3'}}},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},xAxis: [{boundaryGap: false}],yAxis: [{type: 'value'}]}}},async mounted() {const { data: res } = await this.$http.get('reports/type/1')if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取折线图数据成功')// 初始化var myChart = echarts.init(document.getElementById('main'))// 设置配置项myChart.setOption(_.merge(this.options, res.data))}
}
</script>

相关文章:

Vue2 基础八电商后台管理项目——中

代码下载 商品分类页 新商品分类组件 goods/Cate.vue&#xff0c;在router.js中导入子级路由组件 Cate.vue&#xff0c;并设置路由规则。 绘制商品分类基本结构 在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮&#xff1a; <template><div><…...

Typescript window.localStorage 存储 Obj Value区别

window.localStorage.setItem(UserC, JSON.stringify(userC)) const userC JSON.parse(window.localStorage.getItem(UserC) || {}) 不能获得UserC&#xff0c;所有保存的时候需要存储value&#xff0c;而不是对象。 {"__v_isShallow":false, "__v_isRef&quo…...

Linux要解压 .rar 文件,你应该使用 unrar 命令

命令 sudo tar -zxf ~/WebDemo.rar -C /usr/local 有一些问题。tar 命令通常用于解压 .tar、.tar.gz 或 .tar.bz2 文件&#xff0c;而不是 .rar 文件。要解压 .rar 文件&#xff0c;你应该使用 unrar 命令。下面是正确的步骤&#xff1a; 首先&#xff0c;安装 unrar&#xff0…...

【qt】如何获取网卡的信息?

网卡不只一种,有有线的,有无线的等等 我们用QNetworkInterface类的静态函数allInterfaces() 来获取所有的网卡 返回的是一个网卡的容器. 然后我们对每个网卡来获取其设备名称和硬件地址 可以通过静态函数humanReadableName() 来获取设备名称 可以通过静态函数**hardwareAddre…...

使用Netty框架实现WebSocket服务端与客户端通信(附ssl)

仓库地址&#xff1a; https://gitee.com/lfw1024/netty-websocket 导入后可直接运行 预览页面 自签证书&#xff1a; #换成自己的本地ip keytool -genkey -alias server -keyalg RSA -validity 3650 -keystore D:\mystore.jks -ext sanip:192.168.3.7,ip:127.0.0.1,dns:lo…...

ssm校园志愿服务信息系统-计算机毕业设计源码97697

摘 要 随着社会的进步和信息技术的发展&#xff0c;越来越多的学校开始重视志愿服务工作&#xff0c;通过组织各种志愿服务活动&#xff0c;让学生更好地了解社会、服务社会。然而&#xff0c;在实际操作中&#xff0c;志愿服务的组织和管理面临着诸多问题&#xff0c;如志愿者…...

JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程

1. 对象的创建 遇到new指令时 当Java虚拟机遇到一个字节码new指令时。 首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否被加载、解析和初始化过。 如果没有&#xff0c;那么必须执行类的加载过程(加载、检查…...

(七)glDrawArry绘制

几何数据&#xff1a;vao和vbo 材质程序&#xff1a;vs和fs(顶点着色器和片元着色器) 接下来只需要告诉GPU&#xff0c;使用几何数据和材质程序来进行绘制。 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…...

记一次小程序渗透

这次的小程序渗透刚好每一个漏洞都相当经典所以记录一下。 目录 前言 漏洞详情 未授权访问漏洞/ 敏感信息泄露&#xff08;高危&#xff09; 水平越权&#xff08;高危&#xff09; 会话重用&#xff08;高危&#xff09; 硬编码加密密钥泄露&#xff08;中危&#xff0…...

C++ 的常见算法 之一

C 的常见算法 之一 不修改序列算法for_eachcountfind 修改序列算法copymove 不修改序列算法 for_each #include <iostream> // std::cout #include <algorithm> // std::for_each #include <vector> // std::vectorusing namespace std;struc…...

微前端的需求有哪些?微前端的原理是怎么样的?为什么这么设计,及微前端的应用场景是什么?对有些客户,前端的重要性高于后端

微前端&#xff08;Micro Frontends&#xff09;是将前端应用拆分成多个独立、可部署的部分&#xff0c;每个部分可以由不同的团队独立开发、测试、部署和维护。这种架构类似于微服务在后端的应用&#xff0c;是为了应对复杂前端应用的维护和扩展问题而提出的。 来龙去脉 背景…...

【Spring Boot】统一数据返回

目录 统一数据返回一. 概念二.实现统一数据返回2.1 重写responseAdvice方法2.2 重写beforeBodyWriter方法 三. 特殊类型-String的处理四. 全部代码 统一数据返回 一. 概念 其实统一数据返回是运用了AOP&#xff08;对某一类事情的集中处理&#xff09;的思维&#xff0c;简单…...

证券交易系统中服务器监控系统功能设计

1.背景介绍 此服务器监控系统的目的在于提高行情服务器的监管效率&#xff0c;因目前的的行情服务器&#xff0c;包括DM、DT、DS配置数量较多&#xff0c;巡回维护耗时较多&#xff0c;当行情服务器出现异常故障&#xff0c;或者因为网络问题造成数据断线等情况时&#xff0c;监…...

【线性代数的本质】矩阵与线性变换

线性变化要满足两点性质&#xff1a; 直线&#xff08;连续的点&#xff09;在变换后还是直线。原点不变。 假设有坐标轴&#xff08;基底&#xff09; i ^ \widehat{i} i 和 j ^ \widehat{j} j ​&#xff1a; i ^ [ 1 0 ] , j ^ [ 0 1 ] \widehat{i}\begin{bmatrix} 1 \…...

CV02_超强数据集:MSCOCO数据集的简单介绍

1.1 简介 MSCOCO数据集&#xff0c;全称为Microsoft Common Objects in Context&#xff0c;是由微软公司在2014年推出并维护的一个大规模的图像数据集&#xff0c;旨在推动计算机视觉领域的研究&#xff0c;尤其是目标识别、目标检测、实例分割、图像描述生成等任务。该数据集…...

Linux--信号(万字详解!超完整!)

目录 0.预备知识 0.1.基本概念 0.2.信号的捕捉 0.3.理解信号的发送与保存 1.信号的产生&#xff08;阶段一&#xff09; 1.通过kill命令&#xff0c;向指定进程发送指定的信号 2.通过终端按键产生信号&#xff1a;ctrlc&#xff08;信号2&#xff09;&#xff0c;ctrl\(…...

onnx模型转rknn到部署

简介 最近开始用3568的板子&#xff0c;之前是在用3399&#xff0c;cpu的话3399比3568强&#xff0c;但是3568有1T的npu算力&#xff0c;所以模型移植过来用npu使用&#xff0c;之前用ncnn感觉太慢了&#xff0c;rk的npu使用没有开源&#xff0c;所以没法兼容&#xff0c;只能跑…...

lua入门(1) - 基本语法

本文参考自&#xff1a; Lua 基本语法 | 菜鸟教程 (runoob.com) 需要更加详细了解的还请参看lua 上方链接 交互式编程 Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。 Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用&#xff1a; 如下图: 按…...

Finding Global Homophily in Graph Neural Networks When Meeting Heterophily

本文发表于:ICML22 推荐指数: #paper/⭐⭐⭐ 问题背景: 异配图的邻接矩阵难以确定,以及异配图的计算复杂度开销大 可行的解决办法:高通滤波多跳邻居,GPRGNN(pagerank一类&#xff0c;各阶邻居的权重不同,ACM-GCN&#xff08;高低通滤波,H2GCN&#xff08;应该复杂度很大&…...

DisFormer:提高视觉动态预测的准确性和泛化能力

最新的研究进展已经显示出目标中心的表示方法在视觉动态预测任务中可以显著提升预测精度&#xff0c;并且增加模型的可解释性。这种表示方法通过将视觉场景分解为独立的对象&#xff0c;有助于模型更好地理解和预测场景中的变化。 尽管在静态图像的解耦表示学习方面已经取得了一…...

Android SurfaceFlinger——Surface和Layer介绍(十九)

按照前面系统开机动画的流程继续分析,在获取到显示屏信息后,下一步就是开始创建 Surface和设置 Layer 层级,这里就出现了两个新的概念——Surface 和 Layer。 一、基本概念 1、Surface介绍 在 Android 系统中,Surface 是一个非常核心的概念,它是用于显示图像的生产者-消…...

C++基础(七):类和对象(中-2)

上一篇博客学的默认成员函数是类和对象的最重要的内容&#xff0c;相信大家已经掌握了吧&#xff0c;这一篇博客接着继续剩下的内容&#xff0c;加油&#xff01; 目录 一、const成员&#xff08;理解&#xff09; 1.0 引入 1.1 概念 1.2 总结 1.2.1 对象调用成员函数 …...

对秒杀的思考

一、秒杀的目的 特价商品&#xff0c;数量有限&#xff0c;先到先得&#xff0c;售完为止 二、优惠券的秒杀 和特价商品的秒杀是一样的&#xff0c;只不过秒杀的商品是优惠券 三、秒杀的需求 秒杀前&#xff1a;提前将秒杀商品&#xff0c;存放到Redis秒杀中&#xff1a;使…...

数据结构预科

在堆区申请两个长度为32的空间&#xff0c;实现两个字符串的比较【非库函数实现】 要求&#xff1a; 1> 定义函数&#xff0c;在对区申请空间&#xff0c;两个申请&#xff0c;主函数需要调用2次 2> 定义函数&#xff0c;实现字符串的输入&#xff0c;void input(char …...

想做亚马逊测评技术需要解决哪些问题,有哪些收益?

现在真正有亚马逊测评技术的人赚的盆满钵满&#xff0c;有些人看到别人赚取就自己盲目去做&#xff0c;买完了账号和设备就感觉自己懂了&#xff0c;却不知里面的水深着&#xff0c;花了钱却没有掌握真正的技术&#xff0c;号莫名其妙就封完了&#xff0c;而每一次大风控注定要…...

1117 数字之王

solution 判断现有数字是否全为个位数 全为个位数&#xff0c;找出出现次数最多的数字&#xff0c;并首行输出最多出现次数&#xff0c;第二行输出所有出现该次数的数值不全为个位数 若当前位数值为0&#xff0c;无需处理若当前位数值非0&#xff0c;则每位立方相乘&#xff0…...

关于ORACLE单例数据库中的logfile的切换、删除以及添加

一、有关logfile的状态解释 UNUSED&#xff1a; 尚未记录change的空白group&#xff08;一般会出现在loggroup刚刚被添加&#xff0c;或者刚刚使用了reset logs打开数据库&#xff0c;或者使用clear logfile后&#xff09; CURRENT: 当前正在被LGWR使用的gro…...

Linux高并发服务器开发(十三)Web服务器开发

文章目录 1 使用的知识点2 http请求get 和 post的区别 3 整体功能介绍4 基于epoll的web服务器开发流程5 服务器代码6 libevent版本的本地web服务器 1 使用的知识点 2 http请求 get 和 post的区别 http协议请求报文格式: 1 请求行 GET /test.txt HTTP/1.1 2 请求行 健值对 3 空…...

人工智能系列-NumPy(二)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 链接数组 anp.array([[1,2],[3,4]]) print(第一个数组&#xff1a;) print(a) print(\n) bnp.array([[5,6],[7,8]]) print(第二个数组&#xff1a;) print(b) print(\n) print…...

[单master节点k8s部署]19.监控系统构建(四)kube-state-metrics

kube-state-metrics 是一个Kubernetes的附加组件&#xff0c;它通过监听 Kubernetes API 服务器来收集和生成关于 Kubernetes 对象&#xff08;如部署、节点和Pod等&#xff09;的状态的指标。这些指标可供 Prometheus 进行抓取和存储&#xff0c;从而使你能够监控和分析Kubern…...

字符串函数5-9题(30 天 Pandas 挑战)

字符串函数 1. 相关知识点1.5 字符串的长度条件判断1.6 apply映射操作1.7 python大小写转换1.8 正则表达式匹配2.9 包含字符串查询 2. 题目2.5 无效的推文2.6 计算特殊奖金2.7 修复表中的名字2.8 查找拥有有效邮箱的用户2.9 患某种疾病的患者 1. 相关知识点 1.5 字符串的长度条…...

【C语言题目】34.猜凶手

文章目录 作业标题作业内容2.解题思路3.具体代码 作业标题 猜凶手 作业内容 日本某地发生了一件谋杀案&#xff0c;警察通过排查确定杀人凶手必为4个嫌疑犯的一个。 以下为4个嫌疑犯的供词: A说&#xff1a;不是我。 B说&#xff1a;是C。 C说&#xff1a;是D。 D说&#xff…...

C++ 多进程多线程间通信

目录 一、进程间通信 1、管道&#xff08;Pipe&#xff09; 2、消息队列&#xff08;Message Queue&#xff09; 3、共享内存&#xff08;Shared Memory&#xff09; 4、信号量&#xff08;Semaphore&#xff09; 5、套接字&#xff08;Socket&#xff09; 6、信号&…...

怎么做防御系统IPS

入侵防御系统&#xff08;IPS&#xff09;是入侵检测系统&#xff08;IDS&#xff09;的增强版本&#xff0c;它不仅检测网络流量中的恶意活动&#xff0c;还能自动采取措施阻止这些活动。实现IPS的主要工具包括Snort和Suricata。以下是使用Snort和Suricata来实现IPS的详细步骤…...

达梦数据库的系统视图v$auditrecords

达梦数据库的系统视图v$auditrecords 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$AUDITRECORDS 是专门用来存储和查询数据库审计记录的重要系统视图。这个视图提供了对所有审计事件的访问权限&#xff0c;包括操作类型、操作用户、时间戳、目标对象等信…...

Spring Boot与MyBatis-Plus:代码逆向生成指南

在Spring Boot项目中使用MyBatis-Plus进行代码逆向生成&#xff0c;可以通过MyBatis-Plus提供的代码生成器来快速生成实体类、Mapper接口、Service接口及其实现类等。以下是一个简单的示例步骤&#xff1a; 代码逆向生成 1.添加依赖&#xff1a; 在pom.xml文件中添加MyBati…...

【MySQL】mysql访问

mysql访问 1.引入MySQL 客户端库2.C/C 进行增删改3.查询的处理细节4.图形化界面访问数据库4.1下载MYSQL Workbench4.2MYSQL Workbench远程连接数据库 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&a…...

(1)Jupyter Notebook 下载及安装

目录 1. Jupyter Notebook是什么&#xff1f;2. Jupyter Notebook特征3. 组成部分3.1 网页应用3.2 文档 4. 适用场景5. 利用Google Colab安装Jupyter Notebook3.1 什么是 Colab&#xff1f;3.2 访问 Google Colab3.3 新建笔记本 1. Jupyter Notebook是什么&#xff1f; 百度百科…...

监控平台zabbix对接grafana

本次博客基于监控平台zabbix介绍与部署-CSDN博客的环境下进行的 1、安装grafana并启动 添加一台虚拟机20.0.0.30 &#xff08;1&#xff09;系统初始化 [rootzx3 ~]# systemctl stop firewalld [rootzx3 ~]# setenforce 0 [rootzx3 ~]#&#xff08;2&#xff09;安装并启动…...

14-11 2024 年的 13 个 AI 趋势

2024 年的 13 个 AI 趋势 人工智能对环境的影响和平人工智能人工智能支持的问题解决和决策针对人工智能公司的诉讼2024 年美国总统大选与人工智能威胁人工智能、网络犯罪和社会工程威胁人工智能治疗孤独与对人工智能的情感依赖人工智能影响者中国争夺人工智能霸主地位人工智能…...

计算机大方向的选择

选专业要了解自己的兴趣所在。 即想要学习什么样的专业&#xff0c;如果有明确的专业意向&#xff0c;就可以有针对性地选择那些专业实力较强的院校。 2.如果没有明确的专业意向&#xff0c;可以优先考虑一下院校。 确定一下自己想要选择综合性院校还是理工类院校或是像财经或者…...

使用Qt Installer Framework在centos7中打包

文章目录 步骤 1: 安装Qt和Qt Installer Framework安装Qt安装Qt Installer Framework步骤 2: 创建项目目录结构步骤 3: 编写安装脚本配置文件(config/config.xml)Package 信息meta/package.xmldata 目录步骤 4: 编写安装脚本步骤 5: 生成安装程序总结在CentOS 7中使用Qt Inst…...

您的私人办公室!-----ONLYOFFICE8.1版本的桌面编辑器测评

随时随地创建并编辑文档&#xff0c;还可就其进行协作 ONLYOFFICE 文档是一款强大的在线编辑器&#xff0c;为您使用的平台提供文本文档、电子表格、演示文稿、表单和 PDF 编辑工具。 网页地址链接&#xff1a; https://www.onlyoffice.com/zh/office-suite.aspxhttps://www…...

点估计和参数分布的对比

点估计&#xff08;Point Estimation&#xff09;和 参数分布&#xff08;Parameter Distribution&#xff09;是统计学中两种不同的参数估计方法。 文章目录 点估计&#xff08;Point Estimation&#xff09;参数分布&#xff08;Parameter Distribution&#xff09;对比总结 …...

桌面保存的Word文件删除怎么找回?超实用的三个方法?

在日常工作和学习中&#xff0c;我们经常会使用Word文档进行文字编辑和文件保存。但是&#xff0c;有时由于操作失误或系统故障&#xff0c;我们会不小心将存放在电脑桌面重要的Word文件删除了。导致无法挽回的损失&#xff0c;但幸运的是&#xff0c;有一些方法可以帮助我们找…...

【leetcode】双指针算法题

文章目录 1.算法思想2.移动零3.复写零方法一方法二 4.快乐数5.盛水最多的容器方法一&#xff08;暴力求解&#xff09;方法二&#xff08;左右指针&#xff09; 6.有效三角形的个数方法一&#xff08;暴力求解&#xff09;方法二&#xff08;左右指针&#xff09; 7.两数之和8.…...

vue-router 源码分析——8.重定向

这是对vue-router 3 版本的源码分析。 本次分析会按以下方法进行&#xff1a; 按官网的使用文档顺序&#xff0c;围绕着某一功能点进行分析。这样不仅能学习优秀的项目源码&#xff0c;更能加深对项目的某个功能是如何实现的理解。这个对自己的技能提升&#xff0c;甚至面试时…...

CAN总线协议

CAN总线协议&#xff0c;全程为控制器局域网&#xff08;Controller Area Network&#xff09;协议&#xff0c;是一种用于实时应用的串行通讯协议。该协议由德国某公司专门为汽车行业开发&#xff0c;并逐渐成为一种标准&#xff0c;这是国际上应用最广泛的现场总线之一。 一…...

NLP篇1

场景&#xff1a;假设给你一篇文章。 目标&#xff1a;说白了&#xff0c;就是数学的分类。但是如何实现分类呢。下面将逐步一 一 分析与拆解。先把目标定好了和整体框架定好了。而不是只见树木而不见森林。 情感分类&#xff08;好评、差评&#xff0c;中性&#xff09; 整体…...

【一念发动便是行】念头,就是命运

一个个恶念累积就是负能量&#xff0c;念头就是命运&#xff0c;克除恶念&#xff0c;防范念头&#xff0c;念头都有能量&#xff0c;学圣学须内外庄严检肃&#xff0c;言语有灵 多数人的问题都是出在念头上&#xff0c;念头&#xff0c;就是自己的命运&#xff1b; 当我们对自…...