This commit is contained in:
shijing 2022-04-14 09:13:24 +08:00
commit 3cc0767fa1
51 changed files with 2389 additions and 288 deletions

View File

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

View File

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

@ -77,3 +77,11 @@ export function createRecord(data) {
data data
}) })
} }
export function deptconfirm(id) {
return request({
url: `/supervision/record/${id}/deptconfirm/`,
method: 'put',
})
}

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,39 @@ export const asyncRoutes = [
}, },
] ]
}
,
{
path: '/consulting',
component: Layout,
redirect: '/consulting/',
name: 'consulting',
meta: { title: '资讯资料分享', icon: 'guide', perms: ['consulting_views'] },
alwaysShow: true,
children: [
{
path: 'policy',
name: 'policy',
component: () => import('@/views/consulting/policy.vue'),
meta: { title: '政策资讯', perms: ['policy_view'] }
},
{
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: 'validation',
name: 'validation',
component: () => import('@/views/consulting/validation.vue'),
meta: { title: '能力验证', perms: ['validation_view'] }
},
]
}, },
{ {
path: '/supervision', 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,.zip"
>
<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,324 @@
<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="领域" :filter-method="filterTag" :filters="[{ text: '环保领域', value: 1 }, { text: '建工建材', value: 2 },
{ text: '食品领域', value: 3 }, { text: '水利工程', value: 4 },{ text: '检定校准', value: 5 }, { text: '其他领域', value: 6 }]">
<template slot-scope="scope">{{
options_[scope.row.professionalfield]
}}</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="professionalfield">
<el-select
style="width: 100%"
v-model="Content.professionalfield"
placeholder="请选择"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</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,.zip"
>
<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,
options_: {
1: "环保领域",
2: "建工建材",
3: "食品领域",
4: "水利工程",
5: "检定校准",
6: "其他领域",
},
options: [
{
value: 1,
label: "环保领域",
},
{
value: 2,
label: "建工建材",
},
{
value: 3,
label: "食品领域",
},
{
value: 4,
label: "水利工程",
},
{
value: 5,
label: "检定校准",
},
{
value: 6,
label: "其他领域",
},
],
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;
}
});
},
filterTag(value, row) {
return row.professionalfield === value;
},
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,361 @@
<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,.zip"
>
<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:[
{value: "市场监管总局",label: "市场监管总局"},
{value: "北京市", label: "北京市"},
{value: "上海市",label: "上海市"},
{value: "天津市", label: "天津市"},
{value: "重庆市",label: "重庆市"},
{value: "黑龙江省", label: "黑龙江省"},
{value: "辽宁省",label: "辽宁省"},
{value: "吉林省", label: "吉林省"},
{value: "河北省",label: "河北省"},
{value: "河南省", label: "河南省"},
{value: "湖北省",label: "湖北省"},
{value: "湖南省", label: "湖南省"},
{value: "山东省",label: "山东省"},
{value: "山西省", label: "山西省"},
{value: "陕西省",label: "陕西省"},
{value: "安徽省", label: "安徽省"},
{value: "浙江省",label: "浙江省"},
{value: "江苏省", label: "江苏省"},
{value: "福建省",label: "福建省"},
{value: "广东省", label: "广东省"},
{value: "海南省",label: "海南省"},
{value: "四川省", label: "四川省"},
{value: "云南省",label: "云南省"},
{value: "贵州省", label: "贵州省"},
{value: "青海省",label: "青海省"},
{value: "甘肃省", label: "甘肃省"},
{value: "江西省",label: "江西省"},
{value: "内蒙古自治区",label: "内蒙古自治区"},
{value: "宁夏回族自治区", label: "宁夏回族自治区"},
{value: "新疆维吾尔自治区",label: "新疆维吾尔自治区"},
{value: "西藏自治区", label: "西藏自治区"},
{value: "广西壮族自治区", label: "广西壮族自治区"},
{value: "香港特别行政区", label: "香港特别行政区"},
{value: "澳门特别行政区", label: "澳门特别行政区"},
{value: "台湾省", label: "台湾省"},
],
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,365 @@
<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(['validation_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="filterTag1">
<template slot-scope="scope">
{{filetype_[scope.row.filetype] }}</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(['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="filetype">
<el-radio-group v-model="Content.filetype">
<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,.zip"
>
<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,
type_:{1:"通知",2:"结果"},
filetype_:{1:"征集通知",2:"结果通报"},
options:[
{value: "市场监管总局",label: "市场监管总局"},
{value: "北京市", label: "北京市"},
{value: "上海市",label: "上海市"},
{value: "天津市", label: "天津市"},
{value: "重庆市",label: "重庆市"},
{value: "黑龙江省", label: "黑龙江省"},
{value: "辽宁省",label: "辽宁省"},
{value: "吉林省", label: "吉林省"},
{value: "河北省",label: "河北省"},
{value: "河南省", label: "河南省"},
{value: "湖北省",label: "湖北省"},
{value: "湖南省", label: "湖南省"},
{value: "山东省",label: "山东省"},
{value: "山西省", label: "山西省"},
{value: "陕西省",label: "陕西省"},
{value: "安徽省", label: "安徽省"},
{value: "浙江省",label: "浙江省"},
{value: "江苏省", label: "江苏省"},
{value: "福建省",label: "福建省"},
{value: "广东省", label: "广东省"},
{value: "海南省",label: "海南省"},
{value: "四川省", label: "四川省"},
{value: "云南省",label: "云南省"},
{value: "贵州省", label: "贵州省"},
{value: "青海省",label: "青海省"},
{value: "甘肃省", label: "甘肃省"},
{value: "江西省",label: "江西省"},
{value: "内蒙古自治区",label: "内蒙古自治区"},
{value: "宁夏回族自治区", label: "宁夏回族自治区"},
{value: "新疆维吾尔自治区",label: "新疆维吾尔自治区"},
{value: "西藏自治区", label: "西藏自治区"},
{value: "广西壮族自治区", label: "广西壮族自治区"},
{value: "香港特别行政区", label: "香港特别行政区"},
{value: "澳门特别行政区", label: "澳门特别行政区"},
{value: "台湾省", label: "台湾省"},
],
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: {
filterTag(value, row) {
return row.type === value;
},
filterTag1(value, row) {
return row.filetype === value;
},
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;
}
});
},
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 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

@ -2,7 +2,7 @@
<div class="login"> <div class="login">
<div class="topTitleWrap"> <div class="topTitleWrap">
<div class="topTitle1">国家新材料测试评价平台</div> <div class="topTitle1">国家新材料测试评价平台</div>
<div class="topTitle2">先进无非金属材料行业中心</div> <div class="topTitle2">先进无非金属材料行业中心</div>
</div> </div>
<div class="login-form"> <div class="login-form">
<img class="logo" src="../../assets/logo.png" /> <img class="logo" src="../../assets/logo.png" />

View File

@ -38,6 +38,12 @@
</el-table-column> </el-table-column>
<el-table-column label="报送说明"> <el-table-column label="报送说明">
<template slot-scope="scope">{{ scope.row.noteb }}</template> <template slot-scope="scope">{{ scope.row.noteb }}</template>
</el-table-column>
<el-table-column label="二级单位确认">
<template slot-scope="scope">
<el-tag v-if="scope.row.dept_yes" effect="plain">已确认</el-tag>
<el-tag type="danger" effect="plain" v-else>未确认</el-tag>
</template>
</el-table-column> </el-table-column>
<el-table-column label="记录状态"> <el-table-column label="记录状态">
<template slot-scope="scope"> <template slot-scope="scope">
@ -86,6 +92,16 @@
size="small" size="small"
@click="handleRecord({ action: 'up', record: scope.row })" @click="handleRecord({ action: 'up', record: scope.row })"
>报送</el-link >报送</el-link
>
<el-link
v-if="
scope.row.dept_yes == false && scope.row.state == '已报送' &&
checkPermission(['record_detconfirm'])
"
type="primary"
size="small"
@click="handleRecord({ action: 'deptconfirm', record: scope.row })"
>二级单位确认</el-link
> >
<el-link <el-link
v-if=" v-if="

View File

@ -152,6 +152,12 @@
scope.row.belong_dept_.name scope.row.belong_dept_.name
}}</template> }}</template>
</el-table-column> </el-table-column>
<el-table-column label="二级单位确认">
<template slot-scope="scope">
<el-tag v-if="scope.row.dept_yes" effect="plain">已确认</el-tag>
<el-tag type="danger" effect="plain" v-else>未确认</el-tag>
</template>
</el-table-column>
<el-table-column label="记录状态"> <el-table-column label="记录状态">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag type="danger" v-if="scope.row.state == '待报送'">{{ <el-tag type="danger" v-if="scope.row.state == '待报送'">{{
@ -457,9 +463,7 @@ export default {
this.centerDialogVisible = false; this.centerDialogVisible = false;
this.listQuery = { this.listQuery = {
page: 1, page: 1,
page_size: 20, page_size: 20
state: "待报送",
is_self: true,
}; };
this.getList(); this.getList();
}); });

View File

@ -99,6 +99,12 @@
@click="confirm()" @click="confirm()"
v-else-if="this.data.action == 'delete'" v-else-if="this.data.action == 'delete'"
>删除</el-button >删除</el-button
>
<el-button
@click="confirm()"
type="primary"
v-if="this.data.action == 'deptconfirm'"
>确认</el-button
> >
<el-button type="primary" @click="confirm()" v-else>确认</el-button> <el-button type="primary" @click="confirm()" v-else>确认</el-button>
</div> </div>
@ -136,6 +142,7 @@ import {
rejectRecord, rejectRecord,
confirmRecord, confirmRecord,
deleteRecord, deleteRecord,
deptconfirm
} from "@/api/record"; } from "@/api/record";
export default { export default {
name: "recorddo", name: "recorddo",
@ -218,12 +225,19 @@ export default {
this.$message.success("成功"); this.$message.success("成功");
this.$emit("handleDo",true); this.$emit("handleDo",true);
}); });
} else if (this.data.action == "reject") { } else if (this.data.action == "deptconfirm") {
deptconfirm(this.record.id).then((res) => {
this.$message.success("二级单位确认成功");
this.$emit("handleDo",true);
});
}
else if (this.data.action == "reject") {
rejectRecord(this.record.id, this.record).then((res) => { rejectRecord(this.record.id, this.record).then((res) => {
this.$message.success("成功"); this.$message.success("成功");
this.$emit("handleDo",true); this.$emit("handleDo",true);
}); });
} else if (this.data.action == "confirm") { }else if (this.data.action == "confirm") {
confirmRecord(this.record.id).then((res) => { confirmRecord(this.record.id).then((res) => {
this.$message.success("成功"); this.$message.success("成功");
this.$emit("handleDo",true); this.$emit("handleDo",true);

View File

@ -247,6 +247,12 @@
}}</el-tag> }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="二级单位确认">
<template slot-scope="scope">
<el-tag v-if="scope.row.dept_yes" effect="plain">已确认</el-tag>
<el-tag type="danger" effect="plain" v-else>未确认</el-tag>
</template>
</el-table-column>
<el-table-column label="报送要求/备注"> <el-table-column label="报送要求/备注">
<template slot-scope="scope">{{ scope.row.note }}</template> <template slot-scope="scope">{{ scope.row.note }}</template>
</el-table-column> </el-table-column>

View File

@ -1,14 +1,21 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card> <el-card>
<el-button type="primary" icon="el-icon-plus" @click="handleAddVideo" <el-button type="primary" icon="el-icon-plus" @click="handleAddVideo"
>新增</el-button >新增</el-button
> >
</el-card> </el-card>
<el-card style="margin-top: 10px"> <el-card style="margin-top: 10px">
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="videoList.results.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase())|| data.category_name.toLowerCase().includes(search.toLowerCase()))" :data="
videoList.results.filter(
(data) =>
!search ||
data.name.toLowerCase().includes(search.toLowerCase()) ||
data.category_name.toLowerCase().includes(search.toLowerCase())
)
"
border border
fit fit
stripe stripe
@ -22,42 +29,42 @@
<el-table-column label="描述"> <el-table-column label="描述">
<template slot-scope="scope">{{ scope.row.description }}</template> <template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column> </el-table-column>
<el-table-column label="视频类别"> <el-table-column label="视频类别">
<template slot-scope="scope">{{ scope.row.category_name }}</template> <template slot-scope="scope">{{ scope.row.category_name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间"> <el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template> <template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column> </el-table-column>
<el-table-column label="视频地址"> <el-table-column label="视频地址">
<template slot-scope="scope">{{ scope.row.mediaurl }}</template> <template slot-scope="scope">{{ scope.row.mediaurl }}</template>
</el-table-column> </el-table-column>
<el-table-column label="封面地址"> <el-table-column label="封面地址">
<template slot-scope="scope">{{ scope.row.coverurl }}</template> <template slot-scope="scope">{{ scope.row.coverurl }}</template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center" align="center"
label="操作" label="操作"
width="200px" width="200px"
fixed="right" fixed="right"
> >
<template slot="header" slot-scope="scope"> <template slot="header" slot-scope="scope">
<el-input <el-input
v-model="search" v-model="search"
size="mini" size="mini"
placeholder="输入关键字搜索"/> placeholder="输入关键字搜索"
</template> />
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
:disabled="!checkPermission(['video_update'])" :disabled="!checkPermission(['video_update'])"
type="primary" type="primary"
size="small" size="small"
icon="el-icon-edit" icon="el-icon-edit"
@click="handleEdit(scope)" @click="handleEdit(scope)"
/> />
<el-button <el-button
:disabled="!checkPermission(['video_delete'])" :disabled="!checkPermission(['video_delete'])"
type="danger" type="danger"
size="small" size="small"
icon="el-icon-delete" icon="el-icon-delete"
@ -77,22 +84,21 @@
<el-dialog <el-dialog
:visible.sync="dialogVisible" :visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑视频信息' : '新增视频信息'" :title="dialogType === 'edit' ? '编辑视频信息' : '新增视频信息'"
> >
<el-form <el-form
ref="Forms" ref="Forms"
:model="VideoContent" :model="VideoContent"
label-width="80px" label-width="80px"
label-position="right" label-position="right"
:rules="rule1" :rules="rule1"
> >
<el-form-item label="视频名称" prop="name"> <el-form-item label="视频名称" prop="name">
<el-input v-model="VideoContent.name" placeholder="名称" /> <el-input v-model="VideoContent.name" placeholder="名称" />
</el-form-item> </el-form-item>
<el-form-item label="视频描述" prop="description"> <el-form-item label="视频描述" prop="description">
<el-input v-model="VideoContent.description" placeholder="名称" /> <el-input v-model="VideoContent.description" placeholder="名称" />
</el-form-item> </el-form-item>
<el-form-item label="视频类型" prop="category"> <el-form-item label="视频类型" prop="category">
<el-cascader <el-cascader
v-model="VideoContent.category" v-model="VideoContent.category"
:options="typeOptions" :options="typeOptions"
@ -101,54 +107,92 @@
style="width: 100%" style="width: 100%"
></el-cascader> ></el-cascader>
</el-form-item> </el-form-item>
<form ref="vcExample"> <form ref="vcExample">
<input type="file" style="display:none;" ref="vcExampleVideo" @change="setVcExampleVideoName()" /> <input
<input type="file" style="display:none;" ref="vcExampleCover" @change="setVcExampleCoverName()" /> type="file"
</form> style="display: none"
<div class="row" style="padding:10px;"> ref="vcExampleVideo"
@change="setVcExampleVideoName()"
<el-button type="primary" @click="vcExampleAddVideo">{{vcExampleVideoName || '添加视频'}}</el-button> />
<el-button type="primary" @click="vcExampleAddCover">{{vcExampleCoverName || '添加封面'}}</el-button> <input
<el-button type="success" @click="vcExampleAddUpload">上传视频和封面</el-button> type="file"
</div> style="display: none"
ref="vcExampleCover"
@change="setVcExampleCoverName()"
<div class="row" id="resultBox"> />
<!-- 上传信息组件 --> </form>
<div class="uploaderMsgBox" v-for="uploaderInfo in uploaderInfos"> <div class="row" style="padding: 10px">
<el-button type="primary" @click="vcExampleAddVideo">{{
<div v-if="uploaderInfo.videoInfo" > vcExampleVideoName || "添加视频"
视频名称{{uploaderInfo.videoInfo.name + '.' + uploaderInfo.videoInfo.type}} }}</el-button>
上传进度 <el-button type="primary" @click="vcExampleAddCover">{{
<el-progress :text-inside="true" :stroke-width="24" :percentage="Math.floor(uploaderInfo.progress * 100)" status="success"> vcExampleCoverName || "添加封面"
</el-progress> }}</el-button>
上传结果{{uploaderInfo.isVideoUploadCancel ? '已取消' : uploaderInfo.isVideoUploadSuccess ? '上传成功' : '上传中'}} <el-button type="success" @click="vcExampleAddUpload"
<br> >上传视频和封面</el-button
地址{{uploaderInfo.videoUrl}} >
<a href="javascript:void(0);" class="cancel-upload" v-if="!uploaderInfo.isVideoUploadSuccess && !uploaderInfo.isVideoUploadCancel" @click="uploaderInfo.cancel()">取消上传</a><br>
</div> </div>
<div class="row" id="resultBox">
<!-- 上传信息组件 -->
<div class="uploaderMsgBox" v-for="uploaderInfo in uploaderInfos">
<div v-if="uploaderInfo.videoInfo">
视频名称{{
uploaderInfo.videoInfo.name + "." + uploaderInfo.videoInfo.type
}} 上传进度
<el-progress
:text-inside="true"
:stroke-width="24"
:percentage="Math.floor(uploaderInfo.progress * 100)"
status="success"
>
</el-progress>
上传结果{{
uploaderInfo.isVideoUploadCancel
? "已取消"
: uploaderInfo.isVideoUploadSuccess
? "上传成功"
: "上传中"
}}
<br />
地址{{ uploaderInfo.videoUrl }}
<a
href="javascript:void(0);"
class="cancel-upload"
v-if="
!uploaderInfo.isVideoUploadSuccess &&
!uploaderInfo.isVideoUploadCancel
"
@click="uploaderInfo.cancel()"
>取消上传</a
><br />
</div>
<div v-if="uploaderInfo.coverInfo"> <div v-if="uploaderInfo.coverInfo">
封面名称{{uploaderInfo.coverInfo.name}} 封面名称{{ uploaderInfo.coverInfo.name }} 上传进度
上传进度 <el-progress
<el-progress :text-inside="true" :stroke-width="24" :percentage="Math.floor(uploaderInfo.coverProgress * 100)" status="success"> :text-inside="true"
</el-progress> :stroke-width="24"
上传结果{{uploaderInfo.isCoverUploadSuccess ? '上传成功' : '上传中'}} :percentage="Math.floor(uploaderInfo.coverProgress * 100)"
<br> status="success"
地址{{uploaderInfo.coverUrl}} >
<br> </el-progress>
上传结果{{
<video :src="uploaderInfo.videoUrl" style="width:400px;height:300px" id="video" autoplay></video> uploaderInfo.isCoverUploadSuccess ? "上传成功" : "上传中"
}}
<br />
地址{{ uploaderInfo.coverUrl }}
<br />
<video
:src="uploaderInfo.videoUrl"
style="width: 400px; height: 300px"
id="video"
autoplay
></video>
</div>
</div>
</div> </div>
</div>
</div>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button> <el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -156,76 +200,74 @@
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script src="https://cdn-go.cn/cdn/vod-js-sdk-v6/latest/vod-js-sdk-v6.js"></script> <script src="https://cdn-go.cn/cdn/vod-js-sdk-v6/latest/vod-js-sdk-v6.js"></script>
<script type="text/javascript"> <script type="text/javascript">
import { updatevideo,getsignature,createVideo,getVideoList,deletevideo} from "@/api/video"; import {
updatevideo,
getsignature,
createVideo,
getVideoList,
deletevideo,
} from "@/api/video";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import { getDictList, getDictTypeList } from "@/api/dict"; import { getDictList, getDictTypeList } from "@/api/dict";
import TcVod from "vod-js-sdk-v6"; import TcVod from "vod-js-sdk-v6";
import checkPermission from '@/utils/permission' import checkPermission from "@/utils/permission";
import { genTree } from "@/utils"; import { genTree } from "@/utils";
const defaultVideo = { const defaultVideo = {
name:"", name: "",
description:"", description: "",
category:"", category: "",
mediaurl:'', mediaurl: "",
} };
export default { export default {
components: {Pagination }, components: { Pagination },
data() { data() {
return { return {
dialogVisible:false, dialogVisible: false,
signature: "", signature: "",
treeLoding: false, treeLoding: false,
videoList: { videoList: {
count: 0, count: 0,
}, },
typeOptions:[], typeOptions: [],
dialogType:'', dialogType: "",
listQuery: { listQuery: {
page: 1, page: 1,
page_size: 20, page_size: 20,
}, },
search: '', search: "",
VideoContent:defaultVideo, VideoContent: defaultVideo,
uploaderInfos: [], uploaderInfos: [],
vcExampleVideoName: '', vcExampleVideoName: "",
listLoading:false, listLoading: false,
vcExampleCoverName: '', vcExampleCoverName: "",
rule1: { rule1: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }], name: [{ required: true, message: "请输入名称", trigger: "blur" }],
category: [{ required: true, message: "请选择视频分类", trigger: 'change' }], category: [
{ required: true, message: "请选择视频分类", trigger: "change" },
],
}, },
}; };
}, },
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList();
this.getTypeAll(); this.getTypeAll();
}, },
methods: { methods: {
checkPermission,
checkPermission, //列表加载
//列表加载 getList() {
getList() {
this.listLoading = true; this.listLoading = true;
getVideoList(this.listQuery).then((response) => { getVideoList(this.listQuery).then((response) => {
if (response.data) { if (response.data) {
@ -234,17 +276,17 @@ checkPermission,
this.listLoading = false; this.listLoading = false;
}); });
}, },
//视频类型 //视频类型
getTypeAll() { getTypeAll() {
getDictList({ type__code: "data_video" }).then((res) => { getDictList({ type__code: "data_video" }).then((res) => {
this.typeOptions = genTree(res.data); this.typeOptions = genTree(res.data);
}); });
}, },
/*弹出弹窗 */ /*弹出弹窗 */
handleAddVideo() { handleAddVideo() {
this.VideoContent = Object.assign({},defaultVideo); this.VideoContent = Object.assign({}, defaultVideo);
this.dialogType = "new"; this.dialogType = "new";
this.dialogVisible = true; this.dialogVisible = true;
@ -253,8 +295,8 @@ checkPermission,
}); });
}, },
//删除视频 //删除视频
handleDelete(scope) { handleDelete(scope) {
this.$confirm("确认删除?", "警告", { this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认", confirmButtonText: "确认",
cancelButtonText: "取消", cancelButtonText: "取消",
@ -269,8 +311,8 @@ checkPermission,
console.error(err); console.error(err);
}); });
}, },
//编辑视频 //编辑视频
handleEdit(scope) { handleEdit(scope) {
this.VideoContent = Object.assign({}, scope.row); // copy obj this.VideoContent = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit"; this.dialogType = "edit";
this.dialogVisible = true; this.dialogVisible = true;
@ -279,114 +321,104 @@ checkPermission,
this.$refs["Forms"].clearValidate(); this.$refs["Forms"].clearValidate();
}); });
}, },
setVcExampleVideoName: function () { setVcExampleVideoName: function () {
this.vcExampleVideoName = this.$refs.vcExampleVideo.files[0].name; this.vcExampleVideoName = this.$refs.vcExampleVideo.files[0].name;
}, },
setVcExampleCoverName: function () { setVcExampleCoverName: function () {
this.vcExampleCoverName = this.$refs.vcExampleCover.files[0].name; this.vcExampleCoverName = this.$refs.vcExampleCover.files[0].name;
}, },
/* /*
vcExample添加视频 vcExample添加视频
*/ */
vcExampleAddVideo: function () { vcExampleAddVideo: function () {
this.$refs.vcExampleVideo.click() this.$refs.vcExampleVideo.click();
}, },
/* /*
vcExample添加封面 vcExample添加封面
*/ */
vcExampleAddCover: function () { vcExampleAddCover: function () {
this.$refs.vcExampleCover.click() this.$refs.vcExampleCover.click();
}, },
/* /*
vcExample上传过程 vcExample上传过程
*/ */
vcExampleAddUpload: function () { vcExampleAddUpload: function () {
var self = this; var self = this;
var mediaFile = this.$refs.vcExampleVideo.files[0]; var mediaFile = this.$refs.vcExampleVideo.files[0];
var coverFile = this.$refs.vcExampleCover.files[0]; var coverFile = this.$refs.vcExampleCover.files[0];
// 获取签名 这里必须定义为函数tcVod才可识别 // 获取签名 这里必须定义为函数tcVod才可识别
const getSignature = async function() { const getSignature = async function () {
const { data } = await getsignature() const { data } = await getsignature();
return data return data;
} };
// 前文中所述的获取上传签名的函数 // 前文中所述的获取上传签名的函数
const tcVod = new TcVod({ getSignature }) const tcVod = new TcVod({ getSignature });
var uploader = tcVod.upload({ var uploader = tcVod.upload({
mediaFile: mediaFile, mediaFile: mediaFile,
coverFile: coverFile, coverFile: coverFile,
}) });
uploader.on("media_progress", function (info) {
uploaderInfo.progress = info.percent;
});
uploader.on("media_upload", function (info) {
uploaderInfo.isVideoUploadSuccess = true;
});
uploader.on("cover_progress", function (info) {
uploaderInfo.coverProgress = info.percent;
});
uploader.on("cover_upload", function (info) {
uploaderInfo.isCoverUploadSuccess = true;
});
var uploaderInfo = {
videoInfo: uploader.videoInfo,
coverInfo: uploader.coverInfo,
isVideoUploadSuccess: false,
isVideoUploadCancel: false,
isCoverUploadSuccess: false,
progress: 0,
coverProgress: 0,
fileId: "",
videoUrl: "",
coverUrl: "",
cancel: function () {
uploaderInfo.isVideoUploadCancel = true;
uploader.cancel();
},
};
uploader.on('media_progress', function(info) { this.uploaderInfos.push(uploaderInfo);
uploaderInfo.progress = info.percent; // console.log('uploaderInfos',this.uploaderInfos);
})
uploader.on('media_upload', function(info) {
uploaderInfo.isVideoUploadSuccess = true;
})
uploader.on('cover_progress', function(info) {
uploaderInfo.coverProgress = info.percent;
})
uploader.on('cover_upload', function(info) {
uploaderInfo.isCoverUploadSuccess = true;
})
uploader.done().then(function (doneResult) {
console.log("doneResult", doneResult);
var uploaderInfo = { uploaderInfo.fileId = doneResult.fileId;
videoInfo: uploader.videoInfo,
coverInfo: uploader.coverInfo,
isVideoUploadSuccess: false,
isVideoUploadCancel: false,
isCoverUploadSuccess: false,
progress: 0,
coverProgress: 0,
fileId: '',
videoUrl: '',
coverUrl: '',
cancel: function () {
uploaderInfo.isVideoUploadCancel = true;
uploader.cancel()
},
}
this.uploaderInfos.push(uploaderInfo) uploaderInfo.coverUrl = doneResult.cover.url;
// console.log('uploaderInfos',this.uploaderInfos); uploaderInfo.videoUrl = doneResult.video.url;
uploader.done().then(function (doneResult) { self.$refs.vcExample.reset();
console.log('doneResult', doneResult) self.vcExampleVideoName = "";
self.vcExampleCoverName = "";
});
},
async confirm(form) {
uploaderInfo.fileId = doneResult.fileId;
uploaderInfo.coverUrl = doneResult.cover.url;
uploaderInfo.videoUrl = doneResult.video.url;
self.$refs.vcExample.reset();
self.vcExampleVideoName = ''
self.vcExampleCoverName = ''
})
},
async confirm(form) {
this.$refs[form].validate((valid) => { this.$refs[form].validate((valid) => {
if (valid) { if (valid) {
const isEdit = this.dialogType === "edit"; const isEdit = this.dialogType === "edit";
if (isEdit) { if (isEdit) {
for (var i = 0; i < this.uploaderInfos.length; i++) { for (var i = 0; i < this.uploaderInfos.length; i++) {
this.VideoContent.fileid = this.uploaderInfos[i].fileId;
this.VideoContent.fileid= this.uploaderInfos[i].fileId ; this.VideoContent.coverurl = this.uploaderInfos[i].coverUrl;
this.VideoContent.mediaurl = this.uploaderInfos[i].videoUrl;
this.VideoContent.coverurl= this.uploaderInfos[i].coverUrl ; }
this.VideoContent.mediaurl= this.uploaderInfos[i].videoUrl; // console.log(this.VideoContent)
}
// console.log(this.VideoContent)
updatevideo(this.VideoContent.id, this.VideoContent).then((res) => { updatevideo(this.VideoContent.id, this.VideoContent).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
@ -395,18 +427,15 @@ async confirm(form) {
} }
}); });
} else { } else {
for (var i = 0; i < this.uploaderInfos.length; i++) {
this.VideoContent.fileid = this.uploaderInfos[i].fileId;
for (var i = 0; i < this.uploaderInfos.length; i++) { this.VideoContent.coverurl = this.uploaderInfos[i].coverUrl;
this.VideoContent.mediaurl = this.uploaderInfos[i].videoUrl;
this.VideoContent.fileid= this.uploaderInfos[i].fileId ; }
this.VideoContent.coverurl= this.uploaderInfos[i].coverUrl ;
this.VideoContent.mediaurl= this.uploaderInfos[i].videoUrl;
}
createVideo(this.VideoContent).then((res) => { createVideo(this.VideoContent).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
this.dialogVisible = false; this.dialogVisible = false;
this.$message.success("成功"); this.$message.success("成功");
} }
@ -419,42 +448,39 @@ async confirm(form) {
}, },
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.text-danger { .text-danger {
color: red; color: red;
} }
.control-label { .control-label {
text-align: left !important; text-align: left !important;
} }
#resultBox { #resultBox {
width: 100%; width: 100%;
height: 300px; height: 300px;
border: 1px solid #888; border: 1px solid #888;
padding: 5px; padding: 5px;
overflow: auto; overflow: auto;
margin-bottom: 20px; margin-bottom: 20px;
} }
.uploaderMsgBox { .uploaderMsgBox {
border-bottom: 1px solid #888;
background: #1a7ce0;
color: white;
font-size: medium;
}
border-bottom: 1px solid #888; .cancel-upload {
background: #1a7ce0; text-decoration: none;
color: white; cursor: pointer;
font-size: medium; }
} </style>
.cancel-upload {
text-decoration: none;
cursor: pointer;
}
</style>

BIN
client_mp/static.zip Normal file

Binary file not shown.

View File

@ -0,0 +1,23 @@
# Generated by Django 3.0.5 on 2022-03-16 00:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ability', '0023_auto_20210728_0902'),
]
operations = [
migrations.AddField(
model_name='ability',
name='cma_ok',
field=models.BooleanField(blank=True, null=True),
),
migrations.AddField(
model_name='ability',
name='cnas_ok',
field=models.BooleanField(blank=True, null=True),
),
]

View File

@ -19,6 +19,8 @@ class Ability(BaseModel):
xzfw = models.TextField('限制范围',null=True,blank=True) xzfw = models.TextField('限制范围',null=True,blank=True)
bz = models.TextField('备注',null=True,blank=True) bz = models.TextField('备注',null=True,blank=True)
cma = models.TextField('CMA中心',null=True,blank=True) cma = models.TextField('CMA中心',null=True,blank=True)
cma_ok = models.BooleanField(null=True, blank=True)
cnas_ok = models.BooleanField(null=True, blank=True)
cnas = models.TextField('CNAS中心',null=True,blank=True) cnas = models.TextField('CNAS中心',null=True,blank=True)
cma_o = models.TextField('中心',null=True,blank=True) cma_o = models.TextField('中心',null=True,blank=True)
cma_oplace = models.TextField('地点',null=True,blank=True) cma_oplace = models.TextField('地点',null=True,blank=True)

View File

@ -1,7 +1,7 @@
from django.db.models import base from django.db.models import base
from django.urls import path, include from django.urls import path, include
from rest_framework import routers from rest_framework import routers
from .views import AbilityContentViewSet, AbilityRecordViewSet, CMAViewSet, CNASViewSet, CorrectViewSet, QualificationViewSet,InspectionViewSet,QualificationotherViewSet, QueryRecordListViewSet, correct_ability, merge_cma, merge_cnas from .views import AbilityContentViewSet, AbilityRecordViewSet, CMAViewSet, CNASViewSet, CorrectViewSet, QualificationViewSet,InspectionViewSet,QualificationotherViewSet, QueryRecordListViewSet, correct_ability, correct_cma, merge_cma, merge_cnas
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register('cma', CMAViewSet, basename="cma") router.register('cma', CMAViewSet, basename="cma")
@ -16,6 +16,6 @@ router.register('record', AbilityRecordViewSet, basename="abilityrecord")
urlpatterns = [ urlpatterns = [
path('merge/cma/', merge_cma), path('merge/cma/', merge_cma),
path('merge/cnas/', merge_cnas), path('merge/cnas/', merge_cnas),
# path('correct/', correct_ability), path('correct_cma/', correct_cma),
path('', include(router.urls)) path('', include(router.urls))
] ]

View File

@ -586,7 +586,7 @@ def import_cma(filename, path):
wb = load_workbook(path) wb = load_workbook(path)
sheet = wb.worksheets[0] sheet = wb.worksheets[0]
datalist = [] datalist = []
sszx = filename.replace('.xlsx','').replace('副本14检验检测能力申请表-','') sszx = filename.replace('.xlsx','').replace('14检验检测能力申请表-','')
i = 4 i = 4
while sheet['b'+str(i)].value: while sheet['b'+str(i)].value:
data = {} data = {}
@ -846,9 +846,10 @@ def import_correct(path):
from django.db.models.functions import Cast from django.db.models.functions import Cast
def merge_cnas(request): def merge_cnas(request):
for i in CNAS.objects.all(): for i in CNAS.objects.all():
objs = Ability.objects.filter(lbmc=i.lbmc,xmmc=i.xmmc, bzbh=i.bzbh, bztk=i.bztk) objs = Ability.objects.filter(lbmc=i.lbmc,xmmc=i.xmmc, bzbh=i.bzbh, bztk=i.bztk, bzmc=i.bzmc)
if objs.exists(): if objs.exists():
obj = objs[0] obj = objs[0]
obj.cnas_ok = True
if obj.cnas: if obj.cnas:
obj.cnas = obj.cnas + ',' + i.sszx obj.cnas = obj.cnas + ',' + i.sszx
obj.save() obj.save()
@ -856,15 +857,29 @@ def merge_cnas(request):
obj.cnas = i.sszx obj.cnas = i.sszx
obj.save() obj.save()
print('已修改--'+obj.xmmc+ '-' + obj.cnas) print('已修改--'+obj.xmmc+ '-' + obj.cnas)
else:
obj = Ability()
obj.lbmc = i.lbmc
obj.xmmc = i.xmmc
obj.bzmc = i.bzmc
obj.bzbh = i.bzbh
obj.bztk = i.bztk
obj.cnas = i.sszx
obj.cnas_ok = True
obj.save()
print('已添加--'+obj.xmmc+obj.bzmc)
return Response({})
def merge_cma(request): def merge_cma(request):
for i in CMA.objects.filter(type='center'): for i in CMA.objects.filter(type='center'):
bztk = i.bzbh.split(' ')[-1] bztk = i.bzbh.split(' ')[-1]
bzbh = i.bzbh.rstrip(bztk).strip() bzbh = i.bzbh.rstrip(bztk).strip()
xmxh = i.xmxh.strip()
if len(bzbh)<8: if len(bzbh)<8:
bzbh = i.bzbh bzbh = i.bzbh
bztk = '' bztk = ''
objs = Ability.objects.filter(lbmc=i.lbmc, xmmc=i.xmmc, bzbh = bzbh, bztk=bztk) objs = Ability.objects.filter(lbmc=i.lbmc, xmmc=i.xmmc, bzbh = bzbh, bztk=bztk, xmxh=xmxh, bzmc = i.bzmc)
if objs.exists(): if objs.exists():
obj = objs[0] obj = objs[0]
obj.cma = obj.cma + ',' + i.sszx obj.cma = obj.cma + ',' + i.sszx
@ -884,9 +899,10 @@ def merge_cma(request):
obj.xzfw = i.xzfw obj.xzfw = i.xzfw
obj.bz = i.bz obj.bz = i.bz
obj.cma = i.sszx obj.cma = i.sszx
obj.cma_ok = True
obj.save() obj.save()
print('已添加--'+obj.xmmc+obj.bzmc) print('已添加--'+obj.xmmc+obj.bzmc)
return Response({})
def correct_ability(request): def correct_ability(request):
zxdict = { zxdict = {
"测试中心":"B", "测试中心":"B",
@ -938,3 +954,10 @@ def correct_ability(request):
i.cma_oplace = i.cma_oplace.replace(key, placedict[key]) i.cma_oplace = i.cma_oplace.replace(key, placedict[key])
i.save() i.save()
print('已修改' + i.cma) print('已修改' + i.cma)
def correct_cma(request):
for i in CMA.objects.all():
i.sszx = i.sszx.replace('14检验检测能力申请表-','')
i.save()
return Response()

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,18 @@
# Generated by Django 3.0.5 on 2021-12-14 05:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('consulting', '0003_policy_validation'),
]
operations = [
migrations.AddField(
model_name='professional',
name='professionalfield',
field=models.CharField(choices=[(1, '环保领域'), (2, '建工建材'), (1, '食品领域'), (2, '水利工程'), (1, '检定校准'), (2, '其他领域')], default=1, max_length=50, verbose_name='领域类别'),
),
]

View File

@ -0,0 +1,32 @@
# Generated by Django 3.0.5 on 2021-12-14 06:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('consulting', '0004_professional_professionalfield'),
]
operations = [
migrations.AlterModelOptions(
name='validation',
options={'verbose_name': '能力验证', 'verbose_name_plural': '能力验证'},
),
migrations.AddField(
model_name='validation',
name='filetype',
field=models.CharField(choices=[(1, '征集通知'), (2, '结果通报')], default=1, max_length=50, verbose_name='文件类型'),
),
migrations.AddField(
model_name='validation',
name='provinces',
field=models.CharField(default='', max_length=100, verbose_name='省份'),
),
migrations.AddField(
model_name='validation',
name='type',
field=models.CharField(choices=[(1, '通知'), (2, '结果')], default=1, max_length=50, verbose_name='材料类别'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2021-12-14 07:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('consulting', '0005_auto_20211214_1408'),
]
operations = [
migrations.AlterField(
model_name='professional',
name='professionalfield',
field=models.CharField(choices=[(1, '环保领域'), (2, '建工建材'), (3, '食品领域'), (4, '水利工程'), (5, '检定校准'), (6, '其他领域')], default=1, max_length=50, verbose_name='领域类别'),
),
]

View File

@ -0,0 +1,68 @@
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):
field_choices = (
(1, '环保领域'),
(2, '建工建材'),
(3, '食品领域'),
(4, '水利工程'),
(5, '检定校准'),
(6, '其他领域'),
)
name = models.CharField('名称', max_length=100)
description = models.TextField('描述', default="", blank=True)
professionalfield = models.CharField('领域类别', max_length=50,choices=field_choices, default=1)
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):
type_choices = (
(1, '通知'),
(2, '结果')
)
filetype_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)
filetype=models.CharField('文件类型', max_length=50,
choices=filetype_choices, default=1)
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,54 @@
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']
search_fields = ['provinces']
ordering_fields = ['provinces']
filterset_fields = ['provinces']

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2022-03-02 02:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('supervision', '0028_remove_taskdept_files'),
]
operations = [
migrations.AddField(
model_name='record',
name='dept_yes',
field=models.BooleanField(default=False, verbose_name='二级单位是否确认'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2022-03-02 03:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('supervision', '0029_record_dept_yes'),
]
operations = [
migrations.AlterField(
model_name='record',
name='dept_yes',
field=models.BooleanField(default=True, verbose_name='二级单位是否确认'),
),
]

View File

@ -82,6 +82,7 @@ class Record(CommonBModel):
opinion = models.TextField('修改意见', null=True, blank=True) opinion = models.TextField('修改意见', null=True, blank=True)
noteb = models.TextField('报送说明', null=True, blank=True) noteb = models.TextField('报送说明', null=True, blank=True)
files = models.ManyToManyField(File, verbose_name="关联文件") files = models.ManyToManyField(File, verbose_name="关联文件")
dept_yes = models.BooleanField('二级单位是否确认', default=True)
class Meta: class Meta:
verbose_name = '报送记录' verbose_name = '报送记录'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name

View File

@ -50,12 +50,12 @@ class TaskViewSet(CreateUpdateCustomMixin, ModelViewSet):
return TaksDetailSerializer return TaksDetailSerializer
return TaskListSerializer return TaskListSerializer
def destroy(self, request, *args, **kwargs): # def destroy(self, request, *args, **kwargs):
instance = self.get_object() # instance = self.get_object()
instance.delete() # instance.delete()
TaskDept.objects.filter(task=instance).delete() # TaskDept.objects.filter(task=instance).delete()
Record.objects.filter(task=instance).delete() # Record.objects.filter(task=instance).delete()
return Response(status=status.HTTP_204_NO_CONTENT) # return Response(status=status.HTTP_204_NO_CONTENT)
@action(methods=['post'], detail=True, perms_map = {'post':'task_init'}) @action(methods=['post'], detail=True, perms_map = {'post':'task_init'})
def init(self, request, *args, **kwargs): def init(self, request, *args, **kwargs):
@ -84,6 +84,7 @@ class TaskViewSet(CreateUpdateCustomMixin, ModelViewSet):
data['end_date'] = obj.end_date data['end_date'] = obj.end_date
data['create_by'] = request.user data['create_by'] = request.user
data['state'] = '待发布' data['state'] = '待发布'
data['dept_yes'] = False
record_list.append(Record(**data)) record_list.append(Record(**data))
TaskDept.objects.bulk_create(taskdept_list) TaskDept.objects.bulk_create(taskdept_list)
Record.objects.bulk_create(record_list) Record.objects.bulk_create(record_list)
@ -117,6 +118,7 @@ class TaskViewSet(CreateUpdateCustomMixin, ModelViewSet):
r.end_date = obj.end_date r.end_date = obj.end_date
r.create_by = request.user r.create_by = request.user
r.state = '待报送' r.state = '待报送'
r.dept_yes = False
r.save() r.save()
obj.save() obj.save()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@ -280,7 +282,7 @@ class RecordViewSet(PageOrNot, CreateUpdateCustomMixin, ModelViewSet):
rlist = [] rlist = []
for i in contents: for i in contents:
content = Content.objects.get(pk=i) content = Content.objects.get(pk=i)
data = {'content':content, 'belong_dept':request.user.dept, 'is_self':True, 'content_name':content.name, 'content_desc':content.desc} data = {'content':content, 'belong_dept':request.user.dept, 'is_self':True,'dept_yes':False, 'content_name':content.name, 'content_desc':content.desc}
rlist.append(Record(**data)) rlist.append(Record(**data))
Record.objects.bulk_create(rlist) Record.objects.bulk_create(rlist)
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@ -326,6 +328,8 @@ class RecordViewSet(PageOrNot, CreateUpdateCustomMixin, ModelViewSet):
obj.files.add(*request.data['files']) obj.files.add(*request.data['files'])
obj.noteb = request.data['noteb'] obj.noteb = request.data['noteb']
obj.state = '已报送' obj.state = '已报送'
if obj.belong_dept.type.name=='2级公司':
obj.dept_yes = True
obj.up_user = request.user obj.up_user = request.user
obj.up_date = timezone.now() obj.up_date = timezone.now()
obj.save() obj.save()
@ -351,7 +355,17 @@ class RecordViewSet(PageOrNot, CreateUpdateCustomMixin, ModelViewSet):
else: else:
return Response('请填写修改意见', status=status.HTTP_400_BAD_REQUEST) return Response('请填写修改意见', status=status.HTTP_400_BAD_REQUEST)
return Response('记录状态错误', status=status.HTTP_400_BAD_REQUEST) return Response('记录状态错误', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['put'], detail=True, perms_map = {'put':'record_detconfirm'})
def deptconfirm(self, request, *args, **kwargs):
"""
二级单位确认
"""
obj = self.get_object()
if obj.state in ['已报送']:
obj.dept_yes = True
obj.save()
return Response(status=status.HTTP_200_OK)
return Response('记录状态错误', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['put'], detail=True, perms_map = {'put':'record_confirm'}) @action(methods=['put'], detail=True, perms_map = {'put':'record_confirm'})
def confirm(self, request, *args, **kwargs): def confirm(self, request, *args, **kwargs):
""" """

View File

@ -18,7 +18,7 @@ def get_permission_list(user):
perms = perms | i.perms.all() perms = perms | i.perms.all()
perms_list = perms.values_list('method', flat=True) perms_list = perms.values_list('method', flat=True)
perms_list = list(set(perms_list)) perms_list = list(set(perms_list))
cache.set(user.username + '__perms', perms_list, 60*60*24) cache.set(user.username + '__perms', perms_list, 60*60)
return perms_list return perms_list
def has_permission(action, user): def has_permission(action, user):

View File

@ -8,6 +8,11 @@ class VideoSerializer(serializers.ModelSerializer):
model = Video model = Video
fields = '__all__' fields = '__all__'
class VideoListDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Video
exclude = ['mediaurl']
class VideoSimpleSerializer(serializers.ModelSerializer): class VideoSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Video model = Video

View File

@ -1,6 +1,6 @@
from django.db.models import base from django.db.models import base
from django.urls import path, include from django.urls import path, include
from .views import ClassView, SignatureAPIView, VideoView, VideoViewSet, VRecordViewSet, MyViewRecordAPIView from .views import ClassView, PlayCodeAPIView, SignatureAPIView, VideoView, VideoViewSet, VRecordViewSet, MyViewRecordAPIView
from rest_framework import routers from rest_framework import routers
router = routers.DefaultRouter() router = routers.DefaultRouter()
@ -10,4 +10,5 @@ urlpatterns = [
path('', include(router.urls)), path('', include(router.urls)),
path('video/<int:id>/myview/', MyViewRecordAPIView.as_view()), path('video/<int:id>/myview/', MyViewRecordAPIView.as_view()),
path('signature/', SignatureAPIView.as_view()), path('signature/', SignatureAPIView.as_view()),
path('playcode/<str:fileId>/', PlayCodeAPIView.as_view())
] ]

View File

@ -1,10 +1,10 @@
from datetime import timedelta from datetime import timedelta
from time import timezone from time import timezone
from rest_framework.mixins import ListModelMixin from rest_framework.mixins import ListModelMixin
from apps.vod.serializers import VRecordSerializer, VRecordUpdateSerializer, VideoSerializer from apps.vod.serializers import VRecordSerializer, VRecordUpdateSerializer, VideoListDetailSerializer, VideoSerializer
from apps.vod.models import Video, ViewRecord from apps.vod.models import Video, ViewRecord
from django.shortcuts import render from django.shortcuts import render
from .vodclient import getAllClass, searchMedia, getSignature from .vodclient import getAllClass, getPlayCode, searchMedia, getSignature
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
@ -14,6 +14,7 @@ from rest_framework.decorators import action, permission_classes
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.status import HTTP_400_BAD_REQUEST from rest_framework.status import HTTP_400_BAD_REQUEST
from django.utils import timezone from django.utils import timezone
from rest_framework.exceptions import ParseError
# Create your views here. # Create your views here.
class ClassView(APIView): class ClassView(APIView):
@ -47,6 +48,10 @@ class VideoViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
serializer_class = VideoSerializer serializer_class = VideoSerializer
ordering = ['-views', '-create_time'] ordering = ['-views', '-create_time']
def get_serializer_class(self):
if self.action in ['list', 'retrieve']:
return VideoListDetailSerializer
return super().get_serializer_class()
@action(methods=['get'], detail=False, perms_map={'get':'video_view'}) @action(methods=['get'], detail=False, perms_map={'get':'video_view'})
def myview(self, request, *args, **kwargs): def myview(self, request, *args, **kwargs):
""" """
@ -61,6 +66,7 @@ class VideoViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
return Response(serializer.data) return Response(serializer.data)
class VRecordViewSet(ListModelMixin, GenericViewSet): class VRecordViewSet(ListModelMixin, GenericViewSet):
perms_map = {'get':'viewrecord_view'} perms_map = {'get':'viewrecord_view'}
queryset = ViewRecord.objects.all() queryset = ViewRecord.objects.all()
@ -116,3 +122,17 @@ class SignatureAPIView(APIView):
获取上传签名 获取上传签名
""" """
return Response(getSignature(procedure=request.query_params.get('procedure', None))) return Response(getSignature(procedure=request.query_params.get('procedure', None)))
class PlayCodeAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, fileId):
"""获取播放签名
"""
from .vodclient import appId
try:
playcode = getPlayCode(fileId)
except:
raise ParseError('获取签名失败')
return Response({'psign':playcode, 'appId': appId})

View File

@ -4,6 +4,7 @@ import hmac
import json import json
import random import random
import time import time
import jwt
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST from rest_framework.status import HTTP_400_BAD_REQUEST
@ -16,6 +17,8 @@ from tencentcloud.vod.v20180717 import models, vod_client
SecretId = 'AKIDhDTaV9WeXAXcQxEH4buwg9LGvJQHr9Au' SecretId = 'AKIDhDTaV9WeXAXcQxEH4buwg9LGvJQHr9Au'
SecretKey = 'VjfKjrhGYrte8MIxMUMxHL9h39zYqrc6' SecretKey = 'VjfKjrhGYrte8MIxMUMxHL9h39zYqrc6'
appId = '1253484223'
referKey = 'ntXQi6eDkgUXnvvsiAtm'
# 初始化点播client # 初始化点播client
def initClient(): def initClient():
@ -71,3 +74,31 @@ def getSignature(procedure=None):
Signature = bytes(Sha1) + bytes(Original, 'utf-8') Signature = bytes(Sha1) + bytes(Original, 'utf-8')
Signature2 = base64.b64encode(Signature) Signature2 = base64.b64encode(Signature)
return str(Signature2, 'UTF-8') return str(Signature2, 'UTF-8')
def getPlayCode(fileId:str):
currentTimeStamp = int(time.time())
Original = {
"appId": appId,
"fileId": fileId,
"currentTimeStamp": currentTimeStamp,
"pcfg": "basicDrmPreset",
}
print(Original)
return jwt.encode(Original, referKey, algorithm='HS256')
def startSeVideo(fileId:str):
"""
开始加密视频
"""
try:
client = initClient()
req = models.ProcessMediaByProcedureRequest()
params = {
"FileId":field,
"ProcedureName":"myAesEncryptPreset"
}
req.from_json_string(json.dumps(params))
resp = client.ProcessMediaByProcedure(req)
return doResponse(resp)
except TencentCloudSDKException as err:
print(err)

View File

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

View File

@ -1,20 +1,20 @@
from .settings import * from .settings import *
DEBUG = True DEBUG = True
DATABASES = { DATABASES = {
'default': { # 'default': {
'ENGINE': 'django.db.backends.postgresql', # 'ENGINE': 'django.db.backends.postgresql',
'NAME': 'cma', # 'NAME': 'cma',
'USER': 'postgres', # 'USER': 'postgres',
'PASSWORD': 'zctest1234', # 'PASSWORD': 'zctest1234',
'HOST': '47.95.0.242', # 'HOST': '47.95.0.242',
'PORT': '5432', # 'PORT': '5432',
} # }
# 'default': { 'default': {
# 'ENGINE': 'django.db.backends.postgresql', 'ENGINE': 'django.db.backends.postgresql',
# 'NAME': 'cma', 'NAME': 'cma',
# 'USER': 'cma', 'USER': 'cma',
# 'PASSWORD': 'cma123', 'PASSWORD': 'cma123',
# 'HOST': '172.16.80.102', 'HOST': '172.16.80.102',
# 'PORT': '5432', 'PORT': '5432',
# } }
} }

View File

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