mp:增加图文草稿箱的修改;优化前端代码

This commit is contained in:
YunaiV 2023-01-14 09:17:01 +08:00
parent 28884ee638
commit 90ffe5adb7
8 changed files with 365 additions and 348 deletions

View File

@ -46,6 +46,7 @@ public interface ErrorCodeConstants {
// ========== 公众号草稿 1006007000============ // ========== 公众号草稿 1006007000============
ErrorCode DRAFT_LIST_FAIL = new ErrorCode(1006007000, "获得草稿列表失败,原因:{}"); ErrorCode DRAFT_LIST_FAIL = new ErrorCode(1006007000, "获得草稿列表失败,原因:{}");
ErrorCode DRAFT_CREATE_FAIL = new ErrorCode(1006007001, "创建草稿失败,原因:{}"); ErrorCode DRAFT_CREATE_FAIL = new ErrorCode(1006007001, "创建草稿失败,原因:{}");
ErrorCode DRAFT_UPDATE_FAIL = new ErrorCode(1006007002, "更新草稿失败,原因:{}");
// TODO 要处理下 // TODO 要处理下
ErrorCode MENU_NOT_EXISTS = new ErrorCode(1006001002, "菜单不存在"); ErrorCode MENU_NOT_EXISTS = new ErrorCode(1006001002, "菜单不存在");

View File

@ -7,12 +7,18 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import javax.validation.constraints.NotNull;
@ApiModel("管理后台 - 公众号素材的分页 Request VO") @ApiModel("管理后台 - 公众号素材的分页 Request VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class MpMaterialPageReqVO extends PageParam { public class MpMaterialPageReqVO extends PageParam {
@ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048")
@NotNull(message = "公众号账号的编号不能为空")
private Long accountId;
@ApiModelProperty(value = "是否永久", example = "true") @ApiModelProperty(value = "是否永久", example = "true")
private Boolean permanent; private Boolean permanent;

View File

@ -30,3 +30,25 @@ tenant-id: {{adminTenentId}}
} }
] ]
} }
### 请求 /mp/draft/create 接口 => 成功
PUT {{baseUrl}}/mp/draft/update?accountId=1&mediaId=r6ryvl6LrxBU0miaST4Y-q-G9pdsmZw0OYG4FzHQkKfpLfEwIH51wy2bxisx8PvW
Content-Type: application/json
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
[{
"title": "我是标题OOO",
"author": "我是作者",
"digest": "我是摘要",
"content": "我是内容",
"contentSourceUrl": "https://www.iocoder.cn",
"thumbMediaId": "r6ryvl6LrxBU0miaST4Y-pIcmK-zAAId-9TGgy-DrSLhjVuWbuT3ZBjk9K1yQ0Dn"
}, {
"title": "我是标题XXX",
"author": "我是作者",
"digest": "我是摘要",
"content": "我是内容",
"contentSourceUrl": "https://www.iocoder.cn",
"thumbMediaId": "r6ryvl6LrxBU0miaST4Y-pIcmK-zAAId-9TGgy-DrSLhjVuWbuT3ZBjk9K1yQ0Dn"
}]

View File

@ -7,21 +7,20 @@ import cn.iocoder.yudao.module.mp.controller.admin.news.vo.MpDraftPageReqVO;
import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory; import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.draft.WxMpAddDraft; import me.chanjar.weixin.mp.bean.draft.*;
import me.chanjar.weixin.mp.bean.draft.WxMpDraftItem;
import me.chanjar.weixin.mp.bean.draft.WxMpDraftList;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.DRAFT_CREATE_FAIL; import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.DRAFT_LIST_FAIL;
// TODO 芋艿权限 // TODO 芋艿权限
@Api(tags = "管理后台 - 公众号草稿") @Api(tags = "管理后台 - 公众号草稿")
@ -54,14 +53,37 @@ public class MpDraftController {
@ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true,
example = "1024", dataTypeClass = Long.class) example = "1024", dataTypeClass = Long.class)
public CommonResult<String> createDraft(@RequestParam("accountId") Long accountId, public CommonResult<String> createDraft(@RequestParam("accountId") Long accountId,
@RequestBody WxMpAddDraft reqVO) { @RequestBody WxMpAddDraft draft) {
WxMpService mpService = mpServiceFactory.getRequiredMpService(accountId); WxMpService mpService = mpServiceFactory.getRequiredMpService(accountId);
try { try {
String mediaId = mpService.getDraftService().addDraft(reqVO); String mediaId = mpService.getDraftService().addDraft(draft);
return success(mediaId); return success(mediaId);
} catch (WxErrorException e) { } catch (WxErrorException e) {
throw exception(DRAFT_CREATE_FAIL, e.getError().getErrorMsg()); throw exception(DRAFT_CREATE_FAIL, e.getError().getErrorMsg());
} }
} }
@PutMapping("/update")
@ApiOperation("更新草稿")
@ApiImplicitParams({
@ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true,
example = "1024", dataTypeClass = Long.class),
@ApiImplicitParam(name = "mediaId", value = "草稿素材的编号", required = true,
example = "xxx", dataTypeClass = String.class),
})
public CommonResult<Boolean> createDraft(@RequestParam("accountId") Long accountId,
@RequestParam("mediaId") String mediaId,
@RequestBody List<WxMpDraftArticles> articles) {
WxMpService mpService = mpServiceFactory.getRequiredMpService(accountId);
try {
for (int i = 0; i < articles.size(); i++) {
WxMpDraftArticles article = articles.get(i);
mpService.getDraftService().updateDraft(new WxMpUpdateDraft(mediaId, i, article));
}
return success(true);
} catch (WxErrorException e) {
throw exception(DRAFT_UPDATE_FAIL, e.getError().getErrorMsg());
}
}
} }

View File

@ -20,6 +20,7 @@ public interface MpMaterialMapper extends BaseMapperX<MpMaterialDO> {
default PageResult<MpMaterialDO> selectPage(MpMaterialPageReqVO pageReqVO) { default PageResult<MpMaterialDO> selectPage(MpMaterialPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<MpMaterialDO>() return selectPage(pageReqVO, new LambdaQueryWrapperX<MpMaterialDO>()
.eq(MpMaterialDO::getAccountId, pageReqVO.getAccountId())
.eqIfPresent(MpMaterialDO::getPermanent, pageReqVO.getPermanent()) .eqIfPresent(MpMaterialDO::getPermanent, pageReqVO.getPermanent())
.eqIfPresent(MpMaterialDO::getType, pageReqVO.getType())); .eqIfPresent(MpMaterialDO::getType, pageReqVO.getType()));
} }

View File

@ -19,3 +19,12 @@ export function createDraft(accountId, articles) {
} }
}) })
} }
// 更新草稿
export function updateDraft(accountId, mediaId, articles) {
return request({
url: '/mp/draft/update?accountId=' + accountId + '&mediaId=' + mediaId,
method: 'put',
data: articles
})
}

View File

@ -117,7 +117,7 @@
}, },
props: { props: {
objData: { objData: {
type: Object, type: Object, // type - accountId -
required: true required: true
}, },
newsType:{ // 12稿 newsType:{ // 12稿
@ -148,6 +148,11 @@
selectMaterial(item) { selectMaterial(item) {
this.$emit('selectMaterial', item) this.$emit('selectMaterial', item)
}, },
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1
this.getPage()
},
getPage() { getPage() {
this.loading = true this.loading = true
if (this.objData.type === 'news' && this.newsType === '1') { // + if (this.objData.type === 'news' && this.newsType === '1') { // +

View File

@ -20,6 +20,8 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
芋道源码
优化代码和项目的代码保持一致
--> -->
<template> <template>
<div class="app-container"> <div class="app-container">
@ -54,7 +56,7 @@ SOFTWARE.
<!-- TODO 芋艿权限样式搜索框之类的 --> <!-- TODO 芋艿权限样式搜索框之类的 -->
<el-row class="ope-row"> <el-row class="ope-row">
<el-button type="success" circle @click="handlePublishNews(item)">发布</el-button> <el-button type="success" circle @click="handlePublishNews(item)">发布</el-button>
<el-button type="primary" icon="el-icon-edit" circle @click="handleEditNews(item)"></el-button> <el-button type="primary" icon="el-icon-edit" circle @click="handleUpdate(item)"></el-button>
<el-button type="danger" icon="el-icon-delete" circle @click="delMaterial(item)"></el-button> <el-button type="danger" icon="el-icon-delete" circle @click="delMaterial(item)"></el-button>
</el-row> </el-row>
</div> </div>
@ -66,14 +68,10 @@ SOFTWARE.
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/> @pagination="getList"/>
<!-- TODO 芋艿位置调整 --> <!-- 添加或修改草稿对话框 -->
<el-dialog :title="operateMaterial === 'add' ? '新建图文' : '修改图文'" <el-dialog :title="operateMaterial === 'add' ? '新建图文' : '修改图文'"
append-to-body append-to-body width="80%" top="20px" :visible.sync="dialogNewsVisible"
:before-close="dialogNewsClose" :before-close="dialogNewsClose" :close-on-click-modal="false">
:close-on-click-modal="false"
:visible.sync="dialogNewsVisible"
width="80%"
top="20px">
<div class="left"> <div class="left">
<div class="select-item"> <div class="select-item">
<div v-for="(news, index) in articlesAdd" :key='news.id'> <div v-for="(news, index) in articlesAdd" :key='news.id'>
@ -115,12 +113,11 @@ SOFTWARE.
</div> </div>
</div> </div>
<div class="right" v-loading="addMaterialLoading" v-if="articlesAdd.length > 0"> <div class="right" v-loading="addMaterialLoading" v-if="articlesAdd.length > 0">
<!--富文本编辑器组件--> <br /> <br /> <br /> <br />
<el-row> <!-- 标题作者原文地址 -->
<wx-editor v-model="articlesAdd[isActiveAddNews].content" :account-id="this.uploadData.accountId" <el-input v-model="articlesAdd[isActiveAddNews].title" placeholder="请输入标题(必填)" />
v-if="hackResetEditor"/> <el-input v-model="articlesAdd[isActiveAddNews].author" placeholder="请输入作者" style="margin-top: 5px;" />
</el-row> <el-input v-model="articlesAdd[isActiveAddNews].contentSourceUrl" placeholder="请输入原文地址" style="margin-top: 5px;" />
<br><br><br><br>
<!-- 封面和摘要 --> <!-- 封面和摘要 -->
<div class="input-tt">封面和摘要</div> <div class="input-tt">封面和摘要</div>
<div> <div>
@ -137,20 +134,20 @@ SOFTWARE.
<div slot="tip" class="el-upload__tip">支持 bmp/png/jpeg/jpg/gif 格式大小不超过 2M</div> <div slot="tip" class="el-upload__tip">支持 bmp/png/jpeg/jpg/gif 格式大小不超过 2M</div>
</el-upload> </el-upload>
</div> </div>
</div>
<el-dialog title="选择图片" :visible.sync="dialogImageVisible" width="80%" append-to-body> <el-dialog title="选择图片" :visible.sync="dialogImageVisible" width="80%" append-to-body>
<WxMaterialSelect :objData="{repType:'image'}" @selectMaterial="selectMaterial" /> <wx-material-select ref="materialSelect" :objData="{type: 'image', accountId: this.queryParams.accountId}"
@selectMaterial="selectMaterial" />
</el-dialog> </el-dialog>
<el-input :rows="8" type="textarea" v-model="articlesAdd[isActiveAddNews].digest" placeholder="请输入摘要"
class="digest" maxlength="120"></el-input>
</div> </div>
<!-- 标题作者原文地址 --> <el-input :rows="8" type="textarea" v-model="articlesAdd[isActiveAddNews].digest" placeholder="请输入摘要"
<div class="input-tt">标题</div> class="digest" maxlength="120" style="float: right" />
<el-input v-model="articlesAdd[isActiveAddNews].title" placeholder="请输入标题"></el-input> </div>
<div class="input-tt">作者</div> <!--富文本编辑器组件-->
<el-input v-model="articlesAdd[isActiveAddNews].author" placeholder="请输入作者"></el-input> <el-row>
<div class="input-tt">原文地址</div> <wx-editor v-model="articlesAdd[isActiveAddNews].content" :account-id="this.uploadData.accountId"
<el-input v-model="articlesAdd[isActiveAddNews].contentSourceUrl" placeholder="请输入原文地址"></el-input> v-if="hackResetEditor"/>
</el-row>
<!-- 原文地址 -->
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button @click="dialogNewsVisible = false"> </el-button> <el-button @click="dialogNewsVisible = false"> </el-button>
@ -166,7 +163,7 @@ import WxEditor from '@/views/mp/components/wx-editor/WxEditor.vue';
import WxNews from '@/views/mp/components/wx-news/main.vue'; import WxNews from '@/views/mp/components/wx-news/main.vue';
import WxMaterialSelect from '@/views/mp/components/wx-material-select/main.vue' import WxMaterialSelect from '@/views/mp/components/wx-material-select/main.vue'
import { getAccessToken } from '@/utils/auth' import { getAccessToken } from '@/utils/auth'
import { createDraft, getDraftPage } from "@/api/mp/draft"; import {createDraft, getDraftPage, updateDraft} from "@/api/mp/draft";
import { getSimpleAccounts } from "@/api/mp/account"; import { getSimpleAccounts } from "@/api/mp/account";
export default { export default {
@ -192,18 +189,12 @@ export default {
accountId: undefined, accountId: undefined,
}, },
page1: {
total: 0, //
currentPage: 1, //
pageSize: 10 //
},
// ========== ========== // ========== ==========
actionUrl: process.env.VUE_APP_BASE_API + "/admin-api/mp/material/upload-permanent", // actionUrl: process.env.VUE_APP_BASE_API + "/admin-api/mp/material/upload-permanent", //
headers: { Authorization: "Bearer " + getAccessToken() }, // headers: { Authorization: "Bearer " + getAccessToken() }, //
fileList: [], fileList: [],
uploadData: { uploadData: {
"type": 'image', // TODO thumb "type": 'image',
// "accountId": 1, // "accountId": 1,
}, },
@ -213,8 +204,6 @@ export default {
articlesAdd: [], articlesAdd: [],
isActiveAddNews: 0, isActiveAddNews: 0,
dialogImageVisible: false, dialogImageVisible: false,
imageListData: [],
tableLoading1: false,
operateMaterial: 'add', operateMaterial: 'add',
articlesMediaId: '', articlesMediaId: '',
hackResetEditor: false, hackResetEditor: false,
@ -236,6 +225,7 @@ export default {
}) })
}, },
methods: { methods: {
// ======================== ========================
/** 设置账号编号 */ /** 设置账号编号 */
setAccountId(accountId) { setAccountId(accountId) {
this.queryParams.accountId = accountId; this.queryParams.accountId = accountId;
@ -267,6 +257,10 @@ export default {
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.queryParams.pageNo = 1 this.queryParams.pageNo = 1
//
if (this.queryParams.accountId) {
this.setAccountId(this.queryParams.accountId)
}
this.getList() this.getList()
}, },
/** 重置按钮操作 */ /** 重置按钮操作 */
@ -279,62 +273,24 @@ export default {
this.handleQuery() this.handleQuery()
}, },
delMaterial(item){ // ======================== /稿 ========================
this.$confirm('此操作将永久删除该草稿, 是否继续?', '提示', { /** 新增按钮操作 */
confirmButtonText: '确定', handleAdd() {
cancelButtonText: '取消', this.resetEditor();
type: 'warning' this.reset();
}).then(() => { //
this.loading = true this.operateMaterial = 'add'
delObj({ this.dialogNewsVisible = true
id:item.mediaId
}).then(response => {
this.loading = false
if(response.code == 200){
this.getList(this.queryParams)
}else{
this.loading = false
this.$message.error('删除出错:' + response.msg)
}
}).catch(() => {
this.loading = false
})
})
}, },
getPage1(){ /** 更新按钮操作 */
this.tableLoading1 = true handleUpdate(item){
getPage1({ this.resetEditor();
current: this.page1.currentPage, this.reset();
size: this.page1.pageSize, this.articlesMediaId = item.mediaId
type:'image' this.articlesAdd = JSON.parse(JSON.stringify(item.content.newsItem))
}).then(response => { //
this.tableLoading1 = false this.operateMaterial = 'edit'
this.imageListData = response.data.items this.dialogNewsVisible = true
this.page1.total = response.data.totalCount
}).catch(() => {
this.tableLoading1 = false
})
},
openMaterial(){
this.imageListData = null
this.page1.currentPage = 1
this.getPage1()
this.dialogImageVisible = true
},
dialogNewsClose(done){
this.$confirm('修改内容可能还未保存,确定关闭吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.hackResetEditor = false//
this.$nextTick(() => {
this.hackResetEditor = true//
})
this.isActiveAddNews = 0
done()
}).catch(() => {
})
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
@ -347,59 +303,23 @@ export default {
}).finally(() => { }).finally(() => {
this.addMaterialLoading = false this.addMaterialLoading = false
}) })
}
if(this.operateMaterial == 'edit'){
putObj({
articles:this.articlesAdd,
mediaId:this.articlesMediaId
}).then(response => {
this.addMaterialLoading = false
this.dialogNewsVisible = false
if(response.code == 200){
this.isActiveAddNews = 0
this.articlesAdd = [
{
"title": '',
"thumbMediaId": '',
"author": '',
"digest": '',
"showCoverPic": '',
"content": '',
"contentSourceUrl": '',
"needOpenComment":'',
"onlyFansCanComment":'',
"thumbUrl":''
}
]
this.getList(this.queryParams)
} else { } else {
this.$message.error('修改图文出错:' + response.msg) updateDraft(this.queryParams.accountId, this.articlesMediaId, this.articlesAdd).then(response => {
} this.$modal.msgSuccess("更新成功");
}).catch(() => { this.dialogNewsVisible = false;
this.getList()
}).finally(() => {
this.addMaterialLoading = false this.addMaterialLoading = false
}) })
} }
}, },
handleEditNews(item){ //
this.hackResetEditor = false // dialogNewsClose(done) {
this.$nextTick(() => { this.$modal.confirm('修改内容可能还未保存,确定关闭吗?').then(() => {
this.hackResetEditor = true // this.reset()
}) this.resetEditor()
if (this.operateMaterial == 'add') { done()
this.isActiveAddNews = 0 }).catch(() => {})
}
this.operateMaterial = 'edit'
this.articlesAdd = JSON.parse(JSON.stringify(item.content.newsItem))
this.articlesMediaId = item.mediaId
this.dialogNewsVisible = true
},
/** 新增按钮操作 */
handleAdd() {
this.resetEditor();
this.reset();
//
this.operateMaterial = 'add'
this.dialogNewsVisible = true
}, },
// //
reset() { reset() {
@ -498,11 +418,20 @@ export default {
this.articlesAdd[this.isActiveAddNews].thumbMediaId = response.data.mediaId this.articlesAdd[this.isActiveAddNews].thumbMediaId = response.data.mediaId
this.articlesAdd[this.isActiveAddNews].thumbUrl = response.data.url this.articlesAdd[this.isActiveAddNews].thumbUrl = response.data.url
}, },
// or 稿
selectMaterial(item) { selectMaterial(item) {
this.dialogImageVisible = false this.dialogImageVisible = false
this.articlesAdd[this.isActiveAddNews].thumbMediaId = item.mediaId this.articlesAdd[this.isActiveAddNews].thumbMediaId = item.mediaId
this.articlesAdd[this.isActiveAddNews].thumbUrl = item.url this.articlesAdd[this.isActiveAddNews].thumbUrl = item.url
}, },
//
openMaterial() {
this.dialogImageVisible = true
try {
this.$refs['materialSelect'].queryParams.accountId = this.queryParams.accountId // accountId
this.$refs['materialSelect'].handleQuery(); //
} catch (e) {}
},
// ======================== 稿 ======================== // ======================== 稿 ========================
handlePublishNews(item){ handlePublishNews(item){
@ -521,7 +450,29 @@ export default {
}) })
}).catch(() => { }).catch(() => {
}) })
},
delMaterial(item){
this.$confirm('此操作将永久删除该草稿, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.loading = true
delObj({
id:item.mediaId
}).then(response => {
this.loading = false
if(response.code == 200){
this.getList(this.queryParams)
}else{
this.loading = false
this.$message.error('删除出错:' + response.msg)
} }
}).catch(() => {
this.loading = false
})
})
},
} }
} }
</script> </script>