提交 abc2055b authored 作者: pengxiaohui's avatar pengxiaohui

feat: 调试案例管理和类型管理页接口

上级 c7fe2466
VITE_LOGIN_URL=https://login.ezijing.com/auth/login/index VITE_LOGIN_URL=https://login2.ezijing.com/auth/login/index
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
}, },
"dependencies": { "dependencies": {
"axios": "^0.23.0", "axios": "^0.23.0",
"blueimp-md5": "^2.18.0",
"vuedraggable": "^2.24.3",
"element-ui": "^2.15.6", "element-ui": "^2.15.6",
"query-string": "^7.0.1", "query-string": "^7.0.1",
"vue": "^2.6.14", "vue": "^2.6.14",
......
...@@ -88,3 +88,34 @@ textarea:focus { ...@@ -88,3 +88,34 @@ textarea:focus {
:root { :root {
--main-color: #3276fc; --main-color: #3276fc;
} }
/* element-ui input,textarea font-family reset */
.el-input__inner, .el-textarea__inner{
font-family: 'PingFang SC', 'PingFangSC-Regular', 'Source Han Sans CN', -apple-system, 'Microsoft YaHei', 'Helvetica', 'Arial', Verdana,
'Hiragino Sans GB', 'Wenquanyi Micro Hei', sans-serif;
}
/* element-ui drawer reset */
.el-drawer__header{
padding:14px 16px !important;
margin-bottom:0 !important;
border-bottom:1px solid #DCDFE6;
}
.el-drawer__header>h5{
font-size:16px;
color:#666;
font-weight:600;
}
.el-drawer__body{
height:calc(100% - 82px);
overflow-y: auto;
}
/* element-ui dialog reset */
.el-dialog .el-dialog__header{
padding:20px 16px 10px;
}
.el-dialog .el-dialog__body{
padding:10px 20px;
}
.el-dialog__footer{
text-align: center;
}
\ No newline at end of file
...@@ -25,7 +25,7 @@ export default { ...@@ -25,7 +25,7 @@ export default {
return { return {
menuList: [ menuList: [
{ name: '案例管理', path: '/case', icon: 'el-icon-files' }, { name: '案例管理', path: '/case', icon: 'el-icon-files' },
{ name: '类型管理', path: '/type', icon: 'el-icon-coin' } { name: '类型管理', path: '/category', icon: 'el-icon-coin' }
] ]
} }
}, },
......
...@@ -6,3 +6,27 @@ import httpRequest from '@/utils/axios' ...@@ -6,3 +6,27 @@ import httpRequest from '@/utils/axios'
export function getCaseList(params) { export function getCaseList(params) {
return httpRequest.get('/api/xtraining/admin/v1/cases', { params }) return httpRequest.get('/api/xtraining/admin/v1/cases', { params })
} }
/**
* 获取类型列表
*/
export function getCategoryList(params) {
return httpRequest.get('/api/xtraining/admin/v1/categories', { params })
}
/**
* 新建案例
*/
export function createCase(data) {
return httpRequest.post('/api/xtraining/admin/v1/case', data)
}
/**
* 更新案例
*/
export function updateCase(id, data) {
return httpRequest.put(`/api/xtraining/admin/v1/case/${id}`, data)
}
/**
* 删除案例
*/
export function deleteCase(id) {
return httpRequest.delete(`/api/xtraining/admin/v1/case/${id}`)
}
\ No newline at end of file
<template>
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="120px">
<el-form-item label="案例名称" prop="name">
<el-input v-model="form.name" size="small" placeholder="请输入案例名称"/>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio :label="1">基金</el-radio>
<!-- <el-radio :label="2">股票</el-radio>
<el-radio :label="3">保险</el-radio> -->
</el-radio-group>
</el-form-item>
<el-form-item label="唯一标识" prop="tag">
<el-input v-model="form.tag" size="small" placeholder="请输入唯一标识"/>
</el-form-item>
<el-form-item label="分类" prop="category_id">
<el-select v-model="form.category_id" placeholder="请选择分类" size="small" style="width:100%;">
<el-option v-for="item in categoryOptions" :label="item.name" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="案例文档" ref="el-form-item-upload" prop=
"pdf_uris">
<el-upload
class="upload-pdf"
action="https://webapp-pub.oss-cn-beijing.aliyuncs.com"
:file-list="form.pdf_uris"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:on-remove="handleRemove"
:data="uploadData"
:limit="10">
<el-button size="small" type="primary">点击上传</el-button>
<!-- <div slot="tip" class="el-upload__tip">只能上传pdf文件</div> -->
</el-upload>
</el-form-item>
<el-form-item label="排序码" prop="order">
<el-input-number v-model="form.order" :min="1" :max="100" label="排序码,越大越靠前
"></el-input-number>
</el-form-item>
<el-form-item>
<el-button size="mini" @click="$emit('dialogClose')">取消</el-button>
<el-button type="primary" @click="handleSubmit" size="mini">提交</el-button>
</el-form-item>
</el-form>
</template>
<script>
// api
import { getSignature } from '@/api/base'
import { createCase, getCategoryList, updateCase } from '../api'
import md5 from 'blueimp-md5'
const splitStrLast = function(str, split) {
const fileNameArr = str.split(split)
const last = fileNameArr[fileNameArr.length - 1]
return last
}
export default {
props: {
options: {
type: Object,
default() {
return {}
}
}
},
components: {},
data() {
const uploadValid = (rule, value, callback) => {
if (value && value.length === 0) {
callback(new Error('请上传案件文档'))
} else {
callback()
}
}
return {
form: {},
rules: {
name: { required: true, message: '请输入案例名称', trigger: 'blur' },
type: { required: true, message: '请选择类型', trigger: 'change' },
tag: { required: true, message: '请输入唯一标识', trigger: 'blur' },
category_id: { required: true, message: '请选择分类', trigger: 'change' },
pdf_uris: { required: true, validator: uploadValid, trigger: 'change' }
},
categoryOptions: [],
uploadData: {}
}
},
created() {
this.form = {
name: '',
type: 1,
tag: '',
category_id: '',
pdf_uris: [],
order: 1
}
if (this.options.type === 'edit' && this.options.data.id) {
Object.keys(this.form).forEach(key => {
if (this.options.data[key]) {
if (key === 'pdf_uris') {
this.form[key] = this.options.data[key].map(it => {
return {
name: splitStrLast(it, '/'),
url: it
}
})
}
else this.form[key] = this.options.data[key]
}
})
}
this.fetchCategoryList()
},
methods: {
handleSubmit() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
if (this.options.type === 'create') this.fetchCreateCase()
else this.fetchUpdateCase()
}
})
},
beforeUpload(file) {
const suffix = splitStrLast(file.name, '.')
if (suffix !== 'pdf') {
// this.$message.error('只允许上传pdf格式的文件')
// return false
}
const fileName = file.name
const key = 'upload/xtrainning/' + md5(fileName + new Date().getTime()) + fileName.substr(fileName.lastIndexOf('.'))
return new Promise((resolve, reject) => {
getSignature()
.then(response => {
const { accessid, policy, signature, host } = response
this.uploadData = { key, OSSAccessKeyId: accessid, policy, signature, success_action_status: '200' }
file.src = `${host}/${key}`
resolve(true)
})
.catch(err => {
console.log(err)
reject(err)
})
})
},
handleSuccess(response, file, fileList) {
this.form.pdf_uris.push({
name: file.raw.name,
url: file.raw.src,
size: file.raw.size
})
this.$refs['el-form-item-upload'].$emit('el.form.change')
},
handleRemove(file, fileList) {
this.form.pdf_uris.forEach((item, index) => {
if (item.uid === file.uid && item.url === file.url) {
this.form.pdf_uris.splice(index, 1)
}
})
console.log(this.form.pdf_uris)
},
fetchCreateCase() {
const params = Object.assign({}, this.form)
params.pdf_uris = this.form.pdf_uris.map(item => item.url)
createCase(params).then(res => {
if (res.data && res.data.id) {
this.$message.success('新建案例成功')
this.$emit('submit')
}
})
},
fetchUpdateCase() {
const params = Object.assign({}, this.form)
params.pdf_uris = this.form.pdf_uris.map(item => item.url)
updateCase(this.options.data.id, params).then(res => {
if (res.data && res.data.status) {
this.$message.success('更新案例成功')
this.$emit('submit')
}
})
},
fetchCategoryList() {
getCategoryList({ page: 1, limit: 100 }).then(res => {
this.categoryOptions = res.data.data
})
}
}
}
</script>
<style scoped>
.el-form{
padding:20px 20px 10px 10px
}
</style>
...@@ -2,24 +2,36 @@ ...@@ -2,24 +2,36 @@
<app-card> <app-card>
<app-list v-bind="tableOptions" ref="list"> <app-list v-bind="tableOptions" ref="list">
<template #header-aside> <template #header-aside>
<el-button type="primary">新增</el-button> <el-button type="primary" @click="handleCreate">新建</el-button>
</template> </template>
<template v-slot:table-x="{ row }"> <template v-slot:table-x="{ row }">
<el-button plain>查看</el-button> <el-button plain>查看</el-button>
<el-button type="primary" plain>编辑</el-button> <el-button type="primary" plain @click="handleEdit(row)">编辑</el-button>
<el-button type="danger" plain @click="onRemove(row)">删除</el-button> <el-button type="danger" plain @click="handleRemove(row)">删除</el-button>
</template> </template>
</app-list> </app-list>
<el-drawer :title="formData.type === 'create' ? '新建案例':'编辑案例'" :visible.sync="drawerVisible" :close-on-click-modal="false" :destroy-on-close="true" size="600px" top="15px" @close="handleClose">
<case-form :options="formData" @submit="handleSubmit" />
</el-drawer>
</app-card> </app-card>
</template> </template>
<script> <script>
// 组件
import CaseForm from '../components/CaseForm.vue'
// 接口 // 接口
import { getCaseList } from '../api' import { getCaseList, deleteCase } from '../api'
export default { export default {
components: { CaseForm },
data() { data() {
return {} return {
drawerVisible: false,
formData: {
type: 'create',
data: {}
}
}
}, },
computed: { computed: {
// 列表配置 // 列表配置
...@@ -36,6 +48,8 @@ export default { ...@@ -36,6 +48,8 @@ export default {
columns: [ columns: [
{ label: 'ID', prop: 'id' }, { label: 'ID', prop: 'id' },
{ label: '名称', prop: 'name' }, { label: '名称', prop: 'name' },
{ label: '唯一标识', prop: 'tag' },
{ label: '创建时间', prop: 'created_at' },
{ label: '操作', slots: 'table-x', align: 'right', width: 220 } { label: '操作', slots: 'table-x', align: 'right', width: 220 }
], ],
data: [ data: [
...@@ -64,24 +78,39 @@ export default { ...@@ -64,24 +78,39 @@ export default {
} }
}, },
methods: { methods: {
// 编辑 handleCreate() {
handleUpdate(row) { this.drawerVisible = true
this.$router.push({ name: 'goodsEdit', params: { id: row.spu_id } }) this.formData.type = 'create'
this.formData.data = {}
},
handleEdit(item) {
this.drawerVisible = true
this.formData.type = 'edit'
this.formData.data = item
},
handleClose() {},
handleSubmit() {
this.drawerVisible = false
this.$refs.list.refetch(true)
}, },
// 删除 // 删除
onRemove() { handleRemove(item) {
this.$confirm('商品删除请谨慎操作,确定删除?', '删除商品', { this.$confirm('案例删除请谨慎操作,确定删除?', '删除案例', {
confirmButtonText: '删除', confirmButtonText: '删除',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(this.handleRemove) }).then(() => {
this.fetchRemoveCase(item)
}).catch(() => {})
}, },
// 删除 // 删除
handleRemove() { fetchRemoveCase(item) {
// const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id })) deleteCase(item.id).then(res => {
// deleteGoods({ shop_id: this.shopId, data }).then(res => { if (res.data && res.data.status) {
// this.$refs.list.refetch(true) this.$message.success('删除案例成功')
// }) this.$refs.list.refetch(true)
}
})
} }
} }
} }
......
import httpRequest from '@/utils/axios'
/**
* 获取类型列表
*/
export function getCategoryList(params) {
return httpRequest.get('/api/xtraining/admin/v1/categories', { params })
}
/**
* 新建分类
*/
export function createCategory(data) {
return httpRequest.post('/api/xtraining/admin/v1/category', data)
}
/**
* 更新分类
*/
export function updateCategory(id, data) {
return httpRequest.put(`/api/xtraining/admin/v1/category/${id}`, data)
}
/**
* 删除分类
*/
export function deleteCategory(id) {
return httpRequest.delete(`/api/xtraining/admin/v1/category/${id}`)
}
<template>
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="120px">
<el-form-item label="分类名称" prop="name">
<el-input v-model="form.name" size="small" placeholder="请输入分类名称"/>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio :label="1">基金</el-radio>
<!-- <el-radio :label="2">股票</el-radio>
<el-radio :label="3">保险</el-radio> -->
</el-radio-group>
</el-form-item>
<el-form-item label="唯一标识" prop="tag">
<el-input v-model="form.tag" size="small" placeholder="请输入唯一标识"/>
</el-form-item>
<el-form-item label="排序码" prop="order">
<el-input-number v-model="form.order" :min="1" :max="100" label="排序码,越大越靠前
"></el-input-number>
</el-form-item>
<el-form-item>
<el-button size="mini" @click="$emit('dialogClose')">取消</el-button>
<el-button type="primary" @click="handleSubmit" size="mini">提交</el-button>
</el-form-item>
</el-form>
</template>
<script>
// api
import { createCategory, updateCategory } from '../api'
export default {
props: {
options: {
type: Object,
default() {
return {}
}
}
},
components: {},
data() {
return {
form: {},
rules: {
name: { required: true, message: '请输入分类名称', trigger: 'blur' },
type: { required: true, message: '请选择类型', trigger: 'change' },
tag: { required: true, message: '请输入唯一标识', trigger: 'blur' }
}
}
},
created() {
this.form = {
name: '',
type: 1,
tag: '',
order: 1
}
if (this.options.type === 'edit' && this.options.data.id) {
console.log(this.options.data)
Object.keys(this.form).forEach(key => {
if (this.options.data[key]) {
this.form[key] = this.options.data[key]
}
})
}
this.fetchTypeList()
},
methods: {
handleSubmit() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
if (this.options.type === 'create') this.fetchCreateCategory()
else this.fetchUpdateCategory()
}
})
},
fetchCreateCategory() {
createCategory(this.form).then(res => {
if (res.data && res.data.id) {
this.$message.success('新建分类成功')
this.$emit('submit')
}
})
},
fetchUpdateCategory() {
updateCategory(this.options.data.id, this.form).then(res => {
if (res.data && res.data.status) {
this.$message.success('更新分类成功')
this.$emit('submit')
}
})
},
fetchTypeList() {
getTypeList({ page: 1, limit: 100 }).then(res => {
this.categoryOptions = res.data.data
})
}
}
}
</script>
<style scoped>
.el-form{
padding:20px 20px 10px 10px
}
</style>
...@@ -2,7 +2,7 @@ import AppLayout from '@/components/layout/Index.vue' ...@@ -2,7 +2,7 @@ import AppLayout from '@/components/layout/Index.vue'
const routes = [ const routes = [
{ {
path: '/type', path: '/category',
component: AppLayout, component: AppLayout,
children: [{ path: '', component: () => import('./views/List.vue') }] children: [{ path: '', component: () => import('./views/List.vue') }]
} }
......
...@@ -2,31 +2,43 @@ ...@@ -2,31 +2,43 @@
<app-card> <app-card>
<app-list v-bind="tableOptions" ref="list"> <app-list v-bind="tableOptions" ref="list">
<template #header-aside> <template #header-aside>
<el-button type="primary">新增</el-button> <el-button type="primary" @click="handleCreate">新增</el-button>
</template> </template>
<template v-slot:table-x="{ row }"> <template v-slot:table-x="{ row }">
<el-button plain>查看</el-button> <el-button plain>查看</el-button>
<el-button type="primary" plain>编辑</el-button> <el-button type="primary" plain @click="handleEdit(row)">编辑</el-button>
<el-button type="danger" plain @click="onRemove(row)">删除</el-button> <el-button type="danger" plain @click="handleRemove(row)">删除</el-button>
</template> </template>
</app-list> </app-list>
<el-drawer :title="formData.type === 'create' ? '新建分类':'编辑分类'" :visible.sync="drawerVisible" :close-on-click-modal="false" :destroy-on-close="true" size="600px" top="15px" @close="handleClose">
<category-form :options="formData" @submit="handleSubmit" />
</el-drawer>
</app-card> </app-card>
</template> </template>
<script> <script>
// 组件
import CategoryForm from '../components/CategoryForm.vue'
// 接口 // 接口
import { getTypeList } from '../api' import { getCategoryList, deleteCategory } from '../api'
export default { export default {
components: { CategoryForm },
data() { data() {
return {} return {
drawerVisible: false,
formData: {
type: 'create',
data: {}
}
}
}, },
computed: { computed: {
// 列表配置 // 列表配置
tableOptions() { tableOptions() {
return { return {
remote: { remote: {
httpRequest: getTypeList, httpRequest: getCategoryList,
params: { name: '', tag: '' } params: { name: '', tag: '' }
}, },
filters: [ filters: [
...@@ -36,52 +48,47 @@ export default { ...@@ -36,52 +48,47 @@ export default {
columns: [ columns: [
{ label: 'ID', prop: 'id' }, { label: 'ID', prop: 'id' },
{ label: '名称', prop: 'name' }, { label: '名称', prop: 'name' },
{ label: '唯一标识', prop: 'tag' },
{ label: '创建时间', prop: 'created_at' },
{ label: '操作', slots: 'table-x', align: 'right', width: 220 } { label: '操作', slots: 'table-x', align: 'right', width: 220 }
],
data: [
{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
},
{
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
},
{
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
},
{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}
] ]
} }
} }
}, },
methods: { methods: {
// 编辑 handleCreate() {
handleUpdate(row) { this.drawerVisible = true
this.$router.push({ name: 'goodsEdit', params: { id: row.spu_id } }) this.formData.type = 'create'
this.formData.data = {}
},
handleEdit(item) {
this.drawerVisible = true
this.formData.type = 'edit'
this.formData.data = item
},
handleClose() {},
handleSubmit() {
this.drawerVisible = false
this.$refs.list.refetch(true)
}, },
// 删除 // 删除提示
onRemove() { handleRemove(item) {
this.$confirm('商品删除请谨慎操作,确定删除?', '删除商品', { this.$confirm('案例删除请谨慎操作,确定删除?', '删除案例', {
confirmButtonText: '删除', confirmButtonText: '删除',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(this.handleRemove) }).then(() => {
this.fetchRemoveCase(item)
}).catch(() => {})
}, },
// 删除 // 执行删除请求
handleRemove() { fetchRemoveCase(item) {
// const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id })) deleteCategory(item.id).then(res => {
// deleteGoods({ shop_id: this.shopId, data }).then(res => { if (res.data && res.data.status) {
// this.$refs.list.refetch(true) this.$message.success('删除分类成功')
// }) this.$refs.list.refetch(true)
}
})
} }
} }
} }
......
import httpRequest from '@/utils/axios'
/**
* 获取类型列表
*/
export function getTypeList(params) {
return httpRequest.get('/api/xtraining/admin/v1/categories', { params })
}
...@@ -48,7 +48,7 @@ httpRequest.interceptors.response.use( ...@@ -48,7 +48,7 @@ httpRequest.interceptors.response.use(
function (response) { function (response) {
const { data } = response const { data } = response
// 正常返回 // 正常返回
if (data.code === 0) { if (data.code === 0 || data.host === 'https://webapp-pub.ezijing.com') {
return data return data
} }
// 未登录 // 未登录
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论