正则采集器之四——采集网站管理

本文介绍正则采集器的采集网站管理的开发。

系统需要动态添加采集网站,对网站地址、名称、匹配商品的正则表达式字段进行设置。

新建数据库表

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风格编写。

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

{
    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

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

<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,首先导入方法:

import {
  getCurrentInstance,
  reactive,
  toRefs,
  ref,
  computed,
  watch,
  onMounted,
} from 'vue'

在setup方法中设置好template中可用的对象和方法,vue3中没有this,可以用ctx代替。

const { proxy: ctx } = getCurrentInstance()
  • 页面加载完成后调用onMounted,加载list,数据渲染在el-table组件中。
  • 点击添加或编辑按钮时调用edit方法,弹出编辑框el-dialog组件。
    el-dialog组件中数据表单使用el-form组件,提交时通过ctx.$refs.editForm.validate进行数据校验。
  • 删除方法,通过el-popconfirm加上确认行为。

代码地址及演示地址见博文:正则采集器——需求说明-CSDN博客

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值