今天的进度也有点少,今天去车管所体检了一下,考驾照体检过期了。。。。
今天给服务换了一种方式,设计的是用户注册的时候自动给他分配12个时刻(三天,今天,明天,后天 三天,上午下午各两个时刻)这样的话每个中医生注册的时候就会配有服务了,然后界面变丑了…
服务选择端获取用户及用户的服务,这个今天没算写好,问题在于后端idea在获取当天注册时间的时候,比数据库少8个小时,这样的话 我如果是8号凌晨1点注册,在数据库里面就是7号的下午5的注册的账号,给的服务时间也变成了 7号 8号 9号,实际应该是8 9 10 号这个问题还没解决。
这里就不给代码了。明天接着debug 不慌 头发还有。
服务选择失败!!!
开始文章管理
首先每个中医生登录以后会看见自己发布的文章,然后可以选择上架 ,下架自己的文章,查看和编辑还没有实现,点击下架以后 文章的状态变为下架 后面的按钮变成上架。
首先给这个界面的前端代码贴一下
<template>
<div class="article_list">
<el-table
:data="articleList" size="medial" style="width: 860px; margin: 0 auto;">
<el-table-column label="文章标题" width="100" prop="article_title"></el-table-column>
<el-table-column label="文章简介" width="100" prop="article_describe"></el-table-column>
<el-table-column prop="click_number" label="阅读量" width="100"></el-table-column>
<el-table-column label="状态" width="100">
<template slot-scope="scope">
<el-tag size="mini" v-if="scope.row.article_status === '1'" type="success"> 上架 </el-tag>
<el-tag size="mini" v-else-if="scope.row.article_status === '0'" type="danger"> 下架 </el-tag>
</template>
</el-table-column>
<el-table-column label="发布时间" width="160">
<template slot-scope="scope">
{{ scope.row.create_time.substring(0,19).replace("T", " ") }}
</template>
</el-table-column>
<el-table-column width="300">
<template slot="header">
<el-button type="success" size="mini" @click="handleToAdd">新增文章</el-button>
</template>
<template slot-scope="scope">
<el-button size="mini" type="warning" @click="handlePreviewSkill(scope.row)"> 查看 </el-button>
<el-button size="mini" type="warning" @click="handleResetPwd(scope.row)"> 编辑 </el-button>
<el-button size="mini" v-if="scope.row.article_status === '0'" type="warning" @click="handlePublishArticle(scope.row)"> 上架 </el-button>
<el-button size="mini" v-else-if="scope.row.article_status === '1'" type="danger" @click="handleUnShelveArticle(scope.row)"> 下架 </el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { findArticleByAuthorId, updateStateByArticleId } from '../../api/article'
export default {
name: 'ArticleAdmin',
data () {
return {
articleList: []
}
},
created () {
this.fetchArticleList()
},
methods: {
handleToAdd () {
this.$router.push({ path: '/article-add' })
},
handlePublishArticle (article) {
this.$confirm('此操作将上架文章, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
}).then(() => {
article.article_status = '1'
return updateStateByArticleId(article)
}).then(() => {
this.fetchArticleList()
this.$message({
type: 'success',
message: '上架成功',
offset: 100
})
}).catch(error => {
console.log(error)
if (error !== 'cancel') {
this.$message({
type: 'error',
message: '上架失败',
offset: 100
})
}
})
},
handleUnShelveArticle (article) {
this.$confirm('此操作将下架文章, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
}).then(() => {
article.article_status = '0'
return updateStateByArticleId(article)
}).then(() => {
this.fetchArticleList()
this.$message({
type: 'success',
message: '下架成功',
offset: 100
})
}).catch(error => {
console.log(error)
if (error !== 'cancel') {
this.$message({
type: 'error',
message: '下架失败',
offset: 100
})
}
})
},
fetchArticleList () {
findArticleByAuthorId({ author_id: this.$store.state.user.userinfo.user_id }).then(res => {
console.log(res.data)
this.articleList = res.data
}).catch(error => {
console.log(error)
})
}
}
}
</script>
<style lang="less" scoped>
.article_list {
padding-top: 50px;
}
</style>
给文章设置一个属性就是article_state 也就是文章状态,在获取文章的时候,获取文章的状态,点击上架以后触发事件handlePublishArticle,然后跳出弹窗 将上架文章 确定以后执行updateStateByArticleId 更新数据库里面文章的状态 同时提示上架成功,
//如果取消的话error的值为cancel 这样当error不为cancel的时候 表示上架失败 下架文章同理
fetchArticleList 在创建这个页面的时候执行 然后执行findArticleByAuthorId 通过作者的id查询文章 然后将文章列表给此页面的articleList 所以也就是两个api updateStateByArticleId
findArticleByAuthorId
在article.js添加
export function findArticleByAuthorId (query) {
return request({
url: '/front/findArticleByAuthorId',
method: 'get',
params: query
})
}
export function updateStateByArticleId (data) {
return request({
url: '/updateStateByArticleId',
method: 'post',
data: data
})
}
然后 后接口书写
实体类不需要创建
mapper层 Boolean updateStateByArticleId(Article article);
List
xml文件
<select id="findArticleByAuthorId"
resultType="bysj.bysj.model.Article">
select * from article where author_id = #{author_id}
</select>
<update id="updateStateByArticleId">
update article set article_status = #{article_status} where article_id = #{article_id}
</update>
controller层 updateStateByArticleId findArticleByAuthorId在前面加了一个front表示前台使用
@PostMapping("updateStateByArticleId")
public AjaxResult updateStateByArticleId (HttpServletRequest request, @RequestBody Article article) {
try {
String token = request.getHeader("Authorization");
try {
Claims claims = JwtUtils.checkToken(token);
if (claims == null) {
return AjaxResult.error(50012, "未传输 token");
}
} catch (ExpiredJwtException e) {
return AjaxResult.error(50013, "token 已过期");
} catch (Exception e) {
return AjaxResult.error(50014, "无效 token");
}
Boolean result = articleMapper.updateStateByArticleId(article);
if (result) {
return AjaxResult.success(200, "修改文章状态成功", result);
} else {
return AjaxResult.error(5005, "修改文章状态失败");
}
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error(5005, "修改文章状态失败");
}
}
@GetMapping("front/findArticleByAuthorId")
public AjaxResult findArticleByAuthorId (HttpServletRequest request, @RequestParam Integer author_id) {
try {
List<Article> articleList = articleMapper.findArticleByAuthorId(author_id);
return AjaxResult.success(200, "查询文章列表成功", articleList);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error(50032, "查询文章列表失败");
}
}
中医生文章管理结束
后台文章管理开始
前段代码如下逻辑跟前面没差
<template>
<div>
<el-row class="query">
<el-form :model="queryParams" ref="queryParamsRef" size="small" :inline="true" label-width="68px">
<el-form-item label="文章标题">
<el-input placeholder="请输入文章标题" clearable
v-model="queryParams.article_title" style="width: 240px"/>
</el-form-item>
<el-form-item label="作者">
<el-input placeholder="请输入作者" clearable
v-model="queryParams.author_name" style="width: 240px"/>
</el-form-item>
<el-form-item label="时间">
<el-date-picker v-model="queryParamsTime"
type="datetimerange" range-separator="至"
start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleSearchArticle">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="handlePageReset">重置</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<el-select @change="handleChangeCategory" clearable
style="width: 240px" v-model="page.article_category">
<el-option label="护理" value="1"/>
<el-option label="养生" value="2"/>
</el-select>
</el-row>
<el-row>
<el-table
:data="articleList" size="mini"
style="width: 100%">
<el-table-column prop="article_id" label="编号" width="100"></el-table-column>
<el-table-column prop="article_title" label="文章标题" width="150"></el-table-column>
<el-table-column prop="article_describe" label="文章描述" width="150"></el-table-column>
<el-table-column prop="userDoctor.user_name" label="作者" width="150"></el-table-column>
<el-table-column label="状态" width="100">
<template slot-scope="scope">
<el-tag size="mini" v-if="scope.row.article_status === '0'" type="danger"> 下架 </el-tag>
<el-tag size="mini" v-else-if="scope.row.article_status === '1'" type="success"> 上架 </el-tag>
</template>
</el-table-column>
<el-table-column label="点赞量" width="100" prop="good_number"></el-table-column>
<el-table-column label="点击量" width="100" prop="click_number"></el-table-column>
<el-table-column label="创建时间" width="160">
<template slot-scope="scope">
{{ scope.row.create_time.substring(0,19).replace("T", " ") }}
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button size="mini" type="warning" @click="handlePreviewIllness(scope.row)"> 查看内容 </el-button>
<el-button size="mini" v-if="scope.row.article_status === '0'" type="warning" @click="handlePublishArticle(scope.row)"> 上架 </el-button>
<el-button size="mini" v-else-if="scope.row.article_status === '1'" type="danger" @click="handleUnShelveArticle(scope.row)"> 下架 </el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row id="pagination">
<!-- 分页:开始 -->
<el-pagination v-if="page.listTotal !== '0' && !queryFlag"
small :page-sizes="[6, 12, 18]" :page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="page.listTotal"
@size-change="handleSizeChange" @current-change="handleCurrentChange">
</el-pagination>
<!-- 分页:结束 -->
</el-row>
</div>
</template>
<script>
import { queryArticleByParams, findArticleByCategory, findArticleTotalByCategory, updateStateByArticleId } from '../../api/article'
export default {
name: 'Article',
data () {
return {
queryFlag: false, // 查询所得医生列表,控制分页是否显示
queryParams: {
article_title: null,
author_name: null,
article_category: null,
beginTime: null,
endTime: null
},
articleList: [],
queryParamsTime: [],
page: { // 分页数据
article_category: '1',
pageNum: 1,
pageSize: 6,
listTotal: 0
}
}
},
created () {
this.fetchArticleList()
},
watch: {
queryParamsTime (newTime) { // 监听日期选择
if (newTime[0]) {
this.queryParams.beginTime = newTime[0].toISOString()
}
if (newTime[1]) {
this.queryParams.endTime = newTime[1].toISOString()
}
}
},
methods: {
handlePageReset () {
this.queryFlag = false
this.page.pageNum = 1
this.page.pageSize = 6
this.page.listTotal = 0
this.queryParams.article_title = null
this.queryParams.author_name = null
this.queryParams.article_category = null
this.queryParams.beginTime = null
this.queryParams.endTime = null
this.queryParamsTime = null
this.fetchArticleList()
},
handleSearchArticle () {
this.queryParams.article_category = this.page.article_category
queryArticleByParams(this.queryParams).then(res => {
this.articleList = res.data
this.queryFlag = true
}).catch(error => {
console.log(error)
})
},
handleSizeChange (newPageSize) {
this.page.pageSize = newPageSize
this.fetchArticleList()
},
handleCurrentChange (newPageNum) {
this.page.pageNum = newPageNum
this.fetchArticleList()
},
handleChange (category) {
this.page.article_category = category
this.page.pageNum = 1
this.page.pageSize = 6
this.fetchArticleList()
},
fetchArticleList () {
findArticleTotalByCategory({ article_category: this.page.article_category }).then(res => { // Promise 链式处理
this.page.listTotal = res.data
return findArticleByCategory(this.page)
}).then(res => {
this.articleList = res.data
console.log(res) // for debug
}).catch(error => {
console.log(error)
})
},
handleChangeCategory () {
this.$refs.queryParamsRef.resetFields()
this.fetchArticleList()
},
handlePublishArticle (article) {
this.$confirm('此操作将上架文章, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
}).then(() => {
article.article_status = '1'
return updateStateByArticleId(article)
}).then(() => {
this.fetchArticleList()
this.$message({
type: 'success',
message: '上架成功',
offset: 100
})
}).catch(error => {
console.log(error)
if (error !== 'cancel') {
this.$message({
type: 'error',
message: '上架失败',
offset: 100
})
}
})
},
handleUnShelveArticle (article) {
this.$confirm('此操作将下架文章, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
}).then(() => {
article.article_status = '0'
return updateStateByArticleId(article)
}).then(() => {
this.fetchArticleList()
this.$message({
type: 'success',
message: '下架成功',
offset: 100
})
}).catch(error => {
console.log(error)
if (error !== 'cancel') {
this.$message({
type: 'error',
message: '下架失败',
offset: 100
})
}
})
}
}
}
</script>
<style lang="less" scoped>
</style>
用户端文章获取 只加了一局话也就是文章状态状态为1 添加一个front便是前台使用的api mapper层需要
Integer frontFindArticleTotalByCategory(@Param("article_category") String article_category);
List<Article> frontFindArticleByCategory(@Param("article_category") String article_category);
因为还有分页 所以也需要再写一个不需要token的获取文章总数,
controller层 没有token 的根据分类获取文章
@GetMapping("front/findArticleByCategory")
public AjaxResult frontFindArticleByCategory (@RequestParam String article_category, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
try {
PageHelper.startPage(pageNum, pageSize);
List<Article> articleList = articleMapper.frontFindArticleByCategory(article_category);
return AjaxResult.success(200, "根据分类获取文章列表成功", articleList);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error(5010, "根据分类获取文章列表失败");
}
}
后台文章管理
后台需要token 同时需要获取所有的文章 还有文章总数
不需要新建类,
mapper List<Article> findArticleByCategory(@Param("article_category") String article_category);
Integer findArticleTotalByCategory(@Param("article_category") String article_category);
xml文件 去掉article_status = “1”
controller层为
@GetMapping("findArticleByCategory")
public AjaxResult findArticleByCategory (HttpServletRequest request,@RequestParam String article_category, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
try {
String token = request.getHeader("Authorization");
try {
Claims claims = JwtUtils.checkToken(token);
if (claims == null) {
return AjaxResult.error(50012, "未传输 token");
}
} catch (ExpiredJwtException e) {
return AjaxResult.error(50013, "token 已过期");
} catch (Exception e) {
return AjaxResult.error(50014, "无效 token");
}
PageHelper.startPage(pageNum, pageSize);
List<Article> articleList = articleMapper.findArticleByCategory(article_category);
return AjaxResult.success(200, "根据分类获取文章列表成功", articleList);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error(5010, "根据分类获取文章列表失败");
}
}
@GetMapping("findArticleTotalByCategory")
public AjaxResult findArticleTotalByCategory (HttpServletRequest request, @RequestParam String article_category) {
try {
String token = request.getHeader("Authorization");
try {
Claims claims = JwtUtils.checkToken(token);
if (claims == null) {
return AjaxResult.error(50012, "未传输 token");
}
} catch (ExpiredJwtException e) {
return AjaxResult.error(50013, "token 已过期");
} catch (Exception e) {
return AjaxResult.error(50014, "无效 token");
}
return AjaxResult.success(200, "根据分类获取文章列表总数成功", articleMapper.findArticleTotalByCategory(article_category));
} catch (Exception e) {
return AjaxResult.error(5019, "根据分类获取文章列表总数失败");
}
}
就是多加了一个token验证
后台文章管理结束
角色白名单 首先
- 游客只能看见阅读文章和选择服务 (不能加入购物车)
- 社区人员多加了购物车 个人中心
- 中医生多了文章管理还有服务管理
- 所以写了一个permission 超越权限跳转到登录页面
import router from './router'
import store from './store'
const commonWhiteList = ['/article', '/service', '/article-read', '/login'] // 游客无须重定向白名单
const doctorWhiteList = ['/article', '/article-admin', '/article-read', '/article-add', '/service', '/doctor-center', '/service-admin', '/login'] // 中医生账号无须重定向白名单
const communityWhiteList = ['/article', '/article-read', '/service', '/community-center', '/login'] // 社区人员账号无须重定向白名单
router.beforeEach((to, from, next) => {
console.log(to.path)
if (store.state.user.userinfo !== null) { // 如果已经登录
if (store.state.user.userinfo.role === '0' && (doctorWhiteList.indexOf(to.path) !== -1 || to.path.startsWith('/article-read'))) { // 如果已经登录,且为中医生账号,且处于中医生账号白名单中
next()
} else if (store.state.user.userinfo.role === '1' && (communityWhiteList.indexOf(to.path) !== -1 || to.path.startsWith('/article-read'))) { // 如果已经登录,且为社区人员账号,且处于社区人员账号白名单中
next()
} else { // 如果已经登录,但访问路径超越权限,重新登录
next({ path: '/login' })
}
} else if (commonWhiteList.indexOf(to.path) !== -1 || to.path.startsWith('/article-read')) { // 如果未登录,但处于游客白名单中,放行
next()
} else { // 如果未登录,且不处于游客白名单中,转向登录页
next({ path: '/login' })
}
})