咨询资料分享

This commit is contained in:
shilixia 2021-12-13 10:48:19 +08:00
parent 25091d49fe
commit 7bdd1a6c8a
26 changed files with 1597 additions and 4 deletions

View File

@ -3,8 +3,8 @@ ENV = 'development'
# base api
#VUE_APP_BASE_API = 'http://10.0.11.127:8000/api'
#VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'
VUE_APP_BASE_API = 'https://testsearch.ctc.ac.cn/api'
VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'
#VUE_APP_BASE_API = 'https://testsearch.ctc.ac.cn/api'
#VUE_APP_BASE_API = 'http://47.95.0.242:9101/api'

View File

@ -17,6 +17,7 @@
"dependencies": {
"@riophae/vue-treeselect": "^0.4.0",
"axios": "0.18.1",
"element-china-area-data": "^5.0.2",
"element-ui": "2.13.0",
"file-saver": "^2.0.2",
"js-cookie": "2.2.0",

View File

@ -0,0 +1,31 @@
import request from '@/utils/request'
export function createRegulatory(data) {
return request({
url: '/consulting/regulatory/',
method: 'post',
data
})
}
export function getRegulatoryList(query) {
return request({
url: '/consulting/regulatory/',
method: 'get',
params: query
})
}
export function deleteRegulatory(id) {
return request({
url: `/consulting/regulatory/${id}/`,
method: 'delete'
})
}
export function updateRegulatory(id, data) {
return request({
url: `/consulting/regulatory/${id}/`,
method: 'put',
data
})
}

31
client/src/api/policy.js Normal file
View File

@ -0,0 +1,31 @@
import request from '@/utils/request'
export function createPolicy(data) {
return request({
url: '/consulting/policy/',
method: 'post',
data
})
}
export function getPolicyList(query) {
return request({
url: '/consulting/policy/',
method: 'get',
params: query
})
}
export function deletePolicy(id) {
return request({
url: `/consulting/policy/${id}/`,
method: 'delete'
})
}
export function updatePolicy(id, data) {
return request({
url: `/consulting/policy/${id}/`,
method: 'put',
data
})
}

View File

@ -0,0 +1,31 @@
import request from '@/utils/request'
export function createProfessional(data) {
return request({
url: '/consulting/professional/',
method: 'post',
data
})
}
export function getProfessionalList(query) {
return request({
url: '/consulting/professional/',
method: 'get',
params: query
})
}
export function deleteProfessional(id) {
return request({
url: `/consulting/professional/${id}/`,
method: 'delete'
})
}
export function updateProfessional(id, data) {
return request({
url: `/consulting/professional/${id}/`,
method: 'put',
data
})
}

View File

@ -0,0 +1,31 @@
import request from '@/utils/request'
export function createValidation(data) {
return request({
url: '/consulting/validation/',
method: 'post',
data
})
}
export function getValidationList(query) {
return request({
url: '/consulting/validation/',
method: 'get',
params: query
})
}
export function deleteValidation(id) {
return request({
url: `/consulting/validation/${id}/`,
method: 'delete'
})
}
export function updateValidation(id, data) {
return request({
url: `/consulting/validation/${id}/`,
method: 'put',
data
})
}

View File

@ -136,6 +136,38 @@ export const asyncRoutes = [
},
]
}
,
{
path: '/consulting',
component: Layout,
redirect: '/consulting/',
name: 'consulting',
meta: { title: '咨询资料分享', icon: 'guide', perms: ['regulatory_views'] },
alwaysShow: true,
children: [
{
path: 'regulatory',
name: 'regulatory',
component: () => import('@/views/consulting/regulatory.vue'),
meta: { title: '监管信息', perms: ['regulatory_view'] }
}, {
path: 'professional',
name: 'professional',
component: () => import('@/views/consulting/professional.vue'),
meta: { title: '专业领域要求', perms: ['professional_view'] }
}, {
path: 'policy',
name: 'policy',
component: () => import('@/views/consulting/policy.vue'),
meta: { title: '政策咨询', perms: ['policy_view'] }
}, {
path: 'validation',
name: 'validation',
component: () => import('@/views/consulting/validation.vue'),
meta: { title: '能力验证', perms: ['validation_view'] }
},
]
},
{
path: '/supervision',

View File

@ -0,0 +1,269 @@
<template>
<div class="app-container">
<el-card>
<el-button type="primary" icon="el-icon-plus" @click="handleAddContent" v-if="checkPermission(['policy_create'])"
>新增</el-button
>
</el-card>
<el-card style="margin-top: 10px">
<el-table
v-loading="listLoading"
:data="contentList.results"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column align="center" label="文件下载">
<template slot-scope="scope" v-if="scope.row.file_.file">
<el-link :href="scope.row.file_.file" type="primary">{{ scope.row.file_.name }}</el-link>
</template>
</el-table-column>
<el-table-column label="文件描述" >
<template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="200px"
fixed="right"
>
<template slot-scope="scope">
<el-button
:disabled="!checkPermission(['policy_update'])"
type="primary"
size="small"
icon="el-icon-edit"
@click="handleEdit(scope)"
/>
<el-button
:disabled="!checkPermission(['policy_delete'])"
type="danger"
size="small"
icon="el-icon-delete"
@click="handleDelete(scope)"
/>
</template>
</el-table-column>
</el-table>
<pagination
v-show="contentList.count > 0"
:total="contentList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑政策咨询' : '新增政策咨询'"
>
<el-form
ref="Form"
:model="Content"
label-width="80px"
label-position="right"
:rules="rule1"
>
<el-form-item label="名称" prop="name">
<el-input v-model="Content.name" placeholder="文档名称" />
</el-form-item>
<el-form-item label="文档描述" prop="description">
<el-input
type="textarea"
:rows="4"
v-model="Content.description"
placeholder="文档描述"
/>
</el-form-item>
<el-form-item label="文档上传" prop="file" v-if="dialogVisible">
<el-upload
ref="upload"
:action="upUrl"
:on-preview="handlePreview"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf"
>
<el-button size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getPolicyList,
createPolicy,
deletePolicy,
updatePolicy,
} from "@/api/policy";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { upUrl, upHeaders } from "@/api/file";
const defaultContent = {
name: "",
description: "",
file:null
};
export default {
components: { Pagination, Treeselect },
data() {
return {
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList:[],
Content: defaultContent,
dialogVisible: false,
listQuery: {
page: 1,
page_size: 20,
},
contentList: {
count:0
},
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
};
},
computed: {},
watch: {
filterOrgText(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.getList();
},
methods: {
handlePreview(file) {
if ("url" in file) {
window.open(file.url);
} else {
window.open(file.response.data.path);
}
},
handleUpSuccess(res, file, filelist) {
this.Content.file = res.data.id;
},
handleRemove(file, filelist){
this.Content.file = null;
},
checkPermission,
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
getList() {
getPolicyList(this.listQuery).then((response) => {
if (response.data) {
this.contentList = response.data;
}
});
},
handleAddContent() {
this.Content = Object.assign({}, defaultContent);
this.dialogType = "new";
this.dialogVisible = true;
this.fileList=[]
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.Content = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
if (this.Content.file) {
this.fileList = [
{
name:this.Content.file_.name,
url: this.Content.file,
},
];
}
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deletePolicy(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
console.log(this.Content)
updatePolicy(this.Content.id, this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("编辑成功");
}
});
} else {
createPolicy(this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("新建成功");
}
});
}
} else {
return false;
}
});
},
},
};
</script>

View File

@ -0,0 +1,270 @@
<template>
<div class="app-container">
<el-card>
<el-button type="primary" icon="el-icon-plus" @click="handleAddContent" v-if="checkPermission(['professional_create'])"
>新增</el-button
>
</el-card>
<el-card style="margin-top: 10px">
<el-table
v-loading="listLoading"
:data="contentList.results"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column align="center" label="文件下载">
<template slot-scope="scope" v-if="scope.row.file_.file">
<el-link :href="scope.row.file_.file" type="primary">{{ scope.row.file_.name }}</el-link>
</template>
</el-table-column>
<el-table-column label="文件描述" >
<template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="200px"
fixed="right"
>
<template slot-scope="scope">
<el-button
:disabled="!checkPermission(['professional_update'])"
type="primary"
size="small"
icon="el-icon-edit"
@click="handleEdit(scope)"
/>
<el-button
:disabled="!checkPermission(['professional_delete'])"
type="danger"
size="small"
icon="el-icon-delete"
@click="handleDelete(scope)"
/>
</template>
</el-table-column>
</el-table>
<pagination
v-show="contentList.count > 0"
:total="contentList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑专业领域要求' : '新增专业领域要求'"
>
<el-form
ref="Form"
:model="Content"
label-width="80px"
label-position="right"
:rules="rule1"
>
<el-form-item label="名称" prop="name">
<el-input v-model="Content.name" placeholder="文档名称" />
</el-form-item>
<el-form-item label="文档描述" prop="description">
<el-input
type="textarea"
:rows="4"
v-model="Content.description"
placeholder="文档描述"
/>
</el-form-item>
<el-form-item label="文档上传" prop="file" v-if="dialogVisible">
<el-upload
ref="upload"
:action="upUrl"
:on-preview="handlePreview"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf"
>
<el-button size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getProfessionalList,
createProfessional,
deleteProfessional,
updateProfessional,
} from "@/api/professional";
import { genTree } from "@/utils";
import {provinceAndCityData,CodeToText} from "element-china-area-data";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { upUrl, upHeaders } from "@/api/file";
const defaultContent = {
name: "",
description: "",
file:null
};
export default {
components: { Pagination, Treeselect },
data() {
return {
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList:[],
Content: defaultContent,
dialogVisible: false,
listQuery: {
page: 1,
page_size: 20,
},
contentList: {
count:0
},
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
};
},
computed: {},
watch: {
filterOrgText(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.getList();
},
methods: {
handlePreview(file) {
if ("url" in file) {
window.open(file.url);
} else {
window.open(file.response.data.path);
}
},
handleUpSuccess(res, file, filelist) {
this.Content.file = res.data.id;
},
handleRemove(file, filelist){
this.Content.file = null;
},
checkPermission,
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
getList() {
getProfessionalList(this.listQuery).then((response) => {
if (response.data) {
this.contentList = response.data;
}
});
},
handleAddContent() {
this.Content = Object.assign({}, defaultContent);
this.dialogType = "new";
this.dialogVisible = true;
this.fileList=[]
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.Content = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
if (this.Content.file) {
this.fileList = [
{
name:this.Content.file_.name,
url: this.Content.file,
},
];
}
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteProfessional(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
console.log(this.Content)
updateProfessional(this.Content.id, this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("编辑成功");
}
});
} else {
createProfessional(this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("新建成功");
}
});
}
} else {
return false;
}
});
},
},
};
</script>

View File

@ -0,0 +1,325 @@
<template>
<div class="app-container">
<el-card>
<el-row :gutter="6">
<el-col :xs="12" :md="2">
<el-button type="primary" icon="el-icon-plus" @click="handleAddContent" v-if="checkPermission(['regulatory_create'])"
>新增</el-button
>
</el-col>
<el-col :xs="12" :md="4">
<el-select
v-model="listQuery.provinces"
placeholder="省份"
@change="handleFilter2"
clearable
style="width: 100%"
>
<el-option
v-for="item in options"
:key="item.label"
:label="item.label"
:value="item.label">
</el-option>
</el-select>
</el-col>
</el-row>
</el-card>
<el-card style="margin-top: 10px">
<el-table
v-loading="listLoading"
:data="contentList.results"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="文件类型" :filters="[{ text: '通知', value: 1 }, { text: '结果', value: 2 }]"
:filter-method="filterTag">
<template slot-scope="scope">
{{ type_[scope.row.type] }}</template>
</el-table-column>
<el-table-column label="省份">
<template slot-scope="scope">{{ scope.row.provinces }}</template>
</el-table-column>
<el-table-column align="center" label="文件下载">
<template slot-scope="scope" v-if="scope.row.file_.file">
<el-link :href="scope.row.file_.file" type="primary">{{ scope.row.file_.name }}</el-link>
</template>
</el-table-column>
<el-table-column label="文件描述" >
<template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="200px"
fixed="right"
>
<template slot-scope="scope">
<el-button
:disabled="!checkPermission(['regulatory_update'])"
type="primary"
size="small"
icon="el-icon-edit"
@click="handleEdit(scope)"
/>
<el-button
:disabled="!checkPermission(['regulatory_delete'])"
type="danger"
size="small"
icon="el-icon-delete"
@click="handleDelete(scope)"
/>
</template>
</el-table-column>
</el-table>
<pagination
v-show="contentList.count > 0"
:total="contentList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑监管信息' : '新增监管信息'"
>
<el-form
ref="Form"
:model="Content"
label-width="80px"
label-position="right"
:rules="rule1"
>
<el-form-item label="名称" prop="name">
<el-input v-model="Content.name" placeholder="文档名称" />
</el-form-item>
<el-form-item label="资料分类" prop="type">
<el-radio-group v-model="Content.type">
<el-radio :label="1">通知</el-radio>
<el-radio :label="2">结果</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="省份" prop="provinces">
<el-select v-model="Content.provinces" filterable placeholder="请选择">
<el-option
v-for="item in options"
:key="item.label"
:label="item.label"
:value="item.label">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="文档描述" prop="description">
<el-input
type="textarea"
:rows="4"
v-model="Content.description"
placeholder="文档描述"
/>
</el-form-item>
<el-form-item label="文档上传" prop="file" v-if="dialogVisible">
<el-upload
ref="upload"
:action="upUrl"
:on-preview="handlePreview"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf"
>
<el-button size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getRegulatoryList,
createRegulatory,
deleteRegulatory,
updateRegulatory,
} from "@/api/consulting";
import { genTree } from "@/utils";
import {provinceAndCityData,CodeToText} from "element-china-area-data";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { upUrl, upHeaders } from "@/api/file";
const defaultContent = {
name: "",
description: "",
file:null
};
export default {
components: { Pagination, Treeselect },
data() {
return {
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList:[],
Content: defaultContent,
typeOptions: [],
listLoading: true,
dialogVisible: false,
listQuery: {
page: 1,
page_size: 20,
},
contentList: {
count:0
},
type_:{1:"通知",2:"结果"},
dialogType: "new",
options:provinceAndCityData,
rule1: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
filterOrgText: "",
treeLoding: false,
};
},
computed: {},
watch: {
filterOrgText(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.getList();
},
methods: {
handlePreview(file) {
if ("url" in file) {
window.open(file.url);
} else {
window.open(file.response.data.path);
}
},
handleUpSuccess(res, file, filelist) {
this.Content.file = res.data.id;
},
handleRemove(file, filelist){
this.Content.file = null;
},
checkPermission,
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
filterTag(value, row) {
return row.type === value;
},
getList() {
this.listLoading = true;
getRegulatoryList(this.listQuery).then((response) => {
if (response.data) {
this.contentList = response.data;
}
this.listLoading = false;
});
},
handleFilter2() {
this.listQuery.page = 1;
this.getList();
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
handleAddContent() {
this.Content = Object.assign({}, defaultContent);
this.dialogType = "new";
this.dialogVisible = true;
this.fileList=[]
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.Content = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
if (this.Content.file) {
this.fileList = [
{
name:this.Content.file_.name,
url: this.Content.file,
},
];
}
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteRegulatory(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
console.log(this.Content)
updateRegulatory(this.Content.id, this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("编辑成功");
}
});
} else {
createRegulatory(this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("新建成功");
}
});
}
} else {
return false;
}
});
},
},
};
</script>

View File

@ -0,0 +1,270 @@
<template>
<div class="app-container">
<el-card>
<el-button type="primary" icon="el-icon-plus" @click="handleAddContent" v-if="checkPermission(['validation_create'])"
>新增</el-button
>
</el-card>
<el-card style="margin-top: 10px">
<el-table
v-loading="listLoading"
:data="contentList.results"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column align="center" label="文件下载">
<template slot-scope="scope" v-if="scope.row.file_.file">
<el-link :href="scope.row.file_.file" type="primary">{{ scope.row.file_.name }}</el-link>
</template>
</el-table-column>
<el-table-column label="文件描述" >
<template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="200px"
fixed="right"
>
<template slot-scope="scope">
<el-button
:disabled="!checkPermission(['validation_update'])"
type="primary"
size="small"
icon="el-icon-edit"
@click="handleEdit(scope)"
/>
<el-button
:disabled="!checkPermission(['validation_delete'])"
type="danger"
size="small"
icon="el-icon-delete"
@click="handleDelete(scope)"
/>
</template>
</el-table-column>
</el-table>
<pagination
v-show="contentList.count > 0"
:total="contentList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑能力验证' : '新增能力验证'"
>
<el-form
ref="Form"
:model="Content"
label-width="80px"
label-position="right"
:rules="rule1"
>
<el-form-item label="名称" prop="name">
<el-input v-model="Content.name" placeholder="文档名称" />
</el-form-item>
<el-form-item label="文档描述" prop="description">
<el-input
type="textarea"
:rows="4"
v-model="Content.description"
placeholder="文档描述"
/>
</el-form-item>
<el-form-item label="文档上传" prop="file" v-if="dialogVisible">
<el-upload
ref="upload"
:action="upUrl"
:on-preview="handlePreview"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf"
>
<el-button size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getValidationList,
createValidation,
deleteValidation,
updateValidation,
} from "@/api/validation";
import { genTree } from "@/utils";
import {provinceAndCityData,CodeToText} from "element-china-area-data";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { upUrl, upHeaders } from "@/api/file";
const defaultContent = {
name: "",
description: "",
file:null
};
export default {
components: { Pagination, Treeselect },
data() {
return {
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList:[],
Content: defaultContent,
dialogVisible: false,
listQuery: {
page: 1,
page_size: 20,
},
contentList: {
count:0
},
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
};
},
computed: {},
watch: {
filterOrgText(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.getList();
},
methods: {
handlePreview(file) {
if ("url" in file) {
window.open(file.url);
} else {
window.open(file.response.data.path);
}
},
handleUpSuccess(res, file, filelist) {
this.Content.file = res.data.id;
},
handleRemove(file, filelist){
this.Content.file = null;
},
checkPermission,
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
getList() {
getValidationList(this.listQuery).then((response) => {
if (response.data) {
this.contentList = response.data;
}
});
},
handleAddContent() {
this.Content = Object.assign({}, defaultContent);
this.dialogType = "new";
this.dialogVisible = true;
this.fileList=[]
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.Content = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
if (this.Content.file) {
this.fileList = [
{
name:this.Content.file_.name,
url: this.Content.file,
},
];
}
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteValidation(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
console.log(this.Content)
updateValidation(this.Content.id, this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("编辑成功");
}
});
} else {
createValidation(this.Content).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("新建成功");
}
});
}
} else {
return false;
}
});
},
},
};
</script>

View File

@ -136,7 +136,7 @@ export default {
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
handleDo(val){

View File

View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class QualityConfig(AppConfig):
name = 'consulting'

View File

@ -0,0 +1,39 @@
# Generated by Django 3.0.5 on 2021-12-13 01:56
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0018_auto_20210430_1156'),
]
operations = [
migrations.CreateModel(
name='Regulatory',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=100, verbose_name='名称')),
('description', models.TextField(blank=True, default='', verbose_name='描述')),
('provinces', models.CharField(default='', max_length=100, verbose_name='省份')),
('type', models.CharField(choices=[(1, '通知'), (2, '结果')], default=1, max_length=50, verbose_name='材料类别')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='regulatory_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.File')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='regulatory_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '监管信息',
'verbose_name_plural': '监管信息',
},
),
]

View File

@ -0,0 +1,36 @@
# Generated by Django 3.0.5 on 2021-12-13 02:11
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0018_auto_20210430_1156'),
('consulting', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Professional',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=100, verbose_name='名称')),
('description', models.TextField(blank=True, default='', verbose_name='描述')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='professional_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.File')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='professional_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '专业领域要求',
'verbose_name_plural': '专业领域要求',
},
),
]

View File

@ -0,0 +1,54 @@
# Generated by Django 3.0.5 on 2021-12-13 02:34
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0018_auto_20210430_1156'),
('consulting', '0002_professional'),
]
operations = [
migrations.CreateModel(
name='Validation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=100, verbose_name='名称')),
('description', models.TextField(blank=True, default='', verbose_name='描述')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='validation_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.File')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='validation_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '政策咨询',
'verbose_name_plural': '政策咨询',
},
),
migrations.CreateModel(
name='Policy',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=100, verbose_name='名称')),
('description', models.TextField(blank=True, default='', verbose_name='描述')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='policy_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.File')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='policy_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '政策咨询',
'verbose_name_plural': '政策咨询',
},
),
]

View File

@ -0,0 +1,47 @@
from django.db import models
from utils.model import BaseModel
from apps.system.models import CommonAModel, File
# Create your models here.
class Regulatory(CommonAModel):
type_choices = (
(1, '通知'),
(2, '结果')
)
name = models.CharField('名称', max_length=100)
description = models.TextField('描述', default="", blank=True)
file = models.ForeignKey(File, on_delete=models.CASCADE)
provinces=models.CharField('省份', max_length=100, default="",)
type = models.CharField('材料类别', max_length=50,
choices=type_choices, default=1)
class Meta:
verbose_name = '监管信息'
verbose_name_plural = verbose_name
class Professional(CommonAModel):
name = models.CharField('名称', max_length=100)
description = models.TextField('描述', default="", blank=True)
file = models.ForeignKey(File, on_delete=models.CASCADE)
class Meta:
verbose_name = '专业领域要求'
verbose_name_plural = verbose_name
class Policy(CommonAModel):
name = models.CharField('名称', max_length=100)
description = models.TextField('描述', default="", blank=True)
file = models.ForeignKey(File, on_delete=models.CASCADE)
class Meta:
verbose_name = '政策咨询'
verbose_name_plural = verbose_name
class Validation(CommonAModel):
name = models.CharField('名称', max_length=100)
description = models.TextField('描述', default="", blank=True)
file = models.ForeignKey(File, on_delete=models.CASCADE)
class Meta:
verbose_name = '政策咨询'
verbose_name_plural = verbose_name

View File

@ -0,0 +1,47 @@
from re import template
from django.db.models.base import Model
from rest_framework import serializers
from .models import *
from apps.system.serializers import FileSerializer
from rest_framework.exceptions import ParseError, APIException
class RegulatorySerializer(serializers.ModelSerializer):
file_ = FileSerializer(source='file', read_only=True)
class Meta:
model = Regulatory
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
queryset = queryset.select_related('file')
return queryset
class ProfessionalSerializer(serializers.ModelSerializer):
file_ = FileSerializer(source='file', read_only=True)
class Meta:
model = Professional
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
queryset = queryset.select_related('file')
return queryset
class PolicySerializer(serializers.ModelSerializer):
file_ = FileSerializer(source='file', read_only=True)
class Meta:
model = Policy
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
queryset = queryset.select_related('file')
return queryset
class ValidationSerializer(serializers.ModelSerializer):
file_ = FileSerializer(source='file', read_only=True)
class Meta:
model = Validation
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
queryset = queryset.select_related('file')
return queryset

View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View File

@ -0,0 +1,13 @@
from django.urls import path, include
from rest_framework import routers
from .views import RegulatoryViewSet,ProfessionalViewSet,PolicyViewSet,ValidationViewSet
router = routers.DefaultRouter()
router.register('regulatory', RegulatoryViewSet, basename='regulatory')
router.register('professional', ProfessionalViewSet, basename='professional')
router.register('policy', PolicyViewSet, basename='policy')
router.register('validation', ValidationViewSet, basename='validation')
urlpatterns = [
path('', include(router.urls))
]

View File

@ -0,0 +1,51 @@
from django.conf import settings
from django.core.cache import cache
from django.db.models import Count, Q
from django.db.models.query import QuerySet
from django.http import request
from django.shortcuts import render
from django.utils import timezone
from rest_framework import status
from rest_framework.decorators import action, permission_classes
from rest_framework.exceptions import PermissionDenied
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from utils.pagination import PageOrNot
from apps.system.mixins import CreateUpdateCustomMixin, CreateUpdateModelAMixin, OptimizationMixin
from apps.system.models import Organization
from apps.system.permission import get_permission_list, has_permission
from apps.system.permission_data import RbacFilterSet
from .models import *
from .serializers import *
# Create your views here.
class RegulatoryViewSet(OptimizationMixin, PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
perms_map = {'get': '*', 'post': 'regulatory_create',
'put': 'regulatory_update', 'delete': 'regulatory_delete'}
queryset = Regulatory.objects.all()
serializer_class = RegulatorySerializer
ordering = ['-id']
search_fields = ['provinces']
ordering_fields = ['provinces']
filterset_fields = ['provinces']
class ProfessionalViewSet(OptimizationMixin, PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
perms_map = {'get': '*', 'post': 'professional_create',
'put': 'professional_update', 'delete': 'professional_delete'}
queryset = Professional.objects.all()
serializer_class = ProfessionalSerializer
ordering = ['-id']
class PolicyViewSet(OptimizationMixin, PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
perms_map = {'get': '*', 'post': 'policy_create',
'put': 'policy_update', 'delete': 'policy_delete'}
queryset = Policy.objects.all()
serializer_class = PolicySerializer
ordering = ['-id']
class ValidationViewSet(OptimizationMixin, PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
perms_map = {'get': '*', 'post': 'validation_create',
'put': 'policy_update', 'delete': 'validation_delete'}
queryset = Validation.objects.all()
serializer_class = ValidationSerializer
ordering = ['-id']

View File

@ -46,7 +46,9 @@ INSTALLED_APPS = [
'apps.ability',
'apps.supervision',
'apps.quality',
'apps.vod'
'apps.vod',
'apps.consulting'
]
MIDDLEWARE = [

View File

@ -48,6 +48,8 @@ urlpatterns = [
path('api/supervision/', include('apps.supervision.urls')),
path('api/quality/', include('apps.quality.urls')),
path('api/vod/', include('apps.vod.urls')),
path('api/consulting/', include('apps.consulting.urls')),
path('api/docs/', include_docs_urls(title="接口文档",authentication_classes=[], permission_classes=[])),
path('api/', include(router.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)