Browse Source

接入工作流

kagg886 2 months ago
parent
commit
2f8a56147e

+ 9 - 1
src/api/system/report/type.ts

@@ -1,7 +1,12 @@
 // 投诉区域枚举
 export type ComplaintArea = 'A区' | 'B区'
 
-export type ComplaintStatus = 'pending' | 'processing' | 'completed'
+export enum ComplaintStatus {
+	PENDING,
+	PROCESSING,
+	COMPLETED
+	// 'pending' | 'processing' | 'completed'
+}
 
 // 投诉实体类型
 export interface Complaint {
@@ -19,6 +24,9 @@ export interface Complaint {
 
   createdAt: string;
   updatedAt: string;
+
+	//FIXME: 流程控制需要
+	actionBtn: any;
 }
 
 export type CreateComplaintRequest = Pick<Complaint, 'title' | 'category' | 'source' | 'area' | 'complainantName' | 'contact' | 'level' | 'content'> & {

+ 17 - 11
src/views/system/report/componments/report-detail-dialog.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { computed, getCurrentInstance, ref, unref, watch } from 'vue'
-import { Complaint, ComplaintResolveHistoryInsertRequest } from '/@/api/system/report/type'
+import { Complaint, ComplaintResolveHistoryInsertRequest, ComplaintStatus } from '/@/api/system/report/type'
 import { useAsyncState } from '@vueuse/core'
 import complaint_resolve_history from '/@/api/system/report/complaint-resolve-history'
 import complaints from '/@/api/system/report/complaints'
@@ -116,13 +116,13 @@ const currentResolveStatus = computed(() => complaintResolveList.value.at(-1) ??
 const formatReportStatus = (value: Complaint['status']) => {
 	let a = '-'
 	switch (value) {
-		case 'completed':
+		case ComplaintStatus.COMPLETED:
 			a = '已完成'
 			break
-		case 'pending':
+		case ComplaintStatus.PENDING:
 			a = '待处理'
 			break
-		case 'processing':
+		case ComplaintStatus.PROCESSING:
 			a = '进行中'
 			break
 	}
@@ -132,14 +132,14 @@ const formatReportStatus = (value: Complaint['status']) => {
 const showUpdateForm = ref(false)
 const formComplaintResolve = ref<Omit<ComplaintResolveHistoryInsertRequest, 'ticketNo'>>({
 	description: '',
-	status: 'processing',
+	status: ComplaintStatus.PROCESSING,
 })
 
 const handleCancelUpdate = () => {
 	showUpdateForm.value = false
 	formComplaintResolve.value = {
 		description: '',
-		status: 'processing',
+		status: ComplaintStatus.PROCESSING,
 	}
 }
 
@@ -163,14 +163,14 @@ const { loading: createComplaintResolveLoading, doLoading: createComplaintResolv
 	ElMessage.success('处理状态更新成功')
 	formComplaintResolve.value = {
 		description: '',
-		status: 'processing',
+		status: ComplaintStatus.PROCESSING,
 	}
 	showUpdateForm.value = false
 })
 </script>
 
 <template>
-	<el-dialog v-model="visible" title="投诉详情" width="800px" :close-on-click-modal="false" @close="() => visible = false">
+	<el-dialog v-model="visible" title="投诉详情" width="800px" :close-on-click-modal="false" @close="() => (visible = false)">
 		<div class="complaint-detail">
 			<!-- 头部信息 -->
 			<div class="complaint-header" v-loading="complaintDetailLoading">
@@ -180,7 +180,13 @@ const { loading: createComplaintResolveLoading, doLoading: createComplaintResolv
 						{{ formatReportLevel(complaintDetail?.level) }}
 					</el-tag>
 					<el-tag
-						:type="complaintDetail?.status === 'pending' ? 'info' : complaintDetail?.status === 'processing' ? 'warning' : 'success'"
+						:type="
+							complaintDetail?.status === ComplaintStatus.PENDING
+								? 'info'
+								: complaintDetail?.status === ComplaintStatus.PROCESSING
+								? 'warning'
+								: 'success'
+						"
 						class="ml-2"
 					>
 						{{ formatReportStatus(complaintDetail?.status) }}
@@ -199,7 +205,7 @@ const { loading: createComplaintResolveLoading, doLoading: createComplaintResolv
 				</div>
 			</div>
 
-			<el-row :gutter="20" class="mt-4" >
+			<el-row :gutter="20" class="mt-4">
 				<!-- 左侧基本信息 -->
 				<el-col :span="14">
 					<el-card shadow="never" class="info-card">
@@ -213,7 +219,7 @@ const { loading: createComplaintResolveLoading, doLoading: createComplaintResolv
 						</template>
 
 						<div v-loading="complaintDetailLoading">
-							<el-row :gutter="16" class="info-row" >
+							<el-row :gutter="16" class="info-row">
 								<el-col :span="12">
 									<div class="info-item">
 										<span class="info-label">投诉类型</span>

+ 48 - 42
src/views/system/report/list/index.vue

@@ -1,22 +1,25 @@
 <script setup lang="ts">
-import { ref, onMounted, getCurrentInstance, unref, computed, watch } from 'vue'
+import { computed, getCurrentInstance, onMounted, ref, unref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { Search, Plus, Delete, View, Edit } from '@element-plus/icons-vue'
+import { Delete, Edit, Plus, Search, View } from '@element-plus/icons-vue'
 import { useLoading } from '/@/utils/loading-util'
 import complaints from '/@/api/system/report/complaints'
 import feedback_api from '/@/api/system/report/feedback'
 import {
+	Complaint,
+	ComplaintArea,
 	ComplaintQueryParams,
+	ComplaintStatus,
 	CreateComplaintRequest,
-	ComplaintArea,
-	UpdateComplaintRequest,
-	Complaint,
 	FeedbackCreateParams,
+	UpdateComplaintRequest,
 } from '/@/api/system/report/type'
 import system from '/@/api/system'
 import { useAsyncState, useLocalStorage } from '@vueuse/core'
 import ReportDetailDialog from '/@/views/system/report/componments/report-detail-dialog.vue'
-import { MessageParamsWithType, MessageProps } from 'element-plus/es/components/message/src/message'
+import { MessageProps } from 'element-plus/es/components/message/src/message'
+import { FlowDemoTableColumns } from '/@/views/flow/flowDemo/list/component/model'
+import CheckFlow from '/@/components/gFlow/checkFlow.vue'
 
 const { proxy } = getCurrentInstance() as any
 
@@ -62,13 +65,13 @@ const formatReportType = computed<(value: string) => string>(() => {
 const formatReportStatus = (value: Complaint['status']) => {
 	let a = '-'
 	switch (value) {
-		case 'completed':
+		case ComplaintStatus.COMPLETED:
 			a = '已完成'
 			break
-		case 'pending':
+		case ComplaintStatus.PENDING:
 			a = '待处理'
 			break
-		case 'processing':
+		case ComplaintStatus.PROCESSING:
 			a = '进行中'
 			break
 	}
@@ -78,13 +81,13 @@ const formatReportStatus = (value: Complaint['status']) => {
 const formatReportStatusTagType = (value: Complaint['status']) => {
 	let type: MessageProps['type'] | undefined = undefined
 	switch (value) {
-		case 'completed':
+		case ComplaintStatus.COMPLETED:
 			type = 'success'
 			break
-		case 'pending':
+		case ComplaintStatus.PENDING:
 			type = 'info'
 			break
-		case 'processing':
+		case ComplaintStatus.PROCESSING:
 			type = undefined
 			break
 	}
@@ -153,14 +156,14 @@ type CCRWithDemoFlag = Partial<CreateComplaintRequest> & {
 	flag: boolean | undefined
 }
 
-const demo = useLocalStorage<CCRWithDemoFlag>('system-report-summary-index-demo-params',{
-	flag: false
+const demo = useLocalStorage<CCRWithDemoFlag>('system-report-summary-index-demo-params', {
+	flag: false,
 })
 
-onMounted(()=> {
+onMounted(() => {
 	if (demo.value.flag !== undefined) {
 		addForm.value = {
-			...(demo.value as CreateComplaintRequest)
+			...(demo.value as CreateComplaintRequest),
 		}
 	}
 })
@@ -188,7 +191,7 @@ const handleAddCancel = () => {
 const handleDemoAdded = () => {
 	demo.value = {
 		...addForm.value,
-		flag: true
+		flag: true,
 	}
 	ElMessage.success('草稿已经保存')
 }
@@ -209,7 +212,7 @@ const handleAddConfirm = async () => {
 
 		//删除草稿
 		demo.value = {
-			flag: undefined
+			flag: undefined,
 		}
 
 		//关闭新增对话框
@@ -431,7 +434,10 @@ const { loading: createFeedbackLoading, doLoading: createFeedback } = useLoading
 	}
 
 	const result = await feedback_api
-		.create({ surveyCode: `${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDay()}-${(Math.random() * 100000).toFixed(0)}`, ...feedCreateForm.value })
+		.create({
+			surveyCode: `${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDay()}-${(Math.random() * 100000).toFixed(0)}`,
+			...feedCreateForm.value,
+		})
 		.then(() => true)
 		.catch(() => false)
 
@@ -448,6 +454,11 @@ const handleDetail = (row: Complaint) => {
 	showDetail.value = true
 }
 
+//发起审批
+const ckFlowRef = ref()
+const handleStartFlow = (row: FlowDemoTableColumns | null) => {
+	ckFlowRef.value.handleStartFlow(row)
+}
 </script>
 
 <template>
@@ -516,7 +527,7 @@ const handleDetail = (row: Complaint) => {
 			<!-- 表格 -->
 			<el-table :data="tableData" v-loading="loading" @selection-change="handleSelectionChange" style="width: 100%">
 				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column prop="id" label="标识" width="160" align="center"/>
+				<el-table-column prop="id" label="标识" width="160" align="center" />
 				<el-table-column prop="title" label="投诉标题" min-width="200" show-overflow-tooltip />
 				<el-table-column prop="category" label="投诉类型" width="120" align="center">
 					<template #default="{ row }: { row: Complaint }">
@@ -538,12 +549,11 @@ const handleDetail = (row: Complaint) => {
 				<el-table-column prop="assignee" label="分配给" width="120" align="center" />
 				<el-table-column label="操作" width="300" align="center" fixed="right">
 					<template #default="{ row }: { row: Complaint }">
-						<el-button
-							size="small"
-							type="primary"
-							link
-							@click="handleDetail(row)"
+						<el-button v-if="row.actionBtn && row.actionBtn.type != 'disabled'" type="primary" link @click="handleStartFlow(row)"
+							><el-icon><ele-Coordinate /></el-icon>{{ row.actionBtn.title }}</el-button
 						>
+
+						<el-button size="small" type="primary" link @click="handleDetail(row)">
 							<el-icon>
 								<View />
 							</el-icon>
@@ -585,7 +595,7 @@ const handleDetail = (row: Complaint) => {
 		<el-dialog v-model="addDialogVisible" title="新建投诉" width="800px" :close-on-click-modal="false">
 			<el-form ref="addFormRef" :model="addForm" :rules="addFormRules" label-width="100px" label-position="left">
 				<el-row :gutter="35">
-					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" >
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
 						<el-form-item label="投诉标题" prop="title" required>
 							<el-input v-model="addForm.title" placeholder="请输入投诉标题" maxlength="100" show-word-limit />
 						</el-form-item>
@@ -659,9 +669,7 @@ const handleDetail = (row: Complaint) => {
 			<template #footer>
 				<div class="dialog-footer">
 					<el-button @click="handleAddCancel">取消</el-button>
-					<el-button type="primary" @click="handleAddConfirm">
-						提交投诉
-					</el-button>
+					<el-button type="primary" @click="handleAddConfirm"> 提交投诉 </el-button>
 					<el-button @click="handleDemoAdded">保存草稿</el-button>
 				</div>
 			</template>
@@ -671,7 +679,7 @@ const handleDetail = (row: Complaint) => {
 		<el-dialog v-model="editDialogVisible" title="编辑投诉" width="700px" :close-on-click-modal="false">
 			<el-form ref="editFormRef" :model="editForm" :rules="editFormRules" label-width="100px" label-position="left">
 				<el-row :gutter="35">
-					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" >
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
 						<el-form-item label="投诉标题" prop="title" required>
 							<el-input v-model="editForm.title" placeholder="请输入投诉标题" maxlength="100" show-word-limit />
 						</el-form-item>
@@ -744,9 +752,7 @@ const handleDetail = (row: Complaint) => {
 			<template #footer>
 				<div class="dialog-footer">
 					<el-button @click="handleEditCancel">取消</el-button>
-					<el-button type="primary" @click="handleEditConfirm">
-						提交修改
-					</el-button>
+					<el-button type="primary" @click="handleEditConfirm"> 提交修改 </el-button>
 					<el-button @click="handleEditCancel">保存草稿</el-button>
 				</div>
 			</template>
@@ -755,13 +761,13 @@ const handleDetail = (row: Complaint) => {
 		<!-- 反馈对话框 -->
 		<el-dialog v-model="feedback" title="投诉反馈" width="700px" :close-on-click-modal="false">
 			<el-form ref="feedFormRef" :model="feedCreateForm" :rules="feedFormRules" label-width="120px" label-position="left">
-<!--				<el-form-item label="问卷编号" prop="surveyCode" required>-->
-<!--					<el-input v-model="feedCreateForm.surveyCode" placeholder="请输入问卷编号" maxlength="50" />-->
-<!--				</el-form-item>-->
+				<!--				<el-form-item label="问卷编号" prop="surveyCode" required>-->
+				<!--					<el-input v-model="feedCreateForm.surveyCode" placeholder="请输入问卷编号" maxlength="50" />-->
+				<!--				</el-form-item>-->
 
-<!--				<el-form-item label="投诉编号" prop="ticketNo">-->
-<!--					<el-input v-model="feedCreateForm.ticketNo" placeholder="投诉编号" disabled />-->
-<!--				</el-form-item>-->
+				<!--				<el-form-item label="投诉编号" prop="ticketNo">-->
+				<!--					<el-input v-model="feedCreateForm.ticketNo" placeholder="投诉编号" disabled />-->
+				<!--				</el-form-item>-->
 				<div style="display: flex">
 					<div style="flex: 1">
 						<el-form-item label="调查者姓名" prop="investigatorName" required>
@@ -776,8 +782,6 @@ const handleDetail = (row: Complaint) => {
 					</div>
 				</div>
 
-
-
 				<el-form-item label="处理速度" prop="processingSpeed" required>
 					<el-radio-group v-model="feedCreateForm.processingSpeed">
 						<el-radio v-for="item in related_level" :label="item.value" :key="item.value">
@@ -836,7 +840,9 @@ const handleDetail = (row: Complaint) => {
 			</template>
 		</el-dialog>
 
-		<report-detail-dialog :id="complaintDetailId" v-model:visible="showDetail"/>
+		<report-detail-dialog :id="complaintDetailId" v-model:visible="showDetail" />
+
+		<checkFlow ref="ckFlowRef" @getList="getComplaintList"></checkFlow>
 	</div>
 </template>
 

+ 29 - 40
src/views/system/report/summary/index.vue

@@ -1,26 +1,14 @@
 <script setup lang="ts">
-import { ref, onMounted, computed, getCurrentInstance, unref, watch } from 'vue'
-import {
-	Document,
-	Clock,
-	CircleCheck,
-	Warning,
-	Timer,
-	TrendCharts,
-	PieChart,
-	Position,
-	List,
-	CaretTop,
-	CaretBottom,
-} from '@element-plus/icons-vue'
+import { computed, getCurrentInstance, onMounted, ref, unref, watch } from 'vue'
+import { CaretBottom, CaretTop, CircleCheck, Clock, Document, List, PieChart, Position, Timer, TrendCharts, Warning } from '@element-plus/icons-vue'
 import api from '/@/api/system/report/statistics'
 import report from '/@/api/system/report/complaints'
-import { Complaint, StatisticsQueryParams } from '/@/api/system/report/type'
+import { Complaint, ComplaintStatus, StatisticsQueryParams } from '/@/api/system/report/type'
 
 // 按需引入 ECharts
 import * as echarts from 'echarts/core'
-import { PieChart as PieChartComponent, BarChart, LineChart } from 'echarts/charts'
-import { TitleComponent, TooltipComponent, LegendComponent, GridComponent } from 'echarts/components'
+import { BarChart, LineChart, PieChart as PieChartComponent } from 'echarts/charts'
+import { GridComponent, LegendComponent, TitleComponent, TooltipComponent } from 'echarts/components'
 import { LabelLayout } from 'echarts/features'
 import { CanvasRenderer } from 'echarts/renderers'
 import { useAsyncState, useEventListener } from '@vueuse/core'
@@ -74,13 +62,13 @@ const formatReportSource = computed<(value: string) => string>(() => {
 const formatReportStatus = (value: Complaint['status']) => {
 	let a = '-'
 	switch (value) {
-		case 'completed':
+		case ComplaintStatus.COMPLETED:
 			a = '已完成'
 			break
-		case 'pending':
+		case ComplaintStatus.PENDING:
 			a = '待处理'
 			break
-		case 'processing':
+		case ComplaintStatus.PROCESSING:
 			a = '进行中'
 			break
 	}
@@ -118,10 +106,7 @@ useEventListener('resize', () => {
 })
 
 //异步获取数据
-const {
-	state: statistics,
-	execute: getStatistics,
-} = useAsyncState(async (range: StatisticsQueryParams) => api.overview(range), undefined)
+const { state: statistics, execute: getStatistics } = useAsyncState(async (range: StatisticsQueryParams) => api.overview(range), undefined)
 
 //通过数据和组件挂载状态决定ECOption
 const statisticsOption = computed(() => {
@@ -395,35 +380,39 @@ const areaDistributionOption = computed(() => {
 		},
 		yAxis: {
 			type: 'category',
-			data: prepare.map(item => item.area),
+			data: prepare.map((item) => item.area),
 			axisLine: { show: false },
 			axisTick: { show: false },
 		},
-		series: [{
-			type: 'bar',
-			data: prepare.map(item => ({
-				value: item.count,
-				itemStyle: { color: '#666' },
-			})),
-			barWidth: '50%',
-			itemStyle: {
-				borderRadius: [0, 2, 2, 0],
+		series: [
+			{
+				type: 'bar',
+				data: prepare.map((item) => ({
+					value: item.count,
+					itemStyle: { color: '#666' },
+				})),
+				barWidth: '50%',
+				itemStyle: {
+					borderRadius: [0, 2, 2, 0],
+				},
 			},
-		}],
+		],
 	}
 	return option
 })
 watch(areaDistributionOption, (newVal) => {
-	if (newVal!== undefined) {
+	if (newVal !== undefined) {
 		areaChart.setOption(newVal)
 	}
 })
 
-const {state: recentComplaints} = useAsyncState<Complaint[]>(async () => report.getList({orderBy: 'desc',pageSize: 5}).then((res: {list: Complaint[]})=>res.list),[])
-
+const { state: recentComplaints } = useAsyncState<Complaint[]>(
+	async () => report.getList({ orderBy: 'desc', pageSize: 5 }).then((res: { list: Complaint[] }) => res.list),
+	[]
+)
 
 const detailVisible = ref(false)
-const detailComplaint = ref<number|undefined>(undefined)
+const detailComplaint = ref<number | undefined>(undefined)
 const handleDetail = (complaint: Complaint) => {
 	detailComplaint.value = complaint.id
 	detailVisible.value = true
@@ -674,7 +663,7 @@ const openAll = () => {
 			</div>
 		</el-card>
 
-		<report-detail-dialog :id="detailComplaint" v-model:visible="detailVisible"/>
+		<report-detail-dialog :id="detailComplaint" v-model:visible="detailVisible" />
 	</div>
 </template>