日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
趁熱打鐵,整一個新功能出來,你學會了嗎?

我們就先從最簡單的渠道管理開始。

還是老規(guī)矩,一個特別基礎的細節(jié)我就不啰嗦了,如果大家閱讀吃力,也可以先看看 vhr(https://github.com/lenve/vhr) 再看這個就容易多了。

1. 分配權限

我們依葫蘆畫瓢,首先在 sys_menu 中為渠道相關的操作添加權限,新增如下兩條記錄:

2008 就是渠道管理菜單項的 id。渠道管理將來就對應了這四個操作。

2. 渠道管理表

渠道管理比較簡單,一張表,也不需要引用其他表,如下:

這個表很簡單,沒啥好說的。

3. 服務端接口開發(fā)

3.1 現(xiàn)有功能分析

用了這個腳手架,我也就懶得另起爐灶了,我們現(xiàn)在要寫接口,接口該怎么寫?我們可以參考一個他自己寫好的,例如用戶管理接口。

用戶管理接口位置在 org.javaboy.web.controller.system.SysUserController#list 方法中:

@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list")
public TableDataInfo list(SysUser user) {
startPage();
List list = userService.selectUserList(user);
return getDataTable(list);
}

大家看,首先通過權限注解確保用戶具備相應的權限。這個權限注解對應的方法是 org.javaboy.framework.web.service.PermissionService#hasPermi 方法,具體的邏輯也并不難,當用戶登錄成功后,會查詢出來當前用戶的所有權限,并放到 LoginUser 對象中(這個在本系列的第一篇文章中已經(jīng)講過了),然后將之存入到 Redis 中,現(xiàn)在這里就是從 Redis 中取回 LoginUser 對象,然后拿出來用戶的權限字符串,跟這里需要的權限字符串做比對。

由于這個腳手架自定義了一個 BaseController,里邊封裝了很多常用的操作,所有的業(yè)務 Controller 都是繼承自這個 BaseController,所以這里的 startPage 方法其實就是 BaseController 中的方法,這個方法會自動開啟分頁功能,會從當前請求中提取出分頁參數(shù),然后進行查詢。如果前端沒有傳遞分頁參數(shù),那么默認查詢第一頁,查詢 10 條數(shù)據(jù)。

接下來就是一個常規(guī)的查詢操作,沒啥好說的。

最后的 getDataTable 方法則是將數(shù)據(jù)包裝成一個分頁的 JSON 對象。

還有一點要捋清楚,就是這個腳手架是一個多模塊項目,所有的借口定義統(tǒng)一在 admin 中,不同的功能對應不同的模塊,例如用戶管理相關的功能都在 system 這個模塊中。

好了,看懂這個,我們就照貓畫虎。

3.2 創(chuàng)建工程

首先,我們新建一個自己的功能模塊,這是一個 maven 項目,叫做 tienchin-channel。

這里我想用 MyBatis-Plus 來做,因此我先修改父工程的 dependencyManagement,將 mp 的版本號統(tǒng)一管理起來,同時也將新建模塊加進去,方便后期引用的時候進行版本號統(tǒng)一管理:


3.5.1
3.5.2




com.baomidou
mybatis-plus-boot-starter
${mybatis-plus-boot-starter.version}


com.baomidou
mybatis-plus-generator
${mybatis-plus-generator.version}


org.javaboy
tienchin-channel
${tienchin.version}



創(chuàng)建完成后,我們手動修改一下 tienchin-channel 的 pom.xml 文件,照著腳手架 system 模塊的改即可:


渠道管理模塊




org.javaboy
tienchin-common


渠道管理模塊 org.javaboy tienchin-common

接下來,在 admin 模塊中,依賴當前新建的 tienchin-channel 模塊和 mp 的代碼自動生成依賴,如下:


org.javaboy
tienchin-channel


com.baomidou
mybatis-plus-generator
test

另外依賴我還有一些細微的調(diào)整,例如為父模塊添加了 Spring Boot 作為其 parent 等,這些我就不逐一說明了,大家可以在文末下載源碼查看。

3.3 配置 MP

這個腳手架中雖然用了 MyBatis 的 starter,但是實際上還是自己手動配置的 MyBatis,所以當我們使用 MP 的時候,并不能像在 Spring Boot 中使用 MP 那樣,加個依賴就行了,我們還需要手動改一下配置。

首先我們將 mp 的依賴放到 common 模塊中,畢竟將來無論是 framework 還是我們新建的 tienchin-channel 都依賴 common 模塊,如下:

tienchin-common/pom.xml:


com.baomidou
mybatis-plus-boot-starter

然后,MyBatis 的配置是在 framework 模塊中,具體代碼在 tienchin-framework/src/main/java/org/javaboy/framework/config/MyBatisConfig.java 位置,我們直接在此進行修改即可。

@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis.mapperLocations");
String configLocation = env.getProperty("mybatis.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject();
}

小伙伴們看一下,在配置的過程中,將原本的 SqlSessionFactoryBean 改為 MybatisSqlSessionFactoryBean,其他都不變即可。

如此,我們的 MP 就配置好了。

3.4 生成代碼

接下來,我們在 admin 模塊的單元測試中,通過如下代碼來生成一下 channel 對應的實體類啥的,如果大家對這個自動生成代碼的不熟悉的話,可以看看這篇文章:自動生成實體類,哪個最佳?:

public class Generator {
@Test
public void channelGenerator() {
FastAutoGenerator.create("jdbc:mysql:///tienchin?serverTimezone=Asia/Shanghai&useSSL=false", "root", "123")
.globalConfig(builder -> {
builder.author("javaboy") // 設置作者
.disableOpenDir()
.fileOverride() // 覆蓋已生成文件
.outputDir("/Users/sang/workspace/workspace02/tienchin/tienchin-channel/src/main/java"); // 指定輸出目錄
})
.packageConfig(builder -> {
builder.parent("org.javaboy") // 設置父包名
.moduleName("channel") // 設置父包模塊名
.pathInfo(Collections.singletonMap(OutputFile.xml, "/Users/sang/workspace/workspace02/tienchin/tienchin-channel/src/main/resources/mapper/channel")); // 設置mapperXml生成路徑
})
.strategyConfig(builder -> {
builder.addInclude("tienchin_channel") // 設置需要生成的表名
.addTablePrefix("tienchin_");
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默認的是Velocity引擎模板
.execute();
}
}

自動生成的源碼自帶 Controller,我們將其刪除,重新在 admin 模塊中創(chuàng)建對應的 ChannelController 即可。

對照現(xiàn)有的任意一個 Controller,我們寫出來自己的 Controller,如下:

@RestController
@RequestMapping("/tienchin/channel")
public class ChannelController extends BaseController {

@Autowired
IChannelService channelService;

@PreAuthorize("@ss.hasPermi('tienchin:channel:query')")
@GetMapping("/list")
public TableDataInfo getChannelList() {
startPage();
List list = channelService.list();
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('tienchin:channel:add')")
@Log(title = "渠道管理" , businessType = BusinessType.INSERT)
@PostMapping("/")
public AjaxResult add(@Validated @RequestBody Channel channel) {
channel.setCreateBy(getUsername());
return toAjax(channelService.saveChannel(channel));
}

@PreAuthorize("@ss.hasPermi('tienchin:channel:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable Long id) {
return AjaxResult.success(channelService.getById(id));
}

@PreAuthorize("@ss.hasPermi('tienchin:channel:edit')")
@Log(title = "渠道管理" , businessType = BusinessType.UPDATE)
@PutMapping("/")
public AjaxResult edit(@Validated @RequestBody Channel channel) {
channel.setUpdateBy(getUsername());
channel.setUpdateTime(LocalDateTime.now());
return toAjax(channelService.saveOrUpdate(channel));
}

@PreAuthorize("@ss.hasPermi('tienchin:channel:remove')")
@Log(title = "渠道管理" , businessType = BusinessType.DELETE)
@DeleteMapping("/{channelIds}")
public AjaxResult remove(@PathVariable Long[] channelIds) {
return toAjax(channelService.removeBatchByIds(Arrays.asList(channelIds)));
}

}

都是常規(guī)操作,沒啥特別值得說的地方。

@Log 是腳手架中定義的日志記錄注解,加一個這個注解,會自動將當前的操作記錄到 sys_oper_log 表中,像下面這樣:

@PreAuthorize 操作權限就按一開始在數(shù)據(jù)庫中配置的內(nèi)容即可。

照貓畫虎,很快就寫出來這樣一個接口。

4. 開發(fā)前端頁面

接下來我們來整前端頁面,前端頁面我們在第二篇文章中提到過,該功能對應的頁面是 src/views/tienchin/channel/index.vue,所以我們只需要修改該頁面即可,這個修改,我們也找一個參照物,找一個也是表格的頁面改一下就行了,例如 src/views/system/dict/index.vue,這是字典管理的頁面,我們就照著這個來改就行了,前端的代碼量太大了,我就不全部貼出來了,我挑幾個關鍵的地方來說一下。

4.1 網(wǎng)絡請求

前端是每一個 .vue 文件都將自己所需的網(wǎng)絡請求封裝在一個 js 文件中,然后將來在 .vue 文件中直接引用。

例如關于數(shù)據(jù)字典的所有請求封裝在 src/api/system/dict/type.js 文件中,我照貓畫虎寫了關于 channel 的所有網(wǎng)絡請求:

src/api/channel/index.js

import request from '@/utils/request'

// 查詢所有的渠道信息
export function listChannel(query) {
return request({
url: '/tienchin/channel/list',
method: 'get',
params: query
})
}

// 根據(jù) id 查詢某一個渠道的信息
export function getChannel(channelId) {
return request({
url: '/tienchin/channel/' + channelId,
method: 'get'
})
}

// 添加渠道
export function addChannel(data) {
return request({
url: '/tienchin/channel/',
method: 'post',
data: data
})
}

// 更新渠道信息
export function updateChannel(data) {
return request({
url: '/tienchin/channel/',
method: 'put',
data: data
})
}

// 根據(jù) id 刪除渠道
export function delChannel(channelIds) {
return request({
url: '/tienchin/channel/' + channelIds,
method: 'delete'
})
}

4.2 頁面展示

頁面展示有一個地方需要和大家聊一聊。

就是當用戶登錄成功之后,前端會調(diào)用服務端的接口查看當前用戶信息,包括用戶的權限信息,而且前端還封裝了一個空閑顯示或者隱藏的工具,位置在 src/directive/permission/hasPermi.js,這個工具最終被做成了一個自定義指令,這樣,我們在展示每一個按鈕的時候,可以加上這個指令,將來就會自動根據(jù)用戶是否具備相應的權限來展示相應的按鈕,例如下面這幾個按鈕:


type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['tienchin:channel:add']"
>新增



type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['tienchin:channel:edit']"
>修改



type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['tienchin:channel:remove']"
>刪除


每個按鈕上都有一個 v-hasPermi 標簽來表述這個按鈕將來顯示的條件。

另外,前端也使用到了數(shù)據(jù)字典,也就是一些常見的字段取值我們將之固定下來了,在前端直接引用即可。數(shù)據(jù)字典本身對應的表是 sys_dict_data 和 sys_dict_type,像下面這樣(下圖為 sys_dict_data 表,關于他這個里邊的數(shù)據(jù)字典,后面有空了松哥可以再整一篇文章和大家分析具體用法):

需要用到哪條記錄,就在 vue 文件定義的時候聲明就行了,像下面這樣:

這樣,后期就可以直接引用這個變量了,如下:




options 其實就引用了數(shù)據(jù)字典中的值。

關于這個頁面其他的內(nèi)容就都是常規(guī)操作了,會 vhr 基本上都能看懂,我也就不啰嗦了。

最終弄出來的頁面如下:

5. 小結

好啦,今天就先聊這么多,源碼地址如下:

??https://github.com/lenve/tienchin??


網(wǎng)站名稱:趁熱打鐵,整一個新功能出來,你學會了嗎?
新聞來源:http://www.5511xx.com/article/cdceshs.html