本文介绍正则采集器的采集网站管理的开发。
系统需要动态添加采集网站,对网站地址、名称、匹配商品的正则表达式字段进行设置。
新建数据库表
sql
CREATE TABLE `item_website` (
`id` bigint NOT NULL AUTO_INCREMENT,
`code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`regexp_str` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`regexp_contents` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`start_str` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`end_str` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
后端代码
在后端代码中新建实体类、Mapper类和Controller类,下面贴出Controller类,因为采集网站不会非常多,所以不分页。请求地址和参数采用REST风格编写。
java
package com.learn.reptile.web.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.learn.reptile.entity.po.ItemWebsite;
import com.learn.reptile.entity.vo.R;
import com.learn.reptile.mapper.ItemWebsiteMapper;
@RequestMapping("/itemWebsite")
@RestController
public class ItemWebsiteController {
@Resource
ItemWebsiteMapper itemWebsiteMapper;
@GetMapping
public R<List<ItemWebsite>> list() {
return R.ok(itemWebsiteMapper.selectList(new QueryWrapper<>()));
}
@GetMapping("{id}")
public R get(@PathVariable("id") Long id) {
return R.ok(itemWebsiteMapper.selectById(id));
}
@PostMapping
public R add(@RequestBody ItemWebsite itemWebsite) {
itemWebsiteMapper.insert(itemWebsite);
return R.ok();
}
@PutMapping("{id}")
public R update(@PathVariable("id") Long id, @RequestBody ItemWebsite itemWebsite) {
itemWebsiteMapper.updateById(itemWebsite);
return R.ok();
}
@DeleteMapping("{id}")
public R deleteById(@PathVariable("id") Long id) {
itemWebsiteMapper.deleteById(id);
return R.ok();
}
}
前端代码
添加router,位置:src/router/modules/home.js
javascript
{
path: '/item', //父菜单,下面还会加其他菜单
component: Layout,
name: 'item',
meta: {
title: '商品',
},
icon: 'icon-home',
children: [
{
path: 'itemWebsite',
name: 'itemWebiste',
component: () => import('@/views/item_website/index.vue'),
meta: {
title: '网站',
},
},
],
},
添加api,位置:src/api/itemWebsite.js
javascript
import request from '@/utils/request'
export const add = data => {
return request({
url: '/api/itemWebsite',
method: 'post',
data,
})
}
export const update = data => {
return request({
url: '/api/itemWebsite/' + data.id,
method: 'put',
data,
})
}
export const deleteById = id => {
return request({
url: '/api/itemWebsite/' + id,
method: 'delete',
})
}
export const list = () => {
return request({
url: '/api/itemWebsite',
method: 'get',
})
}
export const getById = id => {
return request({
url: '/api/itemWebsite/' + id,
method: 'get',
})
}
添加页面,位置src/views/item_website/index.vue
html
<template>
<div>
<el-button type="primary" @click="edit(null)">添加</el-button>
<el-table
:data="list"
v-loading="loading"
element-loading-text="Loading"
highlight-current-row
border
fit
>
<el-table-column prop="code" label="编码"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button
type="primary"
@click="$router.push('/item/itemRegexp/' + scope.row.id)"
>
商品匹配规则
</el-button>
<el-button @click="edit(scope.row)">修改</el-button>
<el-popconfirm title="确认删除?" @confirm="deleteById(scope.row.id)">
<template #reference>
<el-button type="danger">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-dialog
v-model="editDialogVisible"
:title="editForm.id ? '修改网站' : '添加网站'"
width="40%"
@close="editDialogVisible = false"
>
<el-form
ref="editFormRef"
:model="editForm"
:rules="editFormRules"
label-position="left"
>
<el-form-item prop="code" label="编码">
<el-input v-model="editForm.code"></el-input>
</el-form-item>
<el-form-item prop="name" label="名称">
<el-input v-model="editForm.name"></el-input>
</el-form-item>
<el-form-item prop="url" label="URL">
<el-input v-model="editForm.url"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save">保存</el-button>
<el-button type="warning" @click="editDialogVisible = false">
取消
</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
import {
getCurrentInstance,
reactive,
toRefs,
ref,
computed,
watch,
onMounted,
} from 'vue'
import { list, add, update, deleteById } from '@/api/itemWebsite'
export default {
setup() {
const { proxy: ctx } = getCurrentInstance()
const state = reactive({
loading: false,
list: [],
editDialogVisible: false,
editForm: {
id: '',
code: '',
name: '',
url: '',
},
editFormRules: {
code: [{ required: true, message: '编码不能为空' }],
name: [{ required: true, message: '名称不能为空' }],
url: [{ required: true, message: 'URL不能为空' }],
},
editFormRef: ref(null),
save() {
ctx.$refs.editFormRef.validate(valid => {
if (valid) {
if (ctx.editForm.id) {
update(ctx.editForm).then(res => {
ctx.$message.success('更新成功')
ctx.editDialogVisible = false
ctx.getList()
})
} else {
add(ctx.editForm).then(res => {
ctx.$message.success('添加成功')
ctx.editDialogVisible = false
ctx.getList()
})
}
}
})
},
edit(row) {
if (row) {
ctx.editForm = {
id: row.id,
code: row.code,
name: row.name,
url: row.url,
}
} else {
ctx.editForm = {
id: '',
code: '',
name: '',
url: '',
}
}
ctx.editDialogVisible = true
},
deleteById(id) {
deleteById(id).then(res => {
ctx.$message.success('删除成功')
ctx.getList()
})
},
getList() {
ctx.loading = true
list().then(res => {
ctx.list = res.data
ctx.loading = false
})
},
})
onMounted(() => {
ctx.getList()
})
return {
...toRefs(state),
}
},
}
</script>
<style></style>
这是典型的vue模板代码的结构,template、script和style三部分,template是html网页模板,javascript是逻辑代码,用于数据、事件绑定。
Vue3,首先导入方法:
javascript
import {
getCurrentInstance,
reactive,
toRefs,
ref,
computed,
watch,
onMounted,
} from 'vue'
在setup方法中设置好template中可用的对象和方法,vue3中没有this,可以用ctx代替。
javascript
const { proxy: ctx } = getCurrentInstance()
- 页面加载完成后调用onMounted,加载list,数据渲染在el-table组件中。
- 点击添加或编辑按钮时调用edit方法,弹出编辑框el-dialog组件。
el-dialog组件中数据表单使用el-form组件,提交时通过ctx.$refs.editForm.validate进行数据校验。 - 删除方法,通过el-popconfirm加上确认行为。
代码地址及演示地址见博文:正则采集器------需求说明-CSDN博客