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

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

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

新建数据库表

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博客

相关推荐
Wiktok6 小时前
【pure-admin】pureadmin的登录对接后端
vue3·pureadmin
蓝胖子的多啦A梦13 小时前
【前端】VUE+Element UI项目 页面自适应横屏、竖屏、大屏、PDA及手机等适配方案
前端·javascript·elementui·html·前端页面适配
Wiktok14 小时前
【Wit】pure-admin后台管理系统前端与FastAPI后端联调通信实例
前端·vue3·pureadmin
Wiktok1 天前
前后端开发Mock作用说明,mock.ts
前端·mock·vue3
wangbing11251 天前
界面规范11-对话框
javascript·vue.js·elementui
麦聪聊数据2 天前
如何使用 QuickAPI 快速连接 MySQL 数据库并发布 RESTful API
数据库·sql·mysql·restful·数据服务
知识分享小能手2 天前
React学习教程,从入门到精通,React AJAX 语法知识点与案例详解(18)
前端·javascript·vue.js·学习·react.js·ajax·vue3
Wiktok3 天前
pureadmin的动态路由和静态路由
前端·vue3·pureadmin
Jinuss3 天前
Vue3源码reactivity响应式篇之watch实现
前端·vue3
知识分享小能手3 天前
React学习教程,从入门到精通,React 组件生命周期详解(适用于 React 16.3+,推荐函数组件 + Hooks)(17)
前端·javascript·vue.js·学习·react.js·前端框架·vue3