main
徐景良 2024-11-18 10:10:37 +08:00
parent 94e8c19fae
commit 1b0bb164be
21 changed files with 1658 additions and 28 deletions

7
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"i18n-ally.localesPaths": [
"src/locales",
"src/locales/lang",
"public/resource/tinymce/langs"
]
}

52
src/api/task/index.ts Normal file
View File

@ -0,0 +1,52 @@
import { defHttp } from '@/utils/http/axios';
import { TaskResultModel, AccountListItem, AccountParams, Task } from './model/index';
enum Api {
// 管理员任务
TaskList = "/api/AdminTaskManage/GteTaskListForAdmin",
AddTask = "/api/AdminTaskManage/AddTask",
EditTask = "/api/AdminTaskManage/EditTask",
DeleteTask = "/api/AdminTaskManage/DeleteTask",
DetailTask = "/api/AdminTaskManage/GteTaskById",
GetAiShp = "/api/AdminTaskManage/GteAiShp",
GetTif = "/api/AdminTaskManage/GteTif",
// 普通用户任务
PersonTaskList = "/api/PersonTask/Load",
PersonTaskDetail = "/api/PersonTask/GetTaskDetail",
SubmitPersonTask = "/api/PersonTask/SubmitTask",
ReturnPersonTask = "/api/PersonTask/ReturnTask"
}
// 管理员任务
export const getTaskList = (params) =>
defHttp.get<TaskResultModel>({ url: Api.TaskList, params });
export const addTask = (params:Task) =>
defHttp.post<TaskResultModel>({ url: Api.AddTask, params });
export const updateTask = (params:Task) =>
defHttp.post<TaskResultModel>({ url: Api.EditTask, params });
export const deleteTask = (params) =>
defHttp.post<TaskResultModel>({ url: Api.DeleteTask, params });
export const getTaskDetail = (params) =>
defHttp.get<TaskResultModel>({ url: Api.DetailTask, params });
export const getAiShape = () =>
defHttp.get<TaskResultModel>({ url: Api.GetAiShp });
export const getTif = () =>
defHttp.get<TaskResultModel>({ url: Api.GetTif });
// 普通用户任务
export const getPersonTaskList = (params) =>
defHttp.get<TaskResultModel>({ url: Api.PersonTaskList, params });
export const getPersonTaskDetail = (params) =>
defHttp.get<TaskResultModel>({ url: Api.PersonTaskDetail, params });
export const CommitTask = (params) =>
defHttp.post<TaskResultModel>({ url: Api.SubmitPersonTask, params });

View File

@ -0,0 +1,45 @@
import { BasicFetchResult } from '@/api/model/baseModel';
import { type } from 'os';
export interface AccountListItem {
databaseLinkId: string;
dbName: string;
dbAlias: string;
dbType: number;
serverAddress: string;
dbConnection: string;
description: string;
}
// task
export interface Task {
id:string;
taskName:string;
shpId:string;
remark:string;
previousPhase:Array;
laterPhase:Array;
}
// shp
export interface Shape {
id:string;
shpName:string;
}
// tif
/**
* @description: Request list return value
*/
export interface AccountParams {
id?: string;
keyword?: string;
page?: string;
limit?: string;
};
export type TaskResultModel = BasicFetchResult<Task>;
export type ShapeResultModel = BasicFetchResult<Shape>

View File

@ -40,7 +40,7 @@
</span>
</Tooltip>
<!-- 云查询结果 -->
<a-modal
<!-- <a-modal
v-model:open="open"
:footer="false"
@cancel="closeCloudQueryModal"
@ -49,7 +49,7 @@
:destroyOnClose="true"
>
<CloudQueryContent @changeCompare="changeCompare"/>
</a-modal>
</a-modal> -->
</div>
</template>
<script lang="ts" setup>
@ -60,7 +60,7 @@
import { useCloudQueryStore } from '@/store/modules/cloudquery';
import { LoadCloudQueryByCaseNo } from '@/api/demo/cloudQuery';
import { getAppEnvConfig } from '@/utils/env';
import CloudQueryContent from '@/components/CloudQueryContent/index.vue';
// import CloudQueryContent from '@/components/CloudQueryContent/index.vue';
import { useMessage } from '@/hooks/web/useMessage';
import axios from 'axios';

View File

@ -82,14 +82,14 @@ export const SchemeRoute: AppRouteRecordRaw = {
title: t('routes.demo.workflow.scheme_preview'),
},
};
export const VideoSupervisionRoute: AppRouteRecordRaw = {
path: '/videosupervision',
name: 'videosupervision',
component: () => import('@/views/sys/exception/VideoSupervision.vue'),
meta: {
title: '视频监管',
},
};
// export const VideoSupervisionRoute: AppRouteRecordRaw = {
// path: '/videosupervision',
// name: 'videosupervision',
// component: () => import('@/views/sys/exception/VideoSupervision.vue'),
// meta: {
// title: '视频监管',
// },
// };
export const LargeScreenRoute: AppRouteRecordRaw = {
path: '/largeScreen',
name: 'largeScreen',
@ -134,5 +134,5 @@ export const basicRoutes = [
SchemeRoute,
FORMCALLPAGE_ROUTE,
LargeScreenRoute,
VideoSupervisionRoute,
// VideoSupervisionRoute,
];

View File

@ -29,7 +29,7 @@
<script setup lang="ts">
import { defineProps, ref } from "vue"
import { BasicTable,useTable,TableAction } from "@/components/Table";
import { LoadCaseHistoryInfoList } from '@/api/demo/system';
// import { LoadCaseHistoryInfoList } from '@/api/demo/system';
import { columns } from './util'
import ShowDetail from './ShowDetail/index.vue'
@ -46,7 +46,7 @@ const [registerTable, { }] =
key: props.caseId,
}
},
api: LoadCaseHistoryInfoList,
// api: LoadCaseHistoryInfoList,
columns,
rowKey: 'id',
// 使

View File

@ -47,7 +47,7 @@
<script lang="ts" setup>
import { PageWrapper } from '@/components/Page';
import { onMounted, ref } from 'vue';
import { LoadCaseInfoListForUpdate,LoadCaseInfoById,UpdateCaseInfo,LoadCaseHistoryInfoList } from '@/api/demo/system';
// import { LoadCaseInfoListForUpdate,LoadCaseInfoById,UpdateCaseInfo,LoadCaseHistoryInfoList } from '@/api/demo/system';
import { BasicTable,useTable,TableAction } from '@/components/Table';
import { columns, searchFormSchema } from './casemodification.data';
import InfoModal from './InfoModal/index.vue'
@ -62,7 +62,7 @@ const infoResult = ref({})
const [registerTable, { setTableData, reload, clearSelectedRowKeys, setPagination, setLoading }] =
useTable({
title: '图斑汇总',
api: LoadCaseInfoListForUpdate,
// api: LoadCaseInfoListForUpdate,
columns,
rowKey: 'id',
formConfig: {
@ -81,12 +81,12 @@ const [registerTable, { setTableData, reload, clearSelectedRowKeys, setPaginatio
},
});
const getCaseDetail = (record) => {
LoadCaseInfoById({id: record.id}).then(res => {
// console.log(res)
// infoResult.value = {}
infoData.value = res
infoModal.value = true
})
// LoadCaseInfoById({id: record.id}).then(res => {
// // console.log(res)
// // infoResult.value = {}
// infoData.value = res
// infoModal.value = true
// })
}
const getHistoryList = (record) => {
// LoadCaseHistoryInfoList({key:record.id}).then(res => {
@ -99,12 +99,12 @@ const getHistoryList = (record) => {
}
const submit = () => {
console.log('submit',infoResult.value)
UpdateCaseInfo(infoResult.value).then(res => {
console.log(res)
message.success('修改成功')
closeInfoModal()
reload()
})
// UpdateCaseInfo(infoResult.value).then(res => {
// console.log(res)
// message.success('')
// closeInfoModal()
// reload()
// })
}
const closeInfoModal = () => {
infoModal.value = false

View File

@ -0,0 +1,151 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './dept.data';
import { getDeptList, addDept, updateDept } from '@/api/demo/system';
import {getAiShape,getTif,addTask} from '@/api/task'
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'DeptModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
setFieldsValue({
...data.record,
});
}
const treeData = await getDeptList();
console.log("treeData",treeData);
const shapefiles = await getAiShape();
const tifs = await getTif();
let afterTifs = handleDealTifTree(tifs)
//
updateSchema([
{
field: 'shpId',
componentProps: { options:shapefiles },
},{
field: 'previousPhase',
componentProps: { treeData:afterTifs },
},{
field: 'laterPhase',
componentProps: { treeData:afterTifs },
}
]);
});
const getTitle = computed(() => (!unref(isUpdate) ? '创建任务' : '编辑任务'));
function handleDealTifTree(tifs){
let handlerAfterTifs =[];
tifs.forEach((item,index)=>{
let obj = {
id:item.areaName,
key:item.areaName,
level:0,
parentId:index,
name:item.areaName,
children:[]
}
item.tifDateGroups.forEach((it,idx)=>{
let data = {
id:it.tifDate,
key:it.tifDate,
level:1,
parentId:index,
name:it.tifDate,
children:[]
}
it.tifDatas.forEach((tifItem,i)=>{
let tifObj = {
id:tifItem.id,
key:tifItem.id,
level:2,
parentId:idx,
name:tifItem.tifName,
}
data.children.push(tifObj);
})
obj.children.push(data)
})
handlerAfterTifs.push(obj);
})
return handlerAfterTifs;
}
async function handleSubmit() {
try {
const values = await validate();
let query = values;
if (query.id) {
query.id = Number(query.id);
} else {
query.id = 0;
}
//
if (!unref(isUpdate)) {
const data = await addTask(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('创建成功');
} else {
return createMessage.error('创建失败');
}
} else {
const data = await updateDept(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('编辑成功');
} else {
return createMessage.error('编辑失败');
}
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style>
::v-deep .update-button{
background:#408eff;
}
</style>

View File

@ -0,0 +1,110 @@
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
ref="asyncExpandTreeRef"
title="部门列表"
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="false"
:treeData="treeData"
:fieldNames="{ key: 'id', title: 'name' }"
@select="handleSelect"
:load-data="onLoadData"
:expandedKeys="expandedKeys"
:loadedKeys="loadedKeys"
@expand="expand"
/>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, nextTick, unref } from 'vue';
import { BasicTree, TreeItem, TreeActionType } from '@/components/Tree';
import { getChildrenTree } from '@/api/demo/system';
import { isArray } from '@/utils/is';
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
const asyncExpandTreeRef = ref<Nullable<TreeActionType>>(null);
const expandedKeys = ref([]);
const loadedKeys = ref([]);
const firstExpandedKeys = ref([]);
const getParentIdList = (list, data) => {
if (data === undefined || data === null) {
return list;
}
list.unshift(data.key);
return getParentIdList(list, data.parent);
};
const expand = (expandIdList, data) => {
if (data.expanded) {
let parentIdList = getParentIdList([data.node.key], data.node.parent);
expandedKeys.value = [...parentIdList];
loadedKeys.value = [...parentIdList];
console.log(firstExpandedKeys.value, parentIdList);
let levelData = treeData.value[0];
console.log(levelData);
for (let i = 1; i < Math.min(firstExpandedKeys.value.length, parentIdList.length); i++) {
if (firstExpandedKeys.value[i] === parentIdList[i]) {
levelData = levelData.children.find((item) => item.id === parentIdList[i]);
console.log(levelData);
} else {
let data = levelData.children.find((item) => item.id === firstExpandedKeys.value[i]);
data.children = null;
break;
}
}
firstExpandedKeys.value = parentIdList;
} else {
}
};
async function fetch() {
treeData.value = (await getChildrenTree({ parentId: 0 })) as unknown as TreeItem[];
//
nextTick(() => {
unref(asyncExpandTreeRef)?.filterByLevel(1);
});
}
function handleSelect(keys) {
emit('select', keys[0]);
}
onMounted(() => {
fetch();
});
defineExpose({
fetch,
});
function onLoadData(treeNode) {
return new Promise((resolve: (value?: unknown) => void) => {
if (isArray(treeNode.children) && treeNode.children.length > 0) {
resolve();
return;
}
getChildrenTree({ parentId: treeNode.id })
.then((res) => {
const asyncTreeAction: TreeActionType | null = unref(asyncExpandTreeRef);
if (asyncTreeAction) {
const nodeChildren = res;
asyncTreeAction.updateNodeByKey(treeNode.eventKey, { children: nodeChildren });
// asyncTreeAction.setExpandedKeys(
// uniq([treeNode.eventKey, ...asyncTreeAction.getExpandedKeys()]),
// );
loadedKeys.value.push(treeNode.eventKey);
}
resolve();
return;
})
.catch((err) => {
console.log(err);
resolve();
return;
});
});
}
</script>

View File

@ -0,0 +1,109 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="1000px">
<BasicForm @register="registerForm" v-show="false" />
<a-descriptions title="" bordered>
<a-descriptions-item label="任务名称" :span="2">{{taskInfo.taskName}}</a-descriptions-item>
<a-descriptions-item label="备注/说明" :span="6">{{taskInfo.remark}}</a-descriptions-item>
<a-descriptions-item label="图斑数量" :span="2"></a-descriptions-item>
<a-descriptions-item label="已领取数量" :span="2"></a-descriptions-item>
<a-descriptions-item label="未领取数量" :span="2"></a-descriptions-item>
<a-descriptions-item label="任务进度" :span="2">
<a-tag color="green" v-if="taskInfo.isCompleted"></a-tag>
<a-tag color="red" v-else></a-tag>
</a-descriptions-item>
<a-descriptions-item label="完成时间" :span="2" v-show="taskInfo.isCompleted">{{taskInfo.completeTime}}</a-descriptions-item>
<a-descriptions-item label="创建人" :span="2">{{taskInfo.createUserName}}</a-descriptions-item>
<a-descriptions-item label="创建时间" :span="2">{{taskInfo.createTime}}</a-descriptions-item>
<a-descriptions-item label="更新人" :span="2">{{taskInfo.updateUserName}}</a-descriptions-item>
<a-descriptions-item label="更新时间" :span="2">{{taskInfo.updateTime}}</a-descriptions-item>
</a-descriptions>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './dept.data';
import { getDeptList, addDept, updateDept } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'DeptModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
});
const taskInfo = ref({})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
taskInfo.value = data.record;
console.log("taskInfo",taskInfo.value);
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
setFieldsValue({
...data.record,
});
}
const treeData = await getDeptList();
updateSchema({
field: 'parentId',
componentProps: { treeData },
});
});
const getTitle = computed(() => (!unref(isUpdate) ? '创建任务' : '任务详情'));
async function handleSubmit() {
try {
const values = await validate();
let query = values;
if (query.id) {
query.id = Number(query.id);
} else {
query.id = 0;
}
//
if (!unref(isUpdate)) {
const data = await addDept(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('创建成功');
} else {
return createMessage.error('创建失败');
}
} else {
const data = await updateDept(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('编辑成功');
} else {
return createMessage.error('编辑失败');
}
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

View File

@ -0,0 +1,59 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="给部门分配职级组" @ok="handleSubmit">
<BasicForm @register="registerForm" :model="modelRef"/>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formGroupSchema } from './dept.data';
import { orgPosGroup} from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'PosGroupModal' });
const emit = defineEmits(['success', 'register']);
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: formGroupSchema,
showActionButtonGroup: false,
});
let depeId = ref()
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
depeId.value = data.record.id
setFieldsValue({
...data.record,
});
});
async function handleSubmit() {
try {
const values = await validate();
let query = {
orgId:depeId.value,
posGroupId:values.posGroupId,
}
//
const data = await orgPosGroup(query);
if(data){
setModalProps({ confirmLoading: true });
// TODO custom api
closeModal();
emit('success');
return createMessage.success('成功');
}else{
return createMessage.error('失败');
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

View File

@ -0,0 +1,153 @@
import { BasicColumn, FormSchema } from '@/components/Table';
import { h } from 'vue';
import { Tag } from 'ant-design-vue';
import { getPosGroupList } from '@/api/demo/system';
export const columns: BasicColumn[] = [
{
title: '任务编号',
dataIndex: 'id',
},
{
title: '任务名称',
dataIndex: 'taskName',
},
{
title: '备注/说明',
dataIndex: 'remark',
},
{
title: '图斑数量',
dataIndex: 'sortNo',
},
{
title: '已领取数量',
dataIndex: 'sortNo',
},
{
title: '未领取数量',
dataIndex: 'sortNo',
},
{
title: '任务状态',
dataIndex: 'status',
width: 80,
customRender: ({ record }) => {
const enable = record.isCompleted;
const color = enable ? 'green' : 'red';
const text = enable ? '已完成' : '未完成';
return h(Tag, { color: color }, () => text);
},
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180,
}
];
export const searchFormSchema: FormSchema[] = [
{
field: 'taskName',
label: '任务名称',
component: 'Input',
colProps: { span: 8 },
},
];
export const formGroupSchema: FormSchema[] = [
{
field: 'posGroupId',
component: 'ApiSelect',
label: '职级组',
required: true,
componentProps: ({ formActionType, formModel }) => {
return {
api: getPosGroupList, // 接口
// 接口参数
resultField: 'result',
labelField: 'name',
valueField: 'id',
};
},
},
];
const updateShpae=()=>{
alert(123);
}
window.updateShpae = updateShpae
export const formSchema: FormSchema[] = [
{
field: 'shpId',
label: '选择AI解译成果',
component: 'Select',
componentProps: {
fieldNames: {
label: 'shpName',
key: 'id',
value: 'id',
},
onChange:(value)=>{
console.log(value)
},
getPopupContainer: () => document.body,
},
required: true,
suffix: () => h('span', {style:"background:#0960BD;padding:8px 10px;border-radius:4px;color:#fff;cursor:pointer;", class: 'update-button',onclick:"updateShpae()"}, '更新数据'),
},
{
field: 'previousPhase',
label: '选择前时项',
component: 'TreeSelect',
componentProps: {
multiple:true,
fieldNames: {
label: 'name',
key: 'id',
value: 'id',
},
onChange:(value)=>{
console.log(value)
},
getPopupContainer: () => document.body,
},
required: true,
suffix: () => h('span', {style:"background:#0960BD;padding:8px 10px;border-radius:4px;color:#fff;cursor:pointer;", class: 'update-button',onclick:"updateShpae()"}, '更新数据'),
},
{
field: 'laterPhase',
label: '选择后时项',
component: 'TreeSelect',
componentProps: {
multiple:true,
fieldNames: {
label: 'name',
key: 'id',
value: 'id',
},
onChange:(value)=>{
console.log(value)
},
getPopupContainer: () => document.body,
},
required: true,
suffix: () => h('span', {style:"background:#0960BD;padding:8px 10px;border-radius:4px;color:#fff;cursor:pointer;", class: 'update-button',onclick:"updateShpae()"}, '更新数据'),
},
{
field: 'taskName',
label: '任务名称',
component: 'Input',
required: true,
},
{
field: 'remark',
label: '备注/说明',
component: 'InputTextArea',
required: false,
}
];

View File

@ -0,0 +1,174 @@
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<!-- <DeptTree ref="childRef" class="w-1/4 xl:w-1/5" @select="handleSelect" /> -->
<BasicTable class="w-4/4 xl:w-5/5" @register="registerTable" :searchInfo="searchInfo">
<template #toolbar>
<!-- <a-button type="primary" @click="handleCreate"> </a-button> -->
<!-- <a-button type="primary" @click="handlePoGroup"> </a-button> -->
<PermissionBtn @btnEvent="onBtnClicked"></PermissionBtn>
</template>
</BasicTable>
<!-- add & edit -->
<DeptModal @register="registerModal" @success="handleSuccess" />
<!-- detail -->
<DetailModal @register="registerDetailModal" @success="handleSuccess"></DetailModal>
<PosGroupModal @register="registerPosGroupModal" @success="handleSuccess"></PosGroupModal>
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { BasicTable, useTable } from '@/components/Table';
import { getOrgList, deleteDept } from '@/api/demo/system';
import {getTaskList,deleteTask,getTaskDetail} from '@/api/task'
import { PageWrapper } from '@/components/Page';
import { useModal } from '@/components/Modal';
import { useMessage } from '@/hooks/web/useMessage';
// import { DeptTree } from './page';
import { DeptModal } from './page';
import { DetailModal } from './page';
import { PosGroupModal } from './page';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { columns, searchFormSchema } from './dept.data';
defineOptions({ name: 'DeptManagement' });
const { createConfirm, createMessage } = useMessage();
const [registerModal, { openModal: openDeptModal }] = useModal();
const [registerDetailModal,{openModal:openDetailModal}] = useModal();
const [registerPosGroupModal, { openModal: openPosGroupModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({
title: '任务列表',
api: getTaskList,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
rowSelection: {
//
// type: 'checkbox',
type: 'radio',
},
useSearchForm: true,
showIndexColumn: false,
showTableSetting: true,
bordered: true,
handleSearchInfoFn(info) {
return info;
},
});
async function handlePoGroup() {
let rows = getSelectRows();
if (!rows.length) {
return createMessage.warn('请选择一个任务');
}
var record = rows[0];
openPosGroupModal(true, {
record,
isUpdate: false,
});
}
const childRef = ref<any>();
function handleCreate() {
openDeptModal(true, {
isUpdate: false,
});
}
async function handleEdit() {
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请选择一个任务进行编辑');
}
// const record = rows[0];
const record =await getTaskDetail({id:rows[0].id});
console.log("record",record);
openDeptModal(true, {
record,
isUpdate: true,
});
}
function handleDetail(){
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请选择一个任务进行查看');
}
const record = rows[0];
openDetailModal(true, {
record,
isUpdate: true,
});
}
async function handleDelete() {
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请选择一个任务进行删除');
}
const query = [rows[0].id];
createConfirm({
iconType: 'info',
title: '删除',
content: '确定要删除当前任务吗',
onOk: async () => {
try{
const data = await deleteTask({id:rows[0].id});
if (data) {
handleSuccess();
createMessage.success('删除成功');
} else {
createMessage.error('删除失败');
}
}catch(e){
console.log(e);
}
},
});
}
function onBtnClicked(domId) {
switch (domId) {
case 'btnAdd':
handleCreate();
break;
case 'btnEdit':
handleEdit();
break;
case 'btnDelete':
handleDelete();
break;
case 'btnPoGroup':
handlePoGroup();
break;
case 'btnDetail':
handleDetail();
break;
default:
break;
}
}
function handleSelect(orgId = '') {
searchInfo.orgId = orgId;
reload();
}
function handleSuccess() {
clearSelectedRowKeys();
// childRef.value.fetch();
reload();
}
</script>

View File

@ -0,0 +1,7 @@
export { default as DeptTree } from './DeptTree.vue';
export { default as DeptModal } from './DeptModal.vue';
export { default as DetailModal } from './DetailModal.vue';
export { default as PosGroupModal } from './PosGroupModal.vue';

View File

@ -0,0 +1,151 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './dept.data';
import { getDeptList, addDept, updateDept } from '@/api/demo/system';
import {getAiShape,getTif,addTask} from '@/api/task'
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'DeptModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
setFieldsValue({
...data.record,
});
}
const treeData = await getDeptList();
console.log("treeData",treeData);
const shapefiles = await getAiShape();
const tifs = await getTif();
let afterTifs = handleDealTifTree(tifs)
//
updateSchema([
{
field: 'shpId',
componentProps: { options:shapefiles },
},{
field: 'previousPhase',
componentProps: { treeData:afterTifs },
},{
field: 'laterPhase',
componentProps: { treeData:afterTifs },
}
]);
});
const getTitle = computed(() => (!unref(isUpdate) ? '创建任务' : '编辑任务'));
function handleDealTifTree(tifs){
let handlerAfterTifs =[];
tifs.forEach((item,index)=>{
let obj = {
id:item.areaName,
key:item.areaName,
level:0,
parentId:index,
name:item.areaName,
children:[]
}
item.tifDateGroups.forEach((it,idx)=>{
let data = {
id:it.tifDate,
key:it.tifDate,
level:1,
parentId:index,
name:it.tifDate,
children:[]
}
it.tifDatas.forEach((tifItem,i)=>{
let tifObj = {
id:tifItem.id,
key:tifItem.id,
level:2,
parentId:idx,
name:tifItem.tifName,
}
data.children.push(tifObj);
})
obj.children.push(data)
})
handlerAfterTifs.push(obj);
})
return handlerAfterTifs;
}
async function handleSubmit() {
try {
const values = await validate();
let query = values;
if (query.id) {
query.id = Number(query.id);
} else {
query.id = 0;
}
//
if (!unref(isUpdate)) {
const data = await addTask(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('创建成功');
} else {
return createMessage.error('创建失败');
}
} else {
const data = await updateDept(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('编辑成功');
} else {
return createMessage.error('编辑失败');
}
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style>
::v-deep .update-button{
background:#408eff;
}
</style>

View File

@ -0,0 +1,110 @@
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
ref="asyncExpandTreeRef"
title="部门列表"
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="false"
:treeData="treeData"
:fieldNames="{ key: 'id', title: 'name' }"
@select="handleSelect"
:load-data="onLoadData"
:expandedKeys="expandedKeys"
:loadedKeys="loadedKeys"
@expand="expand"
/>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, nextTick, unref } from 'vue';
import { BasicTree, TreeItem, TreeActionType } from '@/components/Tree';
import { getChildrenTree } from '@/api/demo/system';
import { isArray } from '@/utils/is';
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
const asyncExpandTreeRef = ref<Nullable<TreeActionType>>(null);
const expandedKeys = ref([]);
const loadedKeys = ref([]);
const firstExpandedKeys = ref([]);
const getParentIdList = (list, data) => {
if (data === undefined || data === null) {
return list;
}
list.unshift(data.key);
return getParentIdList(list, data.parent);
};
const expand = (expandIdList, data) => {
if (data.expanded) {
let parentIdList = getParentIdList([data.node.key], data.node.parent);
expandedKeys.value = [...parentIdList];
loadedKeys.value = [...parentIdList];
console.log(firstExpandedKeys.value, parentIdList);
let levelData = treeData.value[0];
console.log(levelData);
for (let i = 1; i < Math.min(firstExpandedKeys.value.length, parentIdList.length); i++) {
if (firstExpandedKeys.value[i] === parentIdList[i]) {
levelData = levelData.children.find((item) => item.id === parentIdList[i]);
console.log(levelData);
} else {
let data = levelData.children.find((item) => item.id === firstExpandedKeys.value[i]);
data.children = null;
break;
}
}
firstExpandedKeys.value = parentIdList;
} else {
}
};
async function fetch() {
treeData.value = (await getChildrenTree({ parentId: 0 })) as unknown as TreeItem[];
//
nextTick(() => {
unref(asyncExpandTreeRef)?.filterByLevel(1);
});
}
function handleSelect(keys) {
emit('select', keys[0]);
}
onMounted(() => {
fetch();
});
defineExpose({
fetch,
});
function onLoadData(treeNode) {
return new Promise((resolve: (value?: unknown) => void) => {
if (isArray(treeNode.children) && treeNode.children.length > 0) {
resolve();
return;
}
getChildrenTree({ parentId: treeNode.id })
.then((res) => {
const asyncTreeAction: TreeActionType | null = unref(asyncExpandTreeRef);
if (asyncTreeAction) {
const nodeChildren = res;
asyncTreeAction.updateNodeByKey(treeNode.eventKey, { children: nodeChildren });
// asyncTreeAction.setExpandedKeys(
// uniq([treeNode.eventKey, ...asyncTreeAction.getExpandedKeys()]),
// );
loadedKeys.value.push(treeNode.eventKey);
}
resolve();
return;
})
.catch((err) => {
console.log(err);
resolve();
return;
});
});
}
</script>

View File

@ -0,0 +1,109 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="1000px">
<BasicForm @register="registerForm" v-show="false" />
<a-descriptions title="" bordered>
<a-descriptions-item label="任务名称" :span="2">{{taskInfo.taskName}}</a-descriptions-item>
<a-descriptions-item label="备注/说明" :span="6">{{taskInfo.remark}}</a-descriptions-item>
<a-descriptions-item label="图斑数量" :span="2"></a-descriptions-item>
<a-descriptions-item label="已领取数量" :span="2"></a-descriptions-item>
<a-descriptions-item label="未领取数量" :span="2"></a-descriptions-item>
<a-descriptions-item label="任务进度" :span="2">
<a-tag color="green" v-if="taskInfo.isCompleted"></a-tag>
<a-tag color="red" v-else></a-tag>
</a-descriptions-item>
<a-descriptions-item label="完成时间" :span="2" v-show="taskInfo.isCompleted">{{taskInfo.completeTime}}</a-descriptions-item>
<a-descriptions-item label="创建人" :span="2">{{taskInfo.createUserName}}</a-descriptions-item>
<a-descriptions-item label="创建时间" :span="2">{{taskInfo.createTime}}</a-descriptions-item>
<a-descriptions-item label="更新人" :span="2">{{taskInfo.updateUserName}}</a-descriptions-item>
<a-descriptions-item label="更新时间" :span="2">{{taskInfo.updateTime}}</a-descriptions-item>
</a-descriptions>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './dept.data';
import { getDeptList, addDept, updateDept } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'DeptModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
});
const taskInfo = ref({})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
taskInfo.value = data.record;
console.log("taskInfo",taskInfo.value);
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
setFieldsValue({
...data.record,
});
}
const treeData = await getDeptList();
updateSchema({
field: 'parentId',
componentProps: { treeData },
});
});
const getTitle = computed(() => (!unref(isUpdate) ? '创建任务' : '任务详情'));
async function handleSubmit() {
try {
const values = await validate();
let query = values;
if (query.id) {
query.id = Number(query.id);
} else {
query.id = 0;
}
//
if (!unref(isUpdate)) {
const data = await addDept(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('创建成功');
} else {
return createMessage.error('创建失败');
}
} else {
const data = await updateDept(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('编辑成功');
} else {
return createMessage.error('编辑失败');
}
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

View File

@ -0,0 +1,59 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="给部门分配职级组" @ok="handleSubmit">
<BasicForm @register="registerForm" :model="modelRef"/>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formGroupSchema } from './dept.data';
import { orgPosGroup} from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'PosGroupModal' });
const emit = defineEmits(['success', 'register']);
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: formGroupSchema,
showActionButtonGroup: false,
});
let depeId = ref()
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
depeId.value = data.record.id
setFieldsValue({
...data.record,
});
});
async function handleSubmit() {
try {
const values = await validate();
let query = {
orgId:depeId.value,
posGroupId:values.posGroupId,
}
//
const data = await orgPosGroup(query);
if(data){
setModalProps({ confirmLoading: true });
// TODO custom api
closeModal();
emit('success');
return createMessage.success('成功');
}else{
return createMessage.error('失败');
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

View File

@ -0,0 +1,153 @@
import { BasicColumn, FormSchema } from '@/components/Table';
import { h } from 'vue';
import { Tag } from 'ant-design-vue';
import { getPosGroupList } from '@/api/demo/system';
export const columns: BasicColumn[] = [
{
title: '任务编号',
dataIndex: 'id',
},
{
title: '任务名称',
dataIndex: 'taskName',
},
{
title: '备注/说明',
dataIndex: 'remark',
},
{
title: '图斑数量',
dataIndex: 'sortNo',
},
{
title: '已领取数量',
dataIndex: 'sortNo',
},
{
title: '未领取数量',
dataIndex: 'sortNo',
},
{
title: '任务状态',
dataIndex: 'status',
width: 80,
customRender: ({ record }) => {
const enable = record.isCompleted;
const color = enable ? 'green' : 'red';
const text = enable ? '已完成' : '未完成';
return h(Tag, { color: color }, () => text);
},
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180,
}
];
export const searchFormSchema: FormSchema[] = [
{
field: 'taskName',
label: '任务名称',
component: 'Input',
colProps: { span: 8 },
},
];
export const formGroupSchema: FormSchema[] = [
{
field: 'posGroupId',
component: 'ApiSelect',
label: '职级组',
required: true,
componentProps: ({ formActionType, formModel }) => {
return {
api: getPosGroupList, // 接口
// 接口参数
resultField: 'result',
labelField: 'name',
valueField: 'id',
};
},
},
];
const updateShpae=()=>{
alert(123);
}
window.updateShpae = updateShpae
export const formSchema: FormSchema[] = [
{
field: 'shpId',
label: '选择AI解译成果',
component: 'Select',
componentProps: {
fieldNames: {
label: 'shpName',
key: 'id',
value: 'id',
},
onChange:(value)=>{
console.log(value)
},
getPopupContainer: () => document.body,
},
required: true,
suffix: () => h('span', {style:"background:#0960BD;padding:8px 10px;border-radius:4px;color:#fff;cursor:pointer;", class: 'update-button',onclick:"updateShpae()"}, '更新数据'),
},
{
field: 'previousPhase',
label: '选择前时项',
component: 'TreeSelect',
componentProps: {
multiple:true,
fieldNames: {
label: 'name',
key: 'id',
value: 'id',
},
onChange:(value)=>{
console.log(value)
},
getPopupContainer: () => document.body,
},
required: true,
suffix: () => h('span', {style:"background:#0960BD;padding:8px 10px;border-radius:4px;color:#fff;cursor:pointer;", class: 'update-button',onclick:"updateShpae()"}, '更新数据'),
},
{
field: 'laterPhase',
label: '选择后时项',
component: 'TreeSelect',
componentProps: {
multiple:true,
fieldNames: {
label: 'name',
key: 'id',
value: 'id',
},
onChange:(value)=>{
console.log(value)
},
getPopupContainer: () => document.body,
},
required: true,
suffix: () => h('span', {style:"background:#0960BD;padding:8px 10px;border-radius:4px;color:#fff;cursor:pointer;", class: 'update-button',onclick:"updateShpae()"}, '更新数据'),
},
{
field: 'taskName',
label: '任务名称',
component: 'Input',
required: true,
},
{
field: 'remark',
label: '备注/说明',
component: 'InputTextArea',
required: false,
}
];

View File

@ -0,0 +1,174 @@
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<!-- <DeptTree ref="childRef" class="w-1/4 xl:w-1/5" @select="handleSelect" /> -->
<BasicTable class="w-4/4 xl:w-5/5" @register="registerTable" :searchInfo="searchInfo">
<template #toolbar>
<!-- <a-button type="primary" @click="handleCreate"> </a-button> -->
<!-- <a-button type="primary" @click="handlePoGroup"> </a-button> -->
<PermissionBtn @btnEvent="onBtnClicked"></PermissionBtn>
</template>
</BasicTable>
<!-- add & edit -->
<DeptModal @register="registerModal" @success="handleSuccess" />
<!-- detail -->
<DetailModal @register="registerDetailModal" @success="handleSuccess"></DetailModal>
<PosGroupModal @register="registerPosGroupModal" @success="handleSuccess"></PosGroupModal>
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { BasicTable, useTable } from '@/components/Table';
import { getOrgList, deleteDept } from '@/api/demo/system';
import {getTaskList,deleteTask,getTaskDetail} from '@/api/task'
import { PageWrapper } from '@/components/Page';
import { useModal } from '@/components/Modal';
import { useMessage } from '@/hooks/web/useMessage';
// import { DeptTree } from './page';
import { DeptModal } from './page';
import { DetailModal } from './page';
import { PosGroupModal } from './page';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { columns, searchFormSchema } from './dept.data';
defineOptions({ name: 'DeptManagement' });
const { createConfirm, createMessage } = useMessage();
const [registerModal, { openModal: openDeptModal }] = useModal();
const [registerDetailModal,{openModal:openDetailModal}] = useModal();
const [registerPosGroupModal, { openModal: openPosGroupModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({
title: '任务列表',
api: getTaskList,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
rowSelection: {
//
// type: 'checkbox',
type: 'radio',
},
useSearchForm: true,
showIndexColumn: false,
showTableSetting: true,
bordered: true,
handleSearchInfoFn(info) {
return info;
},
});
async function handlePoGroup() {
let rows = getSelectRows();
if (!rows.length) {
return createMessage.warn('请选择一个任务');
}
var record = rows[0];
openPosGroupModal(true, {
record,
isUpdate: false,
});
}
const childRef = ref<any>();
function handleCreate() {
openDeptModal(true, {
isUpdate: false,
});
}
async function handleEdit() {
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请选择一个任务进行编辑');
}
// const record = rows[0];
const record =await getTaskDetail({id:rows[0].id});
console.log("record",record);
openDeptModal(true, {
record,
isUpdate: true,
});
}
function handleDetail(){
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请选择一个任务进行查看');
}
const record = rows[0];
openDetailModal(true, {
record,
isUpdate: true,
});
}
async function handleDelete() {
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请选择一个任务进行删除');
}
const query = [rows[0].id];
createConfirm({
iconType: 'info',
title: '删除',
content: '确定要删除当前任务吗',
onOk: async () => {
try{
const data = await deleteTask({id:rows[0].id});
if (data) {
handleSuccess();
createMessage.success('删除成功');
} else {
createMessage.error('删除失败');
}
}catch(e){
console.log(e);
}
},
});
}
function onBtnClicked(domId) {
switch (domId) {
case 'btnAdd':
handleCreate();
break;
case 'btnEdit':
handleEdit();
break;
case 'btnDelete':
handleDelete();
break;
case 'btnPoGroup':
handlePoGroup();
break;
case 'btnDetail':
handleDetail();
break;
default:
break;
}
}
function handleSelect(orgId = '') {
searchInfo.orgId = orgId;
reload();
}
function handleSuccess() {
clearSelectedRowKeys();
// childRef.value.fetch();
reload();
}
</script>

View File

@ -0,0 +1,7 @@
export { default as DeptTree } from './DeptTree.vue';
export { default as DeptModal } from './DeptModal.vue';
export { default as DetailModal } from './DetailModal.vue';
export { default as PosGroupModal } from './PosGroupModal.vue';