feat: 知识报送审批,统计分析页面开发

dev_1.0.0
xiangcongshuai 11 months ago
parent d031087ddc
commit 601ade4309

@ -48,3 +48,34 @@ export const queryKnowledgeDetail = (data?: object) => {
params: data
});
};
/** 撤回知识库( */
export const recallKnowledge = (data?: object) => {
return http.request("get", "/know-sub/knowledge/recallKnowledge", {
params: data
});
};
/** 撤回知识库( */
export const queryKnowledgeFlowRecord = (data?: object) => {
return http.request(
"get",
"/know-sub/knowledgeFlow/queryKnowledgeFlowRecord",
{
params: data
}
);
};
/** 分页查询知识审批流程( */
export const queryKnowledgeFlowPage = (data?: object) => {
return http.request("get", "/know-sub/knowledgeFlow/queryKnowledgeFlowPage", {
params: data
});
};
/** 审批知识流程(*/
export const processKnowledgeFlow = (data?: object) => {
return http.request("post", "/know-sub/knowledgeFlow/processKnowledgeFlow", {
data
});
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

@ -15,6 +15,19 @@ export default {
meta: {
title: "流程配置",
showLink: true,
showParent: true,
roles: ["admin", "common"]
}
},
{
path: "/businessManagement/statisticAnalysis",
name: "statisticAnalysis",
component: () =>
import("@/views/businessManagement/statisticAnalysis/index.vue"),
meta: {
title: "统计分析",
showLink: true,
showParent: true,
roles: ["admin", "common"]

@ -14,6 +14,7 @@ import {
sessionKey,
setUserInfo
} from "@/utils/auth";
import { useTabsStore } from "./tabs";
export const useUserStore = defineStore({
id: "pure-user",
@ -62,6 +63,8 @@ export const useUserStore = defineStore({
removeToken();
useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
resetRouter();
const tabs = useTabsStore();
tabs.clearTabs();
router.push("/login");
},
/** 刷新`token` */

@ -0,0 +1,64 @@
<template>
<div style="width: 100%; height: 100%">
<div class="chart-style" style="width: 100%; height: 100%">
<vue-chart :option="chartOption" style="width: 100%; height: 100%" />
</div>
</div>
</template>
<script lang="ts" setup>
import VueChart from "./VueChart.vue";
// import * as echarts from "echarts";
import { computed } from "vue";
const props = defineProps({
month_data: {
type: Array,
default: () => []
},
day_data: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
}
});
const total_data = computed(() => {
if (!props.data || props.data.length === 0) {
return 0;
} else {
return props.data.reduce(function (sum, item: any) {
return sum + item.value;
}, 0);
}
});
// function customLabelFormatter(params) {
// const text = params.value.toString();
// const coloredText = text.replace(
// /\d+/g,
// '<span style="color: blue;">$&</span>'
// ); //
// return coloredText;
// }
const chartOption = computed(() => {
return {
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
},
yAxis: {
type: "value"
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: "bar"
}
]
};
});
</script>

@ -0,0 +1,57 @@
<template>
<div style="width: 100%; height: 100%">
<div class="chart-style" style="width: 100%; height: 100%">
<vue-chart :option="chartOption" style="width: 100%; height: 100%" />
</div>
</div>
</template>
<script lang="ts" setup>
import VueChart from "./VueChart.vue";
import { computed } from "vue";
const props = defineProps({
month_data: {
type: Array,
default: () => []
},
day_data: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
}
});
const name_list = computed(() => {
return props.data.map((item: any) => {
return item.name;
});
});
const value_list = computed(() => {
return props.data.map((item: any) => {
return item.value;
});
});
const chartOption = computed(() => {
return {
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
},
yAxis: {
type: "value"
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: "line",
smooth: true
}
]
};
});
</script>

@ -0,0 +1,85 @@
<template>
<div style="width: 100%; height: 100%">
<div class="chart-style" style="width: 100%; height: 100%">
<vue-chart :option="chartOption" style="width: 100%; height: 100%" />
</div>
</div>
</template>
<script lang="ts" setup>
import VueChart from "./VueChart.vue";
// import * as echarts from "echarts";
import { computed } from "vue";
const props = defineProps({
month_data: {
type: Array,
default: () => []
},
day_data: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
}
});
const total_data = computed(() => {
if (!props.data || props.data.length === 0) {
return 0;
} else {
return props.data.reduce(function (sum, item: any) {
return sum + item.value;
}, 0);
}
});
// function customLabelFormatter(params) {
// const text = params.value.toString();
// const coloredText = text.replace(
// /\d+/g,
// '<span style="color: blue;">$&</span>'
// ); //
// return coloredText;
// }
const chartOption = computed(() => {
return {
tooltip: {
trigger: "item"
},
legend: {
top: "5%",
left: "center"
},
series: [
{
name: "Access From",
type: "pie",
radius: ["40%", "70%"],
avoidLabelOverlap: false,
label: {
show: false,
position: "center"
},
color: ["#15D5FF", "#3BF0FF"],
emphasis: {
label: {
show: true,
fontSize: 28,
fontWeight: "600"
}
},
labelLine: {
show: false
},
data: [
{ value: 1048, name: "待审批" },
{ value: 735, name: "已审批" }
]
}
]
};
});
</script>

@ -0,0 +1,36 @@
<template>
<div ref="elChart" style="width: 100%; height: 100%" />
</template>
<script lang="ts" setup>
import { ref, onMounted, onUpdated, onUnmounted } from "vue";
import * as echarts from "echarts";
const props = defineProps({
option: {
type: Object
},
data: {
type: Object
}
});
const elChart = ref();
let chart: any = null;
function clear() {
chart && chart.dispose();
}
function draw() {
if (chart) {
chart.setOption(props.option);
} else {
clear();
chart = echarts.init(elChart.value);
chart.setOption(props.option);
}
}
onMounted(draw);
onUpdated(draw);
onUnmounted(clear);
</script>

@ -0,0 +1,252 @@
<script setup lang="ts">
import statisticIcon from "@/assets/knowledge/statistic.png";
import questionIcon from "@/assets/knowledge/question.png";
import upIcon from "@/assets/knowledge/up.png";
import PieChart from "./compontents/PieChart.vue";
import downIcon from "@/assets/knowledge/down.png";
import LineChat from "./compontents/LineChat.vue";
import ColumnarChat from "./compontents/ColumnarChat.vue";
import { ref } from "vue";
defineOptions({
name: "statisticAnalysis"
});
const timeType = ref("1");
const dataList = ref([]);
</script>
<template>
<div class="statisticAnalysis">
<div class="statisticAnalysis-nav">
<div class="nav-item actived">
<img :src="statisticIcon" alt="" />
<span>知识统计</span>
</div>
<div class="nav-item">
<img :src="questionIcon" alt="" />
<span>问题统计</span>
</div>
</div>
<div class="statisticAnalysis-main">
<div class="data-view">
<div class="data-view-pie">
<PieChart />
</div>
<div class="data-view-content">
<div class="header">报送知识数据概览</div>
<div class="content-list">
<div style="background: #e8f1ff" class="content-list-item">
<span style="color: rgba(20, 109, 255, 0.8)" class="title"
>全部知识</span
>
<span style="color: #146dff" class="num">75,485</span>
<span class="desc"
>环比下降3%
<img :src="downIcon" alt="" />
</span>
</div>
<div style="background: #fff3ea" class="content-list-item">
<span style="color: rgba(255, 126, 44, 0.8)" class="title"
>全部知识</span
>
<span style="color: #ff7e2c" class="num">75,485</span>
<span class="desc"
>环比下降3%
<img :src="upIcon" alt="" />
</span>
</div>
<div style="background: #e7f6ff" class="content-list-item">
<span style="color: rgba(14, 162, 255, 0.8)" class="title"
>全部知识</span
>
<span style="color: #0ea2ff" class="num">75,485</span>
<span class="desc"
>环比下降3%
<img :src="downIcon" alt="" />
</span>
</div>
<div style="background: #f2f1ff" class="content-list-item">
<span style="color: rgba(120, 112, 247, 0.8)" class="title"
>全部知识</span
>
<span style="color: #7870f7" class="num">75,485</span>
<span class="desc"
>环比下降3%
<img :src="downIcon" alt="" />
</span>
</div>
</div>
</div>
</div>
<div class="chart-card">
<div class="chart-card-header">
<span>知识报送数量</span>
<div class="chart-card-header-time">
<el-radio-group v-model="timeType" size="large">
<el-radio-button label="本月" value="1" />
<el-radio-button label="近6个月" value="2" />
<el-radio-button label="全年" value="3" />
</el-radio-group>
<el-date-picker
size="large"
class="ml-4"
v-model="dataList"
type="daterange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</div>
</div>
<div class="chart-card-content">
<div class="left">
<LineChat />
</div>
<div class="right">
<ColumnarChat />
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.statisticAnalysis {
display: flex;
margin: 0 80px;
.statisticAnalysis-nav {
padding-top: 8px;
width: 136px;
height: calc(100vh - 200px);
background: #ffffff;
border-radius: 8px 8px 8px 8px;
flex-direction: column;
align-items: center;
display: flex;
.nav-item {
width: 120px;
height: 104px;
background: #ffffff;
border-radius: 6px 6px 6px 6px;
margin-bottom: 16px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
img {
width: 40px;
height: 40px;
}
span {
font-size: 18px;
color: #0052d9;
margin-top: 8px;
}
}
.actived {
background: #0052d9;
span {
font-size: 18px;
color: #ffffff;
}
}
}
.statisticAnalysis-main {
flex: 1;
margin-left: 16px;
.data-view {
display: flex;
flex-direction: row-reverse;
.data-view-pie {
width: 284px;
// height: 288px;
background: #ffffff;
border-radius: 8px 8px 8px 8px;
}
.data-view-content {
margin-right: 16px;
background: #ffffff;
border-radius: 8px 8px 8px 8px;
flex: 1;
padding: 24px;
display: flex;
flex-direction: column;
.header {
font-weight: bold;
font-size: 20px;
color: #333333;
}
.content-list {
margin-top: 24px;
display: flex;
justify-content: space-between;
.content-list-item {
display: flex;
width: 100%;
padding: 32px;
flex-direction: column;
border-radius: 6px 6px 6px 6px;
margin-right: 16px;
.title {
font-weight: 400;
font-size: 20px;
}
.num {
margin-top: 8px;
font-weight: bold;
font-size: 36px;
}
.desc {
display: flex;
margin-top: 34px;
font-size: 16px;
color: #666666;
align-items: center;
img {
width: 20px;
height: 12px;
margin-left: 6px;
}
}
}
}
}
}
.chart-card {
padding: 0 24px;
background: #ffffff;
border-radius: 8px 8px 8px 8px;
margin-top: 16px;
height: calc(100vh - 535px);
display: flex;
flex-direction: column;
.chart-card-header {
display: flex;
height: 70px;
align-items: center;
justify-content: space-between;
span {
font-weight: bold;
font-size: 20px;
color: #333333;
}
.chart-card-header-time {
display: flex;
align-items: center;
}
}
.chart-card-content {
display: flex;
flex: 1;
.left {
width: 50%;
}
.right {
flex: 1;
}
}
}
}
}
</style>

@ -33,37 +33,55 @@
<script setup lang="ts">
import { ref } from "vue";
import successIcon from "@/assets/knowledge/success.png";
import { message } from "@/utils/message";
const dialogVisible = ref(false);
const reason = ref("");
const todoId = ref("");
const id = ref("");
defineExpose({
open(row) {
open(val1, val2) {
dialogVisible.value = true;
id.value = val1;
todoId.value = val2;
}
});
const closeDialog = () => {
dialogVisible.value = false;
};
const emit = defineEmits(["approvalOk"]);
const submit = () => {
emit("approvalOk", id.value, todoId.value);
closeDialog();
};
</script>
<style lang="scss" scoped>
.Approved-header {
display: flex;
align-items: center;
padding: 0 24px;
height: 76px;
border-bottom: 1px solid rgba(91, 139, 255, 0.3);
position: relative;
width: 100%;
span {
font-weight: bold;
font-size: 20px;
color: #333333;
.Approved {
background: linear-gradient(180deg, #e1ecfe 0%, #ffffff 30%);
.Approved-header {
display: flex;
align-items: center;
padding: 0 24px;
margin-top: 24px;
// border-bottom: 1px solid rgba(91, 139, 255, 0.3);
position: relative;
width: 100%;
span {
font-weight: bold;
font-size: 20px;
color: #333333;
}
img {
width: 28px;
height: 28px;
margin-right: 16px;
}
}
img {
width: 28px;
height: 28px;
margin-right: 16px;
.Approved-content {
font-size: 16px;
color: #666666;
margin-left: 40px;
}
}
:deep(.el-dialog__header) {
padding: 0;
margin: 0;

@ -0,0 +1,104 @@
<template>
<el-dialog
width="600"
append-to-body
v-model="dialogVisible"
:center="true"
custom-class="reject"
><!-- 使用自定义头部组件 -->
<template v-slot:header>
<div class="reject-header">
<img :src="warnIcon" alt="" />
<span>如果您确定驳回请填写驳回原因</span>
</div>
</template>
<div class="reject-content">
<div class="label">撤回原因</div>
<el-input
v-model="reason"
maxlength="200"
:rows="4"
placeholder="请输入"
show-word-limit
type="textarea"
/>
<div class="footer-btn">
<div class="cancel_btn" @click="dialogVisible = false">取消</div>
<!-- <div class="determine_btn">确定</div> -->
<el-button
size="large"
@click="submit"
style="width: 140px; margin: 0"
class="footer-btn"
type="primary"
>确定</el-button
>
</div>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from "vue";
import warnIcon from "@/assets/knowledge/warn.png";
import { message } from "@/utils/message";
const dialogVisible = ref(false);
const reason = ref("");
const todoId = ref("");
const id = ref("");
defineExpose({
open(val1, val2) {
dialogVisible.value = true;
id.value = val1;
todoId.value = val2;
}
});
const closeDialog = () => {
dialogVisible.value = false;
};
const emit = defineEmits(["RejectApprovalOk"]);
const submit = () => {
if (reason.value) {
emit("RejectApprovalOk", id.value, todoId.value, reason.value);
closeDialog();
} else {
message("请填写原因", { type: "error" });
}
};
</script>
<style lang="scss" scoped>
.reject-header {
display: flex;
align-items: center;
padding: 0 24px;
height: 76px;
border-bottom: 1px solid rgba(91, 139, 255, 0.3);
position: relative;
width: 100%;
span {
font-weight: bold;
font-size: 20px;
color: #333333;
}
img {
width: 28px;
height: 28px;
margin-right: 16px;
}
}
:deep(.el-dialog__header) {
padding: 0;
margin: 0;
}
.reject-content {
.label {
font-size: 16px;
color: #333333;
margin-bottom: 16px;
}
.desc {
margin-top: 8px;
font-size: 14px;
color: #b4b4b4;
}
}
</style>

@ -1,28 +1,61 @@
<script setup lang="ts">
import { reactive, ref } from "vue";
import { onActivated, onMounted, reactive, ref } from "vue";
import { ArrowDown } from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import TransferRecords from "../compontents/TransferRecords.vue";
import Details from "../compontents/Details.vue";
import Approved from "./compontents/Approved.vue";
import RejectApproval from "./compontents/RejectApproval.vue";
import {
processKnowledgeFlow,
queryApplicationSubLibrary,
queryDeptManageList,
queryKnowledgeFlowPage
} from "@/api/knowledgeCentre";
import { useKnowledgeCentreStoreHooks } from "@/store/modules/knowledgeCentre";
import { clearObject } from "@/utils/auth";
import { message } from "@/utils/message";
defineOptions({
name: "approval"
});
const loading = ref(false);
const seachForm = reactive({
title: "",
publishDeptName: "",
status: ""
submittedDeptId: "",
processStatus: "1",
baseId: "",
publishDateBegin: "",
publishDateEnd: "",
time: []
});
const flowTypeList = ref([
{
key: "1",
name: "知识报送"
},
{
key: "2",
name: "知识撤回"
},
{
key: "3",
name: "知识删除"
}
]);
const ApprovedRef = ref();
const RejectApprovalRef = ref();
const departmentList = ref([]);
const applicationSubLibrary = ref([]);
const TransferRecordRef = ref();
const DetailsRef = ref();
const tabList = ref([
{
title: "待审批",
id: ""
id: "1"
},
{
title: "已审批",
id: "1"
id: "2"
}
]);
const pagination = reactive({
@ -37,21 +70,44 @@ const columns: TableColumnList = [
width: 55
},
{
label: "ID",
prop: "diseaseName"
label: "序号",
type: "index",
width: 80
},
{
label: "知识标题",
prop: "title",
slot: "titleSlot"
},
{
label: "审核类型",
prop: "flowType",
formatter: ({ flowType }) => {
return flowType === "1"
? "知识报送"
: flowType === "2"
? "知识撤回"
: "知识删除";
}
},
{
label: "发文部门",
prop: "diseaseName"
prop: "submitDeptName"
},
{
label: "状态",
prop: "diseaseName"
label: "报送人",
prop: "submitUserName"
},
{
label: "知识来源",
prop: "knowledgeFrom",
formatter: ({ knowledgeFrom }) => {
return knowledgeFrom === 1 ? "人工添加" : "";
}
},
{
label: "报送部门",
prop: "submitDeptName"
},
{
label: "最新时间",
@ -71,15 +127,21 @@ const dataList = ref([
}
]);
const getData = async () => {
// const params = {
// pageNum: pagination.currentPage,
// pageSize: pagination.pageSize,
// diseaseName: seachForm.diseaseName,
// diseaseType: seachForm.diseaseType
// };
// const res: any = await queryPageList(params);
// dataList.value = res.data.records;
// pagination.total = res.data.total;
if (seachForm.time && seachForm.time.length > 0) {
seachForm.publishDateBegin = seachForm.time[0];
seachForm.publishDateEnd = seachForm.time[1];
} else {
seachForm.publishDateBegin = "";
seachForm.publishDateEnd = "";
}
const params = {
pageNum: pagination.currentPage,
pageSize: pagination.pageSize,
...seachForm
};
const res: any = await queryKnowledgeFlowPage(params);
dataList.value = res.data.records;
pagination.total = res.data.total;
};
function handleSizeChange(val: number) {
pagination.pageSize = val;
@ -97,43 +159,164 @@ const search = () => {
};
const reset = () => {
seachForm.title = "";
seachForm.publishDeptName = "";
clearObject(seachForm);
search();
};
const handleCommand = command => {
console.log("Command", command);
};
const changeStatus = item => {
seachForm.status = item.id;
seachForm.processStatus = item.id;
};
const add = () => {
router.push("/knowledgeCentre/addSubmission");
};
const openRecords = () => {
TransferRecordRef.value.open();
const openRecords = row => {
TransferRecordRef.value.open(row.id, row.title);
};
const openDetails = row => {
DetailsRef.value.open(row);
};
const getDepartmentList = async () => {
const res: any = await queryDeptManageList({
pageNum: 1,
pageSize: 999999
});
if (res.code === 200) {
departmentList.value = res.data.records;
useKnowledgeCentreStoreHooks().getDepartmentList(departmentList.value);
}
};
const getApplicationSubLibrary = async () => {
const res: any = await queryApplicationSubLibrary({
pageNum: 1,
pageSize: 999999
});
if (res.code === 200) {
applicationSubLibrary.value = res.data.records;
useKnowledgeCentreStoreHooks().getApplicationSubLibrary(
applicationSubLibrary.value
);
}
};
const openApproval = row => {
ApprovedRef.value.open(row.knowledgeId, row.todoId);
};
const openRejectApproval = row => {
RejectApprovalRef.value.open(row.knowledgeId, row.todoId);
};
const approvalOk = async (id, todoId) => {
const res: any = await processKnowledgeFlow({
operate: 1,
knowledgeId: id,
todoId
});
if (res.code === 200) {
message("审批成功!", { type: "success" });
search();
}
};
const RejectApprovalOk = async (id, todoId) => {
const res: any = await processKnowledgeFlow({
operate: 2,
knowledgeId: id,
todoId
});
if (res.code === 200) {
message("驳回成功!", { type: "success" });
search();
}
};
onActivated(() => {
search();
});
onMounted(() => {
getDepartmentList();
getApplicationSubLibrary();
getData();
});
</script>
<template>
<div class="submission app-main-content">
<div class="approval app-main-content">
<div class="seach">
<div class="seach-title"><span>知识审批</span></div>
<el-form :model="seachForm">
<el-form label-width="100px" :model="seachForm">
<el-row>
<el-col :span="8">
<el-form-item label="知识标题">
<el-input size="large" v-model="seachForm.title" /> </el-form-item
></el-col>
<el-col :span="8"
><el-form-item label="报送人部门">
<el-select
size="large"
style="width: 100%"
filterable
v-model="seachForm.submittedDeptId"
placeholder="请选择"
>
<el-option
v-for="item in departmentList"
:key="item.id"
:label="item.deptName"
:value="item.id"
/>
</el-select> </el-form-item
></el-col>
<el-col :span="8"
><el-form-item label="应用子库">
<el-select
style="width: 100%"
size="large"
filterable
v-model="seachForm.baseId"
placeholder="请选择"
>
<el-option
v-for="item in applicationSubLibrary"
:key="item.id"
:label="item.baseName"
:value="item.id"
/>
</el-select> </el-form-item
></el-col>
</el-row>
<el-row>
<el-form-item label="知识标题">
<el-input v-model="seachForm.title" />
</el-form-item>
<el-form-item class="ml-4" label="发文部门">
<el-input v-model="seachForm.publishDeptName" />
</el-form-item>
<el-button class="ml-8" @click="search" type="primary"
<el-col :span="8"
><el-form-item label="审核类型">
<el-select
style="width: 100%"
size="large"
filterable
v-model="seachForm.baseId"
placeholder="请选择"
>
<el-option
v-for="item in flowTypeList"
:key="item.key"
:label="item.name"
:value="item.key"
/>
</el-select> </el-form-item
></el-col>
<el-col :span="8">
<el-form-item label="发文时间">
<el-date-picker
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
v-model="seachForm.time"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择"
size="large" /></el-form-item
></el-col>
<el-button size="large" class="ml-8" @click="search" type="primary"
>搜索</el-button
>
<el-button @click="reset"></el-button>
<el-button size="large" @click="reset"></el-button>
</el-row>
</el-form>
</div>
@ -142,7 +325,7 @@ const openDetails = row => {
<div class="tab-list">
<div
class="tab-list-item"
:class="[seachForm.status === item.id ? 'actived' : '']"
:class="[seachForm.processStatus === item.id ? 'actived' : '']"
v-for="(item, index) in tabList"
:key="index"
@click="changeStatus(item)"
@ -150,10 +333,10 @@ const openDetails = row => {
<span>{{ item.title }}</span>
</div>
</div>
<div class="header-btn">
<!-- <div class="header-btn">
<el-button @click="add" type="primary">批量通过</el-button>
<el-button @click="add" type="primary">批量驳回</el-button>
</div>
</div> -->
</div>
<pure-table
showOverflowTooltip
@ -163,8 +346,18 @@ const openDetails = row => {
background: 'var(--el-table-row-hover-bg-color)',
color: 'var(--el-text-color-primary)'
}"
adaptive
:pagination="pagination"
@page-size-change="handleSizeChange"
@page-current-change="handleCurrentChange"
>
<template #operation="{ row }">
<el-button link type="primary" @click="openApproval(row)">
审批
</el-button>
<el-button link type="primary" @click="openRejectApproval(row)">
驳回
</el-button>
<el-button link type="primary" @click="openRecords(row)">
流转记录
</el-button>
@ -178,10 +371,18 @@ const openDetails = row => {
</div>
<TransferRecords ref="TransferRecordRef" />
<Details ref="DetailsRef" />
<Approved @approvalOk="approvalOk" ref="ApprovedRef" />
<RejectApproval
@RejectApprovalOk="RejectApprovalOk"
ref="RejectApprovalRef"
/>
</div>
</template>
<style lang="scss" scoped>
.submission {
.approval {
:deep(.el-form-item) {
align-items: center;
}
.main-table-header {
display: flex;
margin-bottom: 24px;

@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref } from "vue";
import { queryKnowledgeDetail } from "@/api/knowledgeCentre";
import { reactive } from "vue";
defineOptions({
name: "SubmissionDetails"
});
@ -11,11 +12,45 @@ const annexList = ref([
name: "PDF附件名称显示全部点击下载附件"
}
]);
const formData = reactive({
knowledge: {
publishDeptId: "",
knowledgeFrom: undefined,
title: ""
},
knowledgeInfo: {
territory: "",
publishDate: "",
autoLoseEffect: undefined,
execTimeBegin: "",
execTimeEnd: "",
knowledgeTag: "",
policyType: "",
publishScope: undefined
},
knowledgeContext: {
context: ""
},
fileInfoList: []
});
defineExpose({
open(row) {
open(val) {
dialogVisible.value = true;
getDeatils(val);
}
});
const getDeatils = async id => {
const res: any = await queryKnowledgeDetail({
knowledgeId: id
});
for (const key in res.data) {
// eslint-disable-next-line no-prototype-builtins
if (formData.hasOwnProperty(key)) {
formData[key] = res.data[key];
}
}
};
const closeDialog = () => {
dialogVisible.value = false;
@ -43,55 +78,66 @@ const closeDialog = () => {
<div class="basicInfo">
<div class="basicInfo_title">基本信息</div>
<div class="basicInfo_item">
<span>{{ `发文部门:部门1` }}</span>
<span>{{ `发文部门:${formData.knowledge.publishDeptId}` }}</span>
</div>
<div class="basicInfo_item">
<span>{{ `显示来源:暂无` }}</span>
<span v-if="formData.knowledge.knowledgeFrom === 1">{{
`显示来源:人工添加`
}}</span>
<span v-else>{{ `` }}</span>
</div>
<div class="basicInfo_item">
<span>{{ `所属地区:深圳` }}</span>
<span>{{ `所属地区:${formData.knowledgeInfo.territory}` }}</span>
</div>
<div class="basicInfo_item">
<span>{{ `发布日期2023年2月23日` }}</span>
<span>{{
`发布日期:${formData.knowledgeInfo.publishDate}`
}}</span>
</div>
<div class="basicInfo_item">
<span>{{ `时效性:长期有效` }}</span>
<span v-if="formData.knowledgeInfo.autoLoseEffect === 1">{{
`时效性:长期有效`
}}</span>
<span v-if="formData.knowledgeInfo.autoLoseEffect === 2">{{
`时效性:临时有效`
}}</span>
</div>
<div class="basicInfo_item">
<span>{{ `执行期限:系统带出` }}</span>
<div
v-if="formData.knowledgeInfo.autoLoseEffect === 2"
class="basicInfo_item"
>
<span>{{
`执行期限:${formData.knowledgeInfo.execTimeBegin} ~ ${formData.knowledgeInfo.execTimeEnd}`
}}</span>
</div>
<div class="basicInfo_item">
<span>{{
`知识标签:系统带出系统带出系统带出系统带出系统带出系统带出`
`知识标签:${formData.knowledgeInfo.knowledgeTag}`
}}</span>
</div>
<div class="basicInfo_item">
<span>{{ `政策类型:系统带出` }}</span>
<span>{{
`政策类型:${formData.knowledgeInfo.policyType}`
}}</span>
</div>
<div class="basicInfo_item">
<span>{{ `公开范围:公开` }}</span>
<span v-if="formData.knowledgeInfo.publishScope === 1">{{
`公开范围:公开`
}}</span>
<span v-else>{{ `` }}</span>
</div>
</div>
<div class="main-content">
<div class="content-title">标题打造高效物流体系 畅通经济发展</div>
<div class="text">
知识详情市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向以企业为主体着眼于未来发展和区位优势结合实际谋划好物流产业发展规划全面推进现代物流与产业融合发展
市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向以企业为主体着眼于未来发展和区位优势结合实际谋划好物流产业发展规划全面推进现代物流与产业融合发展
市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向以企业为主体着眼于未来发展和区位优势结合实际谋划好物流产业发展规划全面推进现代物流与产业融合发展
市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向以企业为主体着眼于未来发展和区位优势结合实际谋划好物流产业发展规划全面推进现代物流与产业融合发展
市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向
市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向
今年以来高唐经济开发区以市场为导向
市第十四次代表大会中指出以数字经济蓄势赋能推进数字产业化加快发展大数据云计算网络技术等产业打造一批工业互联网平台和数字经济园区大力发展现代服务业加快推进现代服务业与先进制造业深度融合完善现代物流体系今年以来高唐经济开发区以市场为导向
</div>
<div class="content-title">{{ formData.knowledge.title }}</div>
<div class="text" v-html="formData.knowledgeContext.context" />
<div class="annex">
<div
class="annex_item"
v-for="(item, index) in annexList"
v-for="(item, index) in formData.fileInfoList"
:key="index"
>
<span>{{ `附件${index + 1}: ` }}</span>
<span class="link">{{ item.name }}</span>
<span class="link">{{ item.fileName }}</span>
</div>
</div>
</div>

@ -1,56 +1,18 @@
<script setup lang="ts">
import { ref } from "vue";
import { queryKnowledgeFlowRecord } from "@/api/knowledgeCentre";
defineOptions({
name: "TransferRecords"
});
const dialogVisible = ref(false);
const recordList = ref([
{
title: "知识报送",
status: 0,
time: "2024-03-12 12:24:23",
name: "刘小华",
department: "深圳市人力资源和社会保障局",
desc: "说明说明说明说明说明说明说明说明说明"
},
{
title: "驳回",
status: 1,
time: "2024-03-12 12:24:23",
name: "刘小华",
department: "深圳市人力资源和社会保障局",
desc: "说明说明说明说明说明说明说明说明说明"
},
{
title: "知识报送",
status: 0,
time: "2024-03-12 12:24:23",
name: "刘小华",
department: "深圳市人力资源和社会保障局",
desc: "说明说明说明说明说明说明说明说明说明"
},
{
title: "通过",
status: 2,
time: "2024-03-12 12:24:23",
name: "刘小华",
department: "深圳市人力资源和社会保障局",
desc: "说明说明说明说明说明说明说明说明说明"
},
{
title: "知识撤回",
status: 3,
time: "2024-03-12 12:24:23",
name: "刘小华",
department: "深圳市人力资源和社会保障局",
desc: "说明说明说明说明说明说明说明说明说明"
}
]);
const recordList = ref([]);
const title = ref("");
defineExpose({
open() {
open(id, name) {
dialogVisible.value = true;
title.value = name;
getDetails(id);
}
});
@ -63,6 +25,12 @@ const getStatusColor = index => {
borderColor: colorList[index]
};
};
const getDetails = async id => {
const res: any = await queryKnowledgeFlowRecord({
knowledgeId: id
});
recordList.value = res.data;
};
</script>
<template>
@ -83,7 +51,7 @@ const getStatusColor = index => {
</div>
<div class="line" />
<div class="content">
<div class="content-title">知识标题知识标题</div>
<div class="content-title">{{ title }}</div>
<div class="record_list">
<div
class="record_list_item"
@ -102,20 +70,20 @@ const getStatusColor = index => {
</div>
<div class="step_content">
<div class="step_content_head">
<span>{{ item.title }}</span>
<span class="time">{{ item.time }}</span>
<span>{{ item.processName }}</span>
<span class="time">{{ item.processTime }}</span>
</div>
<div class="step_content_item">
<span class="label">姓名</span>
<div class="value">{{ item.name }}</div>
<div class="value">{{ item.processUserName }}</div>
</div>
<div class="step_content_item">
<span class="label">部门</span>
<div class="value">{{ item.department }}</div>
<div class="value">{{ item.processDeptName }}</div>
</div>
<div class="step_content_item">
<span class="label">说明</span>
<div class="value">{{ item.desc }}</div>
<div class="value">{{ item.remark }}</div>
</div>
</div>
</div>

@ -43,16 +43,28 @@
<script setup lang="ts">
import { ref } from "vue";
import warnIcon from "@/assets/knowledge/warn.png";
import { message } from "@/utils/message";
const dialogVisible = ref(false);
const reason = ref("");
const id = ref("");
defineExpose({
open(row) {
open(val) {
id.value = val;
dialogVisible.value = true;
}
});
const closeDialog = () => {
dialogVisible.value = false;
};
const emit = defineEmits(["withdrawOk"]);
const submit = () => {
if (reason.value) {
emit("withdrawOk", id.value, reason.value);
closeDialog();
} else {
message("请填写原因", { type: "error" });
}
};
</script>
<style lang="scss" scoped>
.withdraw-header {

@ -11,7 +11,8 @@ import {
queryKnowledgePage,
queryDeptManageList,
queryApplicationSubLibrary,
deleteKnowledge
deleteKnowledge,
recallKnowledge
} from "@/api/knowledgeCentre";
import { clearObject } from "@/utils/auth";
import { onMounted } from "vue";
@ -87,7 +88,7 @@ const tabList = ref([
},
{
title: "待审批",
id: "2"
id: "9"
},
{
title: "驳回",
@ -211,6 +212,7 @@ const reset = () => {
};
const changeStatus = item => {
seachForm.status = item.id;
search();
};
const add = () => {
router.push("/knowledgeCentre/addSubmission");
@ -223,11 +225,11 @@ const handleEdit = row => {
}
});
};
const openRecords = () => {
TransferRecordRef.value.open();
const openRecords = row => {
TransferRecordRef.value.open(row.id, row.title);
};
const openDetails = row => {
DetailsRef.value.open(row);
DetailsRef.value.open(row.id);
};
const openWithdraw = row => {
withdrawRef.value.open(row);
@ -267,6 +269,16 @@ const del = async (id, val) => {
search();
}
};
const withdrawOk = async (id, val) => {
const res: any = await recallKnowledge({
knowledgeId: id,
remark: val
});
if (res.code === 200) {
message("撤回成功", { type: "success" });
search();
}
};
onActivated(() => {
search();
});
@ -286,7 +298,7 @@ onMounted(() => {
<el-col :span="8">
<el-form-item label="知识标题">
<el-input
style="width: 390px"
style="width: 100%"
size="large"
v-model="seachForm.title"
/> </el-form-item
@ -295,7 +307,7 @@ onMounted(() => {
><el-form-item label="发文部门">
<el-select
size="large"
style="width: 390px"
style="width: 100%"
filterable
v-model="seachForm.publishDeptId"
placeholder="请选择"
@ -312,7 +324,7 @@ onMounted(() => {
><el-form-item label="应用子库">
<el-select
size="large"
style="width: 390px"
style="width: 100%"
filterable
v-model="seachForm.baseId"
placeholder="请选择"
@ -330,7 +342,7 @@ onMounted(() => {
<el-col :span="8">
<el-form-item label="发文时间">
<el-date-picker
style="width: 390px"
style="width: 100%"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
@ -365,7 +377,7 @@ onMounted(() => {
<el-button @click="add" size="large" type="primary"
>新建报送</el-button
>
<el-dropdown trigger="click" class="ml-6">
<!-- <el-dropdown trigger="click" class="ml-6">
<div class="main-btn">
<span class="mr-3">批量操作</span>
<el-icon><ArrowDown style="color: #ffffff" /></el-icon>
@ -375,7 +387,7 @@ onMounted(() => {
<el-dropdown-item> 删除 </el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-dropdown> -->
</div>
</div>
<pure-table
@ -386,18 +398,37 @@ onMounted(() => {
background: 'var(--el-table-row-hover-bg-color)',
color: 'var(--el-text-color-primary)'
}"
adaptive
:pagination="pagination"
@page-size-change="handleSizeChange"
@page-current-change="handleCurrentChange"
>
<template #operation="{ row }">
<el-button link type="primary" @click="openRecords(row)">
流转记录
</el-button>
<el-button link type="primary" @click="handleEdit(row)">
<el-button
:disabled="row.modifyFlag === 0"
link
type="primary"
@click="handleEdit(row)"
>
编辑
</el-button>
<el-button link type="primary" @click="openWithdraw(row)">
<el-button
:disabled="row.recallFlag === 0"
link
type="primary"
@click="openWithdraw(row)"
>
撤回
</el-button>
<el-button link type="danger" @click="handleDelete(row)">
<el-button
:disabled="row.deleteFlag === 0"
link
type="danger"
@click="handleDelete(row)"
>
删除
</el-button>
</template>
@ -410,7 +441,7 @@ onMounted(() => {
</div>
<TransferRecords ref="TransferRecordRef" />
<Details ref="DetailsRef" />
<withdraw ref="withdrawRef" />
<withdraw @withdrawOk="withdrawOk" ref="withdrawRef" />
<KnowledgeDelete @delOk="del" ref="KnowledgeDeleteRef" />
</div>
</template>

Loading…
Cancel
Save