处理一些问题
This commit is contained in:
parent
d2e2d448ad
commit
48fbc140f5
|
@ -79,7 +79,7 @@ export default {
|
||||||
functiontree: {
|
functiontree: {
|
||||||
/** 用户中心 获取菜单接口 */
|
/** 用户中心 获取菜单接口 */
|
||||||
get_XTBGXT: (data?: QueryOptions) =>
|
get_XTBGXT: (data?: QueryOptions) =>
|
||||||
http.get('/uc/sys/user/functiontree/XTBGXT', data),
|
http.get('/uc/sys/user/functiontree/HTGLXT', data),
|
||||||
/** 统一授权 未命名接口 */
|
/** 统一授权 未命名接口 */
|
||||||
get_PLRL: (data?: QueryOptions) =>
|
get_PLRL: (data?: QueryOptions) =>
|
||||||
http.get('/uc/sys/user/functiontree/PLRL', data),
|
http.get('/uc/sys/user/functiontree/PLRL', data),
|
||||||
|
@ -161,6 +161,9 @@ export default {
|
||||||
get_toDoPage: (data?: QueryOptions) => http.get('/app/ccsq/toDoPage', data),
|
get_toDoPage: (data?: QueryOptions) => http.get('/app/ccsq/toDoPage', data),
|
||||||
/** 协同办公/出差申请 已办 */
|
/** 协同办公/出差申请 已办 */
|
||||||
get_donePage: (data?: QueryOptions) => http.get('/app/ccsq/donePage', data),
|
get_donePage: (data?: QueryOptions) => http.get('/app/ccsq/donePage', data),
|
||||||
|
/** 协同办公/出差申请 获取可退回节点信息 */
|
||||||
|
get_getBackNode: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/ccsq/getBackNode', data),
|
||||||
/** 协同办公/出差申请 查询流程节点 */
|
/** 协同办公/出差申请 查询流程节点 */
|
||||||
get_getFlowNodeUserConfig: (data?: QueryOptions) =>
|
get_getFlowNodeUserConfig: (data?: QueryOptions) =>
|
||||||
http.get('/app/ccsq/getFlowNodeUserConfig', data),
|
http.get('/app/ccsq/getFlowNodeUserConfig', data),
|
||||||
|
@ -278,6 +281,9 @@ export default {
|
||||||
/** 协同办公/督查督办/执行反馈 执行反馈已办查询 */
|
/** 协同办公/督查督办/执行反馈 执行反馈已办查询 */
|
||||||
get_pageDone: (data?: QueryOptions) =>
|
get_pageDone: (data?: QueryOptions) =>
|
||||||
http.get('/app/feedback/pageDone', data),
|
http.get('/app/feedback/pageDone', data),
|
||||||
|
/** 协同办公/督查督办/立项发起 查询立项对应的反馈 */
|
||||||
|
get_queryFeedback: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/feedback/queryFeedback', data),
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
/** 协同办公/文件上传/下载 多文件上传 */
|
/** 协同办公/文件上传/下载 多文件上传 */
|
||||||
|
@ -381,6 +387,12 @@ export default {
|
||||||
/** 合同系统/申报 退回 */
|
/** 合同系统/申报 退回 */
|
||||||
post_rollback: (data?: BodyOptions) =>
|
post_rollback: (data?: BodyOptions) =>
|
||||||
http.post('/app/sbCtrBasePt/rollback', data),
|
http.post('/app/sbCtrBasePt/rollback', data),
|
||||||
|
/** 合同系统/申报 发起废除 */
|
||||||
|
post_repeal: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/sbCtrBasePt/repeal', data),
|
||||||
|
/** 合同系统/申报 发起流程 */
|
||||||
|
post_start: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/sbCtrBasePt/start', data),
|
||||||
},
|
},
|
||||||
contractBaseInfo: {
|
contractBaseInfo: {
|
||||||
/** 合同系统/立项 合同立项保存 */
|
/** 合同系统/立项 合同立项保存 */
|
||||||
|
@ -625,8 +637,8 @@ export default {
|
||||||
get_getContractSignInfo: (data?: QueryOptions) =>
|
get_getContractSignInfo: (data?: QueryOptions) =>
|
||||||
http.get('/app/qdSign/getContractSignInfo', data),
|
http.get('/app/qdSign/getContractSignInfo', data),
|
||||||
/** 合同系统/签订 打印签订审批表 */
|
/** 合同系统/签订 打印签订审批表 */
|
||||||
get_createUserListWord: (data?: QueryOptions) =>
|
get_printApprove: (data?: QueryOptions) =>
|
||||||
http.get('/app/qdSign/createUserListWord', data),
|
http.get('/app/qdSign/printApprove', data),
|
||||||
/** 合同系统/签订 打印文本 */
|
/** 合同系统/签订 打印文本 */
|
||||||
get_textPrint: (data?: QueryOptions) =>
|
get_textPrint: (data?: QueryOptions) =>
|
||||||
http.get('/app/qdSign/textPrint', data),
|
http.get('/app/qdSign/textPrint', data),
|
||||||
|
@ -721,6 +733,9 @@ export default {
|
||||||
/** 公共 获取请求ip */
|
/** 公共 获取请求ip */
|
||||||
get_getClientIp: (data?: QueryOptions) =>
|
get_getClientIp: (data?: QueryOptions) =>
|
||||||
http.get('/app/common/getClientIp', data),
|
http.get('/app/common/getClientIp', data),
|
||||||
|
/** 公共 获取项目地址 */
|
||||||
|
get_getProjectAddress: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/common/getProjectAddress', data),
|
||||||
},
|
},
|
||||||
address: {
|
address: {
|
||||||
/** 协同办公/订餐管理/订餐地址 查询(分页) */
|
/** 协同办公/订餐管理/订餐地址 查询(分页) */
|
||||||
|
@ -772,9 +787,40 @@ export default {
|
||||||
/** 合同系统/选商/选商结果 保存 */
|
/** 合同系统/选商/选商结果 保存 */
|
||||||
post_save: (data?: BodyOptions) =>
|
post_save: (data?: BodyOptions) =>
|
||||||
http.post('/app/biddingResult/save', data),
|
http.post('/app/biddingResult/save', data),
|
||||||
|
/** 合同系统/选商/选商结果 查询流程审核节点 */
|
||||||
|
get_getFlowNodeUserConfig: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/biddingResult/getFlowNodeUserConfig', data),
|
||||||
|
/** 合同系统/选商/选商结果 启动流程 */
|
||||||
|
post_startWorkFlow: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/biddingResult/startWorkFlow', data),
|
||||||
|
/** 合同系统/选商/选商结果 审核通过 */
|
||||||
|
post_submit: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/biddingResult/submit', data),
|
||||||
|
/** 合同系统/选商/选商结果 退回 */
|
||||||
|
post_rollback: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/biddingResult/rollback', data),
|
||||||
|
/** 合同系统/选商/选商结果 待审核 */
|
||||||
|
get_toDoPage: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/biddingResult/toDoPage', data),
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
/** 合同系统/首页待办/已办 待办 */
|
/** 合同系统/首页待办/已办 首页待办 */
|
||||||
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
||||||
|
/** 合同系统/首页待办/已办 首页已办 */
|
||||||
|
get_done: (data?: QueryOptions) => http.get('/app/home/done', data),
|
||||||
|
},
|
||||||
|
sqConsignPt: {
|
||||||
|
/** 合同系统/签约授权 签约授权保存 */
|
||||||
|
post_saveSignMultiEntity: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/sqConsignPt/saveSignMultiEntity', data),
|
||||||
|
/** 合同系统/签约授权 签约授权查询 */
|
||||||
|
get_SigningaAuthorizationSerch: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/sqConsignPt/SigningaAuthorizationSerch', data),
|
||||||
|
/** 合同系统/签约授权 查询单条签约授权数据 */
|
||||||
|
get_getOne: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/sqConsignPt/getOne', data),
|
||||||
|
/** 合同系统/签约授权 签约授权提交 */
|
||||||
|
post_flowStart: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/sqConsignPt/flowStart', data),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,20 +86,20 @@ export const alovaInstance = createAlova({
|
||||||
statesHook: vueHook,
|
statesHook: vueHook,
|
||||||
requestAdapter: fetchAdapter(),
|
requestAdapter: fetchAdapter(),
|
||||||
/** 设置缓存状态:不开启 */
|
/** 设置缓存状态:不开启 */
|
||||||
// cacheFor: null,
|
cacheFor: null,
|
||||||
cacheFor: {
|
// cacheFor: {
|
||||||
// 统一设置POST的缓存模式
|
// // 统一设置POST的缓存模式
|
||||||
GET: {
|
// GET: {
|
||||||
mode: 'restore',
|
|
||||||
expire: 60 * 10 * 1000,
|
|
||||||
},
|
|
||||||
// POST: {
|
|
||||||
// mode: 'restore',
|
// mode: 'restore',
|
||||||
// expire: 60 * 10 * 1000
|
// expire: 60 * 10 * 1000,
|
||||||
|
// },
|
||||||
|
// // POST: {
|
||||||
|
// // mode: 'restore',
|
||||||
|
// // expire: 60 * 10 * 1000
|
||||||
|
// // },
|
||||||
|
// // // 统一设置HEAD请求的缓存模式
|
||||||
|
// // HEAD: 60 * 10 * 1000
|
||||||
// },
|
// },
|
||||||
// // 统一设置HEAD请求的缓存模式
|
|
||||||
// HEAD: 60 * 10 * 1000
|
|
||||||
},
|
|
||||||
/** 请求拦截器 */
|
/** 请求拦截器 */
|
||||||
beforeRequest: onAuthRequired((method) => {
|
beforeRequest: onAuthRequired((method) => {
|
||||||
const accessStore = useAccessStore();
|
const accessStore = useAccessStore();
|
||||||
|
@ -194,6 +194,9 @@ export const alovaInstance = createAlova({
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 请求配置处理中间件
|
||||||
|
function requestConfigMiddleware(method: string, url: string) {}
|
||||||
|
|
||||||
class Http {
|
class Http {
|
||||||
private appendParamsToUrl(url: string, params: any): string {
|
private appendParamsToUrl(url: string, params: any): string {
|
||||||
let queryString = '';
|
let queryString = '';
|
||||||
|
|
|
@ -43,7 +43,7 @@ export function transferResponse(response: any) {
|
||||||
code = 0;
|
code = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == 'failure' || (msg && msg.includes('token无效'))) {
|
if (code == 'failure' && msg && msg.includes('token无效')) {
|
||||||
code = 401;
|
code = 401;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,24 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { NotificationItem } from "@vben/layouts";
|
import type { NotificationItem } from './notification';
|
||||||
|
|
||||||
import { computed, ref } from "vue";
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import { storeToRefs, useAccessStore } from "@vben/stores";
|
|
||||||
|
import { storeToRefs, useAccessStore, useUserStore } from '@vben/stores';
|
||||||
// import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
|
// import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
|
||||||
|
|
||||||
import { AuthenticationLoginExpiredModal } from "@vben/common-ui";
|
import { useRouter } from 'vue-router';
|
||||||
import { BasicLayout, LockScreen, Notification, UserDropdown } from "@vben/layouts";
|
|
||||||
import { preferences } from "@vben/preferences";
|
import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
|
||||||
import { useUserStore } from "@vben/stores";
|
import { PhUserCircle } from '@vben/icons';
|
||||||
import { BookOpenText, CircleHelp, PhUserCircle } from "@vben/icons";
|
import { BasicLayout, LockScreen, UserDropdown } from '@vben/layouts';
|
||||||
|
import { preferences } from '@vben/preferences';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useAuthStore } from '#/store';
|
||||||
|
import { DICT_TYPE, getDictObj } from '#/utils/dict';
|
||||||
|
|
||||||
|
import { Notification } from './notification';
|
||||||
|
|
||||||
import { useAuthStore } from "#/store";
|
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const notifications = ref<NotificationItem[]>([
|
const notifications = ref<NotificationItem[]>([
|
||||||
|
@ -49,15 +55,17 @@ const notifications = ref<NotificationItem[]>([
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
const accessStore = useAccessStore();
|
const accessStore = useAccessStore();
|
||||||
const showDot = computed(() => notifications.value.some((item) => !item.isRead));
|
const showDot = computed(() =>
|
||||||
|
notifications.value.some((item) => !item.isRead),
|
||||||
|
);
|
||||||
|
|
||||||
const menus = computed(() => [
|
const menus = computed(() => [
|
||||||
{
|
{
|
||||||
handler: () => {
|
handler: () => {
|
||||||
router.push("/user/center");
|
router.push('/user/center');
|
||||||
},
|
},
|
||||||
icon: PhUserCircle,
|
icon: PhUserCircle,
|
||||||
text: "个人中心",
|
text: '个人中心',
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// handler: () => {
|
// handler: () => {
|
||||||
|
@ -98,21 +106,46 @@ function handleMakeAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleViewAll() {
|
function handleViewAll() {
|
||||||
console.log("viewAll");
|
console.log('viewAll');
|
||||||
router.push("/user/todo");
|
router.push('/user/todo');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDev = import.meta.env.MODE === 'development';
|
const isDev = import.meta.env.MODE === 'development';
|
||||||
const value = ref(localStorage.getItem("@@@proxy_type") || ""); // /zp
|
const value = ref(localStorage.getItem('@@@proxy_type') || ''); // /zp
|
||||||
function handleMenuClick(e) {
|
function handleMenuClick(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
if (e.key == "pro") {
|
if (e.key === 'pro') {
|
||||||
localStorage.setItem("@@@proxy_type", "");
|
localStorage.setItem('@@@proxy_type', '');
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem("@@@proxy_type", "/" + e.key);
|
localStorage.setItem('@@@proxy_type', `/${e.key}`);
|
||||||
}
|
}
|
||||||
location.reload()
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const data = await Apis.home.get_todo({
|
||||||
|
params: { pageNum: 1, pageSize: 20 },
|
||||||
|
});
|
||||||
|
|
||||||
|
notifications.value = data.rows.map((item) => {
|
||||||
|
let module =
|
||||||
|
getDictObj(DICT_TYPE.contract_todo_type, item.module)?.label || '';
|
||||||
|
module = module.slice(-4);
|
||||||
|
let moduleTextArr = [...module];
|
||||||
|
moduleTextArr =
|
||||||
|
moduleTextArr.length <= 3 ? moduleTextArr : moduleTextArr.slice(-4);
|
||||||
|
return {
|
||||||
|
moduleTextArr,
|
||||||
|
avatar: '',
|
||||||
|
date: item.createTime,
|
||||||
|
isRead: true,
|
||||||
|
message: item.contractName,
|
||||||
|
title: item.taskName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
console.log(notifications);
|
||||||
|
// resetAllStores();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -130,7 +163,7 @@ function handleMenuClick(e) {
|
||||||
<template #notification>
|
<template #notification>
|
||||||
<a-dropdown v-if="isDev">
|
<a-dropdown v-if="isDev">
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu @click="handleMenuClick" selectable>
|
<a-menu selectable @click="handleMenuClick">
|
||||||
<a-menu-item key="pro"> 正式 </a-menu-item>
|
<a-menu-item key="pro"> 正式 </a-menu-item>
|
||||||
<a-menu-item key="czg"> czg </a-menu-item>
|
<a-menu-item key="czg"> czg </a-menu-item>
|
||||||
<a-menu-item key="zp"> zp </a-menu-item>
|
<a-menu-item key="zp"> zp </a-menu-item>
|
||||||
|
@ -138,7 +171,7 @@ function handleMenuClick(e) {
|
||||||
<a-menu-item key="xmh"> xmh </a-menu-item>
|
<a-menu-item key="xmh"> xmh </a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
<a-button> {{ value ? "代理" + value : "代理切换" }} </a-button>
|
<a-button> {{ value ? `代理${value}` : '代理切换' }} </a-button>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
|
|
||||||
<Notification
|
<Notification
|
||||||
|
@ -160,7 +193,11 @@ function handleMenuClick(e) {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #lock-screen>
|
<template #lock-screen>
|
||||||
<LockScreen :avatar :text="userStore.userInfo?.displayName" @to-login="handleLogout" />
|
<LockScreen
|
||||||
|
:avatar
|
||||||
|
:text="userStore.userInfo?.displayName"
|
||||||
|
@to-login="handleLogout"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</BasicLayout>
|
</BasicLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { default as Notification } from './notification.vue';
|
||||||
|
|
||||||
|
export type * from './types';
|
|
@ -0,0 +1,187 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { NotificationItem } from './types';
|
||||||
|
|
||||||
|
import { Bell, MailCheck } from '@vben/icons';
|
||||||
|
import { $t } from '@vben/locales';
|
||||||
|
import {
|
||||||
|
VbenButton,
|
||||||
|
VbenIconButton,
|
||||||
|
VbenPopover,
|
||||||
|
VbenScrollbar,
|
||||||
|
} from '@vben-core/shadcn-ui';
|
||||||
|
|
||||||
|
import { useToggle } from '@vueuse/core';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* 显示圆点
|
||||||
|
*/
|
||||||
|
dot?: boolean;
|
||||||
|
/**
|
||||||
|
* 消息列表
|
||||||
|
*/
|
||||||
|
notifications?: NotificationItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
defineOptions({ name: 'NotificationPopup' });
|
||||||
|
|
||||||
|
withDefaults(defineProps<Props>(), {
|
||||||
|
dot: false,
|
||||||
|
notifications: () => [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
clear: [];
|
||||||
|
makeAll: [];
|
||||||
|
read: [NotificationItem];
|
||||||
|
viewAll: [];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const [open, toggle] = useToggle();
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
open.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleViewAll() {
|
||||||
|
emit('viewAll');
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMakeAll() {
|
||||||
|
emit('makeAll');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClear() {
|
||||||
|
emit('clear');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClick(item: NotificationItem) {
|
||||||
|
emit('read', item);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<VbenPopover
|
||||||
|
v-model:open="open"
|
||||||
|
content-class="relative right-2 w-[360px] p-0"
|
||||||
|
>
|
||||||
|
<template #trigger>
|
||||||
|
<div class="flex-center mr-2 h-full" @click.stop="toggle()">
|
||||||
|
<VbenIconButton class="bell-button text-foreground relative">
|
||||||
|
<span
|
||||||
|
v-if="dot"
|
||||||
|
class="bg-primary absolute right-0.5 top-0.5 h-2 w-2 rounded"
|
||||||
|
></span>
|
||||||
|
<Bell class="size-4" />
|
||||||
|
</VbenIconButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="relative">
|
||||||
|
<div class="flex items-center justify-between p-4 py-3">
|
||||||
|
<div class="text-foreground">{{ $t('widgets.notifications') }}</div>
|
||||||
|
<VbenIconButton
|
||||||
|
:tooltip="$t('widgets.markAllAsRead')"
|
||||||
|
@click="handleMakeAll"
|
||||||
|
>
|
||||||
|
<MailCheck class="size-4" />
|
||||||
|
</VbenIconButton>
|
||||||
|
</div>
|
||||||
|
<VbenScrollbar v-if="notifications.length > 0">
|
||||||
|
<ul class="!flex max-h-[360px] w-full flex-col">
|
||||||
|
<template v-for="item in notifications" :key="item.title">
|
||||||
|
<li
|
||||||
|
class="hover:bg-accent border-border relative flex w-full cursor-pointer items-start gap-5 border-t px-3 py-3"
|
||||||
|
@click="handleClick(item)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="!item.isRead"
|
||||||
|
class="bg-primary absolute right-2 top-2 h-2 w-2 rounded"
|
||||||
|
></span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="relative flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-blue-500 text-sm font-bold text-white"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex flex-wrap justify-center text-center leading-none"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-for="(char, index) in item.moduleTextArr"
|
||||||
|
:key="index"
|
||||||
|
class="w-1/2 p-0.5"
|
||||||
|
>
|
||||||
|
{{ char }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<div class="flex flex-col gap-1 leading-none">
|
||||||
|
<p class="font-semibold">{{ item.title }}</p>
|
||||||
|
<p class="text-muted-foreground my-1 line-clamp-2 text-xs">
|
||||||
|
{{ item.message }}
|
||||||
|
</p>
|
||||||
|
<p class="text-muted-foreground line-clamp-2 text-xs">
|
||||||
|
{{ item.date }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</VbenScrollbar>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<div class="flex-center text-muted-foreground min-h-[150px] w-full">
|
||||||
|
{{ $t('common.noData') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="border-border flex items-center justify-between border-t px-4 py-3"
|
||||||
|
>
|
||||||
|
<!-- <VbenButton size="sm" variant="ghost" @click="handleClear">
|
||||||
|
{{ $t('widgets.clearNotifications') }}
|
||||||
|
</VbenButton> -->
|
||||||
|
<div></div>
|
||||||
|
<VbenButton size="sm" @click="handleViewAll">
|
||||||
|
{{ $t('widgets.viewAll') }}
|
||||||
|
</VbenButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VbenPopover>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
:deep(.bell-button) {
|
||||||
|
&:hover {
|
||||||
|
svg {
|
||||||
|
animation: bell-ring 1s both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bell-ring {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform-origin: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
15% {
|
||||||
|
transform: rotateZ(10deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
30% {
|
||||||
|
transform: rotateZ(-10deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
45% {
|
||||||
|
transform: rotateZ(5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: rotateZ(-5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
transform: rotateZ(2deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,9 @@
|
||||||
|
interface NotificationItem {
|
||||||
|
avatar: string;
|
||||||
|
date: string;
|
||||||
|
isRead?: boolean;
|
||||||
|
message: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { NotificationItem };
|
|
@ -3,6 +3,12 @@ import { unmountGlobalLoading } from '@vben/utils';
|
||||||
|
|
||||||
import { overridesPreferences } from './preferences';
|
import { overridesPreferences } from './preferences';
|
||||||
|
|
||||||
|
// const dict = new Dictionary(http.get, {});
|
||||||
|
|
||||||
|
// dict.getAll('dict').then((res) => {
|
||||||
|
// console.log('dict', res);
|
||||||
|
// });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用初始化完成之后再进行页面加载渲染
|
* 应用初始化完成之后再进行页面加载渲染
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,10 +7,11 @@ import { startProgress, stopProgress } from '@vben/utils';
|
||||||
|
|
||||||
import { useTitle } from '@vueuse/core';
|
import { useTitle } from '@vueuse/core';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import { coreRouteNames, dynamicRoutes } from '#/router/routes';
|
import { coreRouteNames, dynamicRoutes } from '#/router/routes';
|
||||||
import { useAuthStore } from '#/store';
|
import { useAuthStore } from '#/store';
|
||||||
import Apis from '#/api';
|
|
||||||
import { generateAccess } from './access';
|
import { generateAccess } from './access';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,8 +58,12 @@ function setupCommonGuard(router: Router) {
|
||||||
* permission.path = "/xx/edit" 但route.path = "/xx/edit/:id?" 这种情况,其中id可以为任意值,如meetingId roleId等,
|
* permission.path = "/xx/edit" 但route.path = "/xx/edit/:id?" 这种情况,其中id可以为任意值,如meetingId roleId等,
|
||||||
*/
|
*/
|
||||||
function matchPaths(routePath, permissionPath) {
|
function matchPaths(routePath, permissionPath) {
|
||||||
const routeParts = routePath.split('/');
|
const routeParts = routePath.path.split('/');
|
||||||
const permissionParts = permissionPath.split('/');
|
const permissionParts = permissionPath.path.split('/');
|
||||||
|
|
||||||
|
if (routePath.name === permissionPath.id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (permissionParts.length > routeParts.length) {
|
if (permissionParts.length > routeParts.length) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -72,13 +77,14 @@ function matchPaths(routePath, permissionPath) {
|
||||||
// 过滤路由,只保留第三个数据源配置的路由
|
// 过滤路由,只保留第三个数据源配置的路由
|
||||||
function filterRoutesByPermissions(routes, permissions, staticRouteKeys) {
|
function filterRoutesByPermissions(routes, permissions, staticRouteKeys) {
|
||||||
const filteredRoutes = [];
|
const filteredRoutes = [];
|
||||||
for (let route of routes) {
|
for (const route of routes) {
|
||||||
// console.log('[ route ] >', route)
|
// console.log('[ route ] >', route)
|
||||||
// console.log('[ permission.path ] >', permissions)
|
// console.log('[ permission.path ] >', permissions)
|
||||||
|
|
||||||
const permission = permissions.find(permission =>
|
const permission = permissions.find((permission) =>
|
||||||
matchPaths(route.path, permission.path)
|
matchPaths(route, permission),
|
||||||
);
|
);
|
||||||
|
|
||||||
const isStaticRoute = staticRouteKeys.includes(route.name);
|
const isStaticRoute = staticRouteKeys.includes(route.name);
|
||||||
|
|
||||||
if (permission || isStaticRoute) {
|
if (permission || isStaticRoute) {
|
||||||
|
@ -89,16 +95,18 @@ function filterRoutesByPermissions(routes, permissions, staticRouteKeys) {
|
||||||
title: permission.name,
|
title: permission.name,
|
||||||
};
|
};
|
||||||
if (permission.order) {
|
if (permission.order) {
|
||||||
newRoute.meta.order = permission.order
|
newRoute.meta.order = permission.order;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (route.children) {
|
if (route.children) {
|
||||||
newRoute.children = filterRoutesByPermissions(route.children, permissions, staticRouteKeys);
|
newRoute.children = filterRoutesByPermissions(
|
||||||
|
route.children,
|
||||||
|
permissions,
|
||||||
|
staticRouteKeys,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
filteredRoutes.push(newRoute);
|
filteredRoutes.push(newRoute);
|
||||||
// console.log(JSON.parse(JSON.stringify(filteredRoutes)));
|
// console.log(JSON.parse(JSON.stringify(filteredRoutes)));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,16 +167,28 @@ function setupAccessGuard(router: Router) {
|
||||||
|
|
||||||
// 二开,从统一授权获取菜单key值,遍历本地所有菜单进行添加
|
// 二开,从统一授权获取菜单key值,遍历本地所有菜单进行添加
|
||||||
|
|
||||||
let staticRouteKeys = ["Dashboard", "home", "User", "UserCenter", "UserTodo","IFrame","MeetingStandingBook","MeetingStart","DutyStandingBook","ContractInfo"];
|
const staticRouteKeys = [
|
||||||
|
'Dashboard',
|
||||||
|
'home',
|
||||||
|
'User',
|
||||||
|
'UserCenter',
|
||||||
|
'UserTodo',
|
||||||
|
'IFrame',
|
||||||
|
'MeetingStandingBook',
|
||||||
|
'MeetingStart',
|
||||||
|
'DutyStandingBook',
|
||||||
|
'ContractInfo',
|
||||||
|
];
|
||||||
|
|
||||||
let r = await Apis.sys.user.functiontree.get_XTBGXT()
|
const r = await Apis.sys.user.functiontree.get_XTBGXT();
|
||||||
let originRouters = r.rows[0].children;
|
let originRouters = r.rows[0].children;
|
||||||
// 提取数据的函数
|
// 提取数据的函数
|
||||||
const extractData = (input: any[]) => {
|
const extractData = (input: any[]) => {
|
||||||
const result: any[] = [];
|
const result: any[] = [];
|
||||||
function traverse(node: any) {
|
function traverse(node: any) {
|
||||||
if (node.id && node.name && node.remark) {
|
if (node.id && node.name) {
|
||||||
result.push({
|
result.push({
|
||||||
|
id: node.id,
|
||||||
path: node.remark,
|
path: node.remark,
|
||||||
name: node.name,
|
name: node.name,
|
||||||
order: node.showOrder || 0,
|
order: node.showOrder || 0,
|
||||||
|
@ -186,26 +206,28 @@ function setupAccessGuard(router: Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
// console.log('originRouters', originRouters)
|
// console.log('originRouters', originRouters)
|
||||||
originRouters = extractData(originRouters);
|
originRouters = extractData(originRouters);
|
||||||
// console.log('originRouters', originRouters)
|
// console.log('originRouters', originRouters)
|
||||||
|
|
||||||
let finalRoutes = filterRoutesByPermissions(dynamicRoutes, originRouters, staticRouteKeys);
|
let finalRoutes = filterRoutesByPermissions(
|
||||||
|
dynamicRoutes,
|
||||||
console.log(originRouters)
|
originRouters,
|
||||||
|
staticRouteKeys,
|
||||||
|
);
|
||||||
|
console.log(originRouters);
|
||||||
// console.log('finalRoutes', finalRoutes)
|
// console.log('finalRoutes', finalRoutes)
|
||||||
|
|
||||||
// console.log('dynamicRoutes', dynamicRoutes)
|
// console.log('dynamicRoutes', dynamicRoutes)
|
||||||
// console.log('userInfo', userInfo)
|
// console.log('userInfo', userInfo)
|
||||||
|
|
||||||
if (userInfo.accountId == 'Admin.itl'|| userInfo._isSkip) {
|
if (userInfo.accountId == 'Admin.itl' || userInfo._isSkip) {
|
||||||
finalRoutes = dynamicRoutes;
|
finalRoutes = dynamicRoutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(userInfo)
|
// console.log(userInfo)
|
||||||
|
|
||||||
|
|
||||||
// 生成菜单和路由
|
// 生成菜单和路由
|
||||||
const { accessibleMenus, accessibleRoutes } = await generateAccess({
|
const { accessibleMenus, accessibleRoutes } = await generateAccess({
|
||||||
roles: userRoles,
|
roles: userRoles,
|
||||||
|
|
|
@ -9,7 +9,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
icon: 'lucide:layout-dashboard',
|
icon: 'lucide:layout-dashboard',
|
||||||
title: '合同配置',
|
title: '合同配置',
|
||||||
},
|
},
|
||||||
name: 'ContractConfig',
|
name: 'HTGLHTPZ',
|
||||||
path: '/contract/config',
|
path: '/contract/config',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ContractApproval',
|
name: 'HTGLHTLX',
|
||||||
path: '/contract/approval',
|
path: '/contract/approval',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -80,7 +80,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ContractBusiness',
|
name: 'HTGLHTXS',
|
||||||
path: '/contract/business',
|
path: '/contract/business',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -127,7 +127,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ContractDeclaration',
|
name: 'HTGLHTSB',
|
||||||
path: '/contract/declaration',
|
path: '/contract/declaration',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -212,7 +212,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
// ],
|
// ],
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: 'ContractSign',
|
name: 'HTGLHTQD',
|
||||||
path: '/contract/sign',
|
path: '/contract/sign',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -241,7 +241,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ContractPerform',
|
name: 'HTGLHTLVX',
|
||||||
path: '/contract/perform',
|
path: '/contract/perform',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -307,7 +307,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ContractArchive',
|
name: 'HTGLHTGD',
|
||||||
path: '/contract/archive',
|
path: '/contract/archive',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -347,7 +347,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ContractSignAuthorization',
|
name: 'HTGLHTQYSQ',
|
||||||
path: '/contract/sign-authorization',
|
path: '/contract/sign-authorization',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -385,7 +385,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ContractCompany',
|
name: 'HTGLHTXDR',
|
||||||
path: '/contract/company',
|
path: '/contract/company',
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
meta: {
|
meta: {
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { notification } from 'ant-design-vue';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
import { getUserInfoApi, loginApi } from '#/api/system/auth';
|
import { getUserInfoApi, loginApi } from '#/api/system/auth';
|
||||||
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
export const useAuthStore = defineStore('auth', () => {
|
export const useAuthStore = defineStore('auth', () => {
|
||||||
|
@ -34,20 +33,20 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
let userInfo: null | UserInfo = null;
|
let userInfo: null | UserInfo = null;
|
||||||
try {
|
try {
|
||||||
loginLoading.value = true;
|
loginLoading.value = true;
|
||||||
if(params.username == 'Admin.itl' || params._isSkip){
|
if (params.username == 'Admin.itl' || params._isSkip) {
|
||||||
}else{
|
} else {
|
||||||
params.username = params.username + '.RL'
|
params.username = `${params.username}.RL`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginRes = await loginApi({
|
const loginRes = await loginApi({
|
||||||
...params,
|
...params,
|
||||||
appId: 'PLRL',
|
appId: 'HTGLXT',
|
||||||
appName: 'ERP管理系统',
|
appName: '合同管理系统',
|
||||||
appSecret: 'r1og4wiyrrvr4qvw2aafhgvy',
|
appSecret: 'r1og4wiyrrvr4qvw2aafhgvy',
|
||||||
});
|
});
|
||||||
console.log(loginRes);
|
console.log(loginRes);
|
||||||
if (params._isSkip) {
|
if (params._isSkip) {
|
||||||
loginRes._isSkip = params._isSkip
|
loginRes._isSkip = params._isSkip;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginInfo = JSON.stringify(loginRes);
|
loginInfo = JSON.stringify(loginRes);
|
||||||
|
@ -63,7 +62,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
|
|
||||||
userInfo = fetchUserInfoResult;
|
userInfo = fetchUserInfoResult;
|
||||||
if (params._isSkip) {
|
if (params._isSkip) {
|
||||||
userInfo._isSkip = params._isSkip
|
userInfo._isSkip = params._isSkip;
|
||||||
}
|
}
|
||||||
userStore.setUserInfo(userInfo);
|
userStore.setUserInfo(userInfo);
|
||||||
|
|
||||||
|
@ -111,7 +110,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
async function fetchUserInfo() {
|
async function fetchUserInfo() {
|
||||||
let userInfo: null | UserInfo = null;
|
let userInfo: null | UserInfo = null;
|
||||||
userInfo = await getUserInfoApi();
|
userInfo = await getUserInfoApi();
|
||||||
userInfo = { ...JSON.parse(loginInfo), ...userInfo }
|
userInfo = { ...JSON.parse(loginInfo), ...userInfo };
|
||||||
userStore.setUserInfo(userInfo);
|
userStore.setUserInfo(userInfo);
|
||||||
return userInfo;
|
return userInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { defineStore } from 'pinia';
|
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
// import { getDictDataList } from '@/api/system/dict';
|
// import { getDictDataList } from '@/api/system/dict';
|
||||||
import Apis from '#/api';
|
import Apis from '#/api';
|
||||||
import dataModule from '#/utils/dict/static.data';
|
import dataModule from '#/utils/dict/static.data';
|
||||||
|
@ -9,7 +11,7 @@ const DICT_STORAGE_KEY = 'DICT_KEY';
|
||||||
interface DictDataVO {
|
interface DictDataVO {
|
||||||
dictType: string;
|
dictType: string;
|
||||||
label: string;
|
label: string;
|
||||||
value: string | number | null;
|
value: null | number | string;
|
||||||
colorType: string;
|
colorType: string;
|
||||||
cssClass: string;
|
cssClass: string;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +39,7 @@ export const useDictStore = defineStore('app-dict', () => {
|
||||||
const setDictMap = async (): Promise<boolean> => {
|
const setDictMap = async (): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
const data = await Apis.dictData.get_page({
|
const data = await Apis.dictData.get_page({
|
||||||
params: { pageNum: 1, pageSize: 10000 },
|
params: { pageNum: 1, pageSize: 10_000 },
|
||||||
});
|
});
|
||||||
const dictDataMap: Record<string, DictDataVO[]> = {};
|
const dictDataMap: Record<string, DictDataVO[]> = {};
|
||||||
// 处理静态字典数据
|
// 处理静态字典数据
|
||||||
|
@ -85,38 +87,45 @@ export const useDictStore = defineStore('app-dict', () => {
|
||||||
const getDictData = async (
|
const getDictData = async (
|
||||||
dictTypeArr: string[],
|
dictTypeArr: string[],
|
||||||
): Promise<Record<string, DictDataVO[]>> => {
|
): Promise<Record<string, DictDataVO[]>> => {
|
||||||
if (initDict.value) {
|
|
||||||
const newDictMap: Record<string, DictDataVO[]> = {};
|
const newDictMap: Record<string, DictDataVO[]> = {};
|
||||||
if (isSetDict.value && Object.keys(dictMap.value).length) {
|
|
||||||
|
return await new Promise((resolve) => {
|
||||||
|
if (
|
||||||
|
initDict.value &&
|
||||||
|
isSetDict.value &&
|
||||||
|
Object.keys(dictMap.value).length > 0
|
||||||
|
) {
|
||||||
dictTypeArr.forEach((dictType) => {
|
dictTypeArr.forEach((dictType) => {
|
||||||
newDictMap[dictType] = dictMap.value[dictType] || [];
|
newDictMap[dictType] = dictMap.value[dictType] || [];
|
||||||
});
|
});
|
||||||
return newDictMap;
|
resolve(newDictMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSetDict.value) {
|
// if (!isSetDict.value) {
|
||||||
console.warn('字典数据尚未加载,正在等待...');
|
// console.warn('字典数据尚未加载,正在等待...');
|
||||||
await new Promise((resolve) => {
|
|
||||||
const checkInterval = setInterval(() => {
|
|
||||||
if (isSetDict.value) {
|
|
||||||
clearInterval(checkInterval);
|
|
||||||
dictTypeArr.forEach((dictType) => {
|
|
||||||
newDictMap[dictType] = dictMap.value[dictType] || [];
|
|
||||||
});
|
|
||||||
resolve(true);
|
|
||||||
}
|
|
||||||
}, 45);
|
|
||||||
});
|
|
||||||
return newDictMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
// const checkInterval = setInterval(() => {
|
||||||
return {};
|
// console.warn('字典数据加载中...');
|
||||||
} catch (error) {
|
|
||||||
console.error('getDictMap 函数报错:', error);
|
// if (isSetDict.value) {
|
||||||
return {};
|
// console.warn('字典数据完成.');
|
||||||
}
|
// clearInterval(checkInterval);
|
||||||
|
// dictTypeArr.forEach((dictType) => {
|
||||||
|
// newDictMap[dictType] = dictMap.value[dictType] || [];
|
||||||
|
// });
|
||||||
|
// resolve(newDictMap);
|
||||||
|
// }
|
||||||
|
// }, 45);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// return {};
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('getDictMap 函数报错:', error);
|
||||||
|
// return {};
|
||||||
|
// }
|
||||||
|
resolve(newDictMap);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/** 数据字典工具类 */
|
/** 数据字典工具类 */
|
||||||
import { useDictStore } from '#/store/dict';
|
import { useDictStore } from '#/store/dict';
|
||||||
|
|
||||||
|
@ -15,7 +14,7 @@ const dictStore = useDictStore();
|
||||||
export interface DictDataType {
|
export interface DictDataType {
|
||||||
dictTyp?: string;
|
dictTyp?: string;
|
||||||
label: string;
|
label: string;
|
||||||
value: string | number | null;
|
value: null | number | string;
|
||||||
key?: any;
|
key?: any;
|
||||||
colorType?: string;
|
colorType?: string;
|
||||||
cssClass?: string;
|
cssClass?: string;
|
||||||
|
@ -24,7 +23,7 @@ export interface DictDataType {
|
||||||
|
|
||||||
export interface DictDataOptions {
|
export interface DictDataOptions {
|
||||||
label?: any;
|
label?: any;
|
||||||
value?: string | number | null;
|
value?: null | number | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDictDatas(dictType: string) {
|
export function getDictDatas(dictType: string) {
|
||||||
|
@ -40,7 +39,10 @@ export function getDictOpts(dictType: string) {
|
||||||
return getDictDatas(dictType);
|
return getDictDatas(dictType);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDictOptions(dictType: string, valueType?: 'string' | 'number' | 'boolean'): any[] {
|
export function getDictOptions(
|
||||||
|
dictType: string,
|
||||||
|
valueType?: 'boolean' | 'number' | 'string',
|
||||||
|
): any[] {
|
||||||
const dictOption: DictDataType[] = [];
|
const dictOption: DictDataType[] = [];
|
||||||
valueType ||= 'string';
|
valueType ||= 'string';
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ export function getDictOptions(dictType: string, valueType?: 'string' | 'number'
|
||||||
? `${dict.value}`
|
? `${dict.value}`
|
||||||
: valueType === 'boolean'
|
: valueType === 'boolean'
|
||||||
? `${dict.value}` === 'true'
|
? `${dict.value}` === 'true'
|
||||||
: Number.parseInt(`${dict.value}`)
|
: Number.parseInt(`${dict.value}`),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -68,7 +70,11 @@ export function getDictObj(dictType: string, value: any): DictDataType | null {
|
||||||
const dictOptions: DictDataType[] = getDictDatas(dictType);
|
const dictOptions: DictDataType[] = getDictDatas(dictType);
|
||||||
if (dictOptions) {
|
if (dictOptions) {
|
||||||
if (value) {
|
if (value) {
|
||||||
return dictOptions.find((dict: DictDataType) => dict.value === value.toString()) || null;
|
return (
|
||||||
|
dictOptions.find(
|
||||||
|
(dict: DictDataType) => dict.value === value.toString(),
|
||||||
|
) || null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,9 +85,8 @@ export function getDictObj(dictType: string, value: any): DictDataType | null {
|
||||||
/** 获取字典默认数据 */
|
/** 获取字典默认数据 */
|
||||||
export function getDictDefaultObj(dictType: string): DictDataType | null {
|
export function getDictDefaultObj(dictType: string): DictDataType | null {
|
||||||
const dictOptions: DictDataType[] = getDictDatas(dictType);
|
const dictOptions: DictDataType[] = getDictDatas(dictType);
|
||||||
if (dictOptions) {
|
return dictOptions
|
||||||
return dictOptions.find((dict: DictDataType) => dict.isDefault == '1') || dictOptions[0];
|
? dictOptions.find((dict: DictDataType) => dict.isDefault == '1') ||
|
||||||
} else {
|
dictOptions[0]
|
||||||
return null;
|
: null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,5 +51,7 @@ export enum DICT_TYPE {
|
||||||
/** 合同立项节点流程 */
|
/** 合同立项节点流程 */
|
||||||
contract_abolish_flow_node = 'contract_abolish_flow_node',
|
contract_abolish_flow_node = 'contract_abolish_flow_node',
|
||||||
/** 合同授权期限 */
|
/** 合同授权期限 */
|
||||||
contract_authorization_period = 'contract_authorization_period'
|
contract_authorization_period = 'contract_authorization_period',
|
||||||
|
/** 合同待办类型 */
|
||||||
|
contract_todo_type = 'contract_todo_type'
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,22 @@ export default {
|
||||||
|
|
||||||
// 授权期限
|
// 授权期限
|
||||||
contract_authorization_period: createEntry('合同授权期限', [
|
contract_authorization_period: createEntry('合同授权期限', [
|
||||||
{ label: '确定', value: 'forever' },
|
{ label: '确定', value: '0' },
|
||||||
{ label: '不确定', value: 'date' },
|
{ label: '不确定', value: '1' },
|
||||||
|
]),
|
||||||
|
|
||||||
|
// 合同待办类型
|
||||||
|
contract_todo_type: createEntry('合同待办类型', [
|
||||||
|
{ label: '合同立项', value: 'contractSetup' },
|
||||||
|
{ label: '合同立项废除', value: 'contractSetupAbolish' },
|
||||||
|
{ label: '合同选商', value: 'selectMerchant' },
|
||||||
|
{ label: '合同选商废除', value: 'selectMerchantAbolish' },
|
||||||
|
{ label: '合同选商结果', value: 'selectMerchantResult' },
|
||||||
|
{ label: '合同选商结果废除', value: 'selectMerchantResultAbolish' },
|
||||||
|
{ label: '合同申报', value: 'contractDeclare' },
|
||||||
|
{ label: '合同签订', value: 'contractSign' },
|
||||||
|
{ label: '合同履行', value: 'contractPerform' },
|
||||||
|
{ label: '合同归档', value: 'contractFile' },
|
||||||
|
{ label: '签约授权', value: 'signAuthorization' },
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,7 +49,7 @@ export function getFormSchema(params: any = {}) {
|
||||||
class: 'min-w-[200px]',
|
class: 'min-w-[200px]',
|
||||||
prototype: true,
|
prototype: true,
|
||||||
dict: dict({
|
dict: dict({
|
||||||
async getData({ form = {} }) {
|
async getData(_context) {
|
||||||
return filterContractTypes(contractTypeData, '-1');
|
return filterContractTypes(contractTypeData, '-1');
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -186,8 +186,9 @@ onMounted(async () => {
|
||||||
|
|
||||||
<template #operate="{ row }">
|
<template #operate="{ row }">
|
||||||
<a-button
|
<a-button
|
||||||
|
class="text-primary"
|
||||||
size="small"
|
size="small"
|
||||||
type="primary"
|
type="text"
|
||||||
@click="toDetailPage('approval', row.guid)"
|
@click="toDetailPage('approval', row.guid)"
|
||||||
>
|
>
|
||||||
查看
|
查看
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<script lang="tsx" setup>
|
<script lang="tsx" setup>
|
||||||
import { ref, nextTick } from 'vue';
|
import { nextTick, ref } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import dayjs, { Dayjs } from 'dayjs';
|
import { MdiCloudUpload } from '@vben/icons';
|
||||||
import Apis from '#/api';
|
|
||||||
import { message, type UploadChangeParam } from 'ant-design-vue';
|
|
||||||
import { FileUploader } from '#/utils/file';
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
import { DICT_TYPE, getDictOptions, getDictObj } from '#/utils/dict';
|
import { message, type UploadChangeParam } from 'ant-design-vue';
|
||||||
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { DICT_TYPE, getDictObj, getDictOptions } from '#/utils/dict';
|
||||||
|
import { FileUploader } from '#/utils/file';
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'success'): void;
|
(e: 'success'): void;
|
||||||
|
@ -20,7 +24,7 @@ const data = ref({
|
||||||
});
|
});
|
||||||
|
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
let isConfirmLoading = ref(false);
|
const isConfirmLoading = ref(false);
|
||||||
|
|
||||||
const formBinding = ref({
|
const formBinding = ref({
|
||||||
col: { span: 24 },
|
col: { span: 24 },
|
||||||
|
@ -35,8 +39,8 @@ const formBinding = ref({
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
dict: dict({
|
dict: dict({
|
||||||
async getData(form) {
|
async getData() {
|
||||||
return getDictOptions(DICT_TYPE.contract_basis_type);
|
return await getDictOptions(DICT_TYPE.contract_basis_type);
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -81,7 +85,7 @@ const formBinding = ref({
|
||||||
component: {
|
component: {
|
||||||
name: 'a-textarea',
|
name: 'a-textarea',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
props: {},
|
autoSize: { minRows: 4, maxRows: 6 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fileList: {
|
fileList: {
|
||||||
|
@ -93,7 +97,7 @@ const formBinding = ref({
|
||||||
|
|
||||||
const handleChange = (info: UploadChangeParam) => {
|
const handleChange = (info: UploadChangeParam) => {
|
||||||
formRef.value.setFormData({
|
formRef.value.setFormData({
|
||||||
fileList: info.fileList.length ? info.fileList : [],
|
fileList: info.fileList.length > 0 ? info.fileList : [],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,7 +109,7 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
data.value = baseModalApi.getData<Record<string, any>>() || {};
|
data.value = baseModalApi.getData<Record<string, any>>() || {};
|
||||||
if (data.value.isUpdate) {
|
if (data.value.isUpdate) {
|
||||||
if (data.value.record.fileUuid) {
|
if (data.value.record.fileUuid) {
|
||||||
let files = await fileUploader.select(data.value.record.fileUuid);
|
const files = await fileUploader.select(data.value.record.fileUuid);
|
||||||
console.log(files);
|
console.log(files);
|
||||||
data.value.record.fileList = files;
|
data.value.record.fileList = files;
|
||||||
}
|
}
|
||||||
|
@ -123,11 +127,11 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
console.log(formRef.value?.form);
|
console.log(formRef.value?.form);
|
||||||
await formRef.value?.submit();
|
await formRef.value?.submit();
|
||||||
|
|
||||||
let form = formRef.value.form;
|
const form = formRef.value.form;
|
||||||
{
|
{
|
||||||
let tempFileList = form.fileList;
|
const tempFileList = form.fileList;
|
||||||
let tempFiles: any = [];
|
let tempFiles: any = [];
|
||||||
if (tempFileList && tempFileList.length) {
|
if (tempFileList && tempFileList.length > 0) {
|
||||||
tempFiles = await fileUploader.upload(tempFileList, { source: 'ht' });
|
tempFiles = await fileUploader.upload(tempFileList, { source: 'ht' });
|
||||||
}
|
}
|
||||||
console.log(tempFiles);
|
console.log(tempFiles);
|
||||||
|
@ -142,7 +146,7 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
if (form.basisTypeId) {
|
if (form.basisTypeId) {
|
||||||
form.basisTypeName = getDictObj(
|
form.basisTypeName = getDictObj(
|
||||||
DICT_TYPE.contract_basis_type,
|
DICT_TYPE.contract_basis_type,
|
||||||
row.basisTypeId,
|
form.basisTypeId,
|
||||||
)?.label;
|
)?.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,18 +167,18 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BaseModal
|
<BaseModal
|
||||||
:title="data.isUpdate ? '修改签约依据信息' : '新增签约依据信息'"
|
:confirm-loading="isConfirmLoading"
|
||||||
:loading="isConfirmLoading"
|
:loading="isConfirmLoading"
|
||||||
:confirmLoading="isConfirmLoading"
|
:title="data.isUpdate ? '修改签约依据信息' : '新增签约依据信息'"
|
||||||
>
|
>
|
||||||
<fs-form ref="formRef" v-bind="formBinding">
|
<fs-form ref="formRef" v-bind="formBinding">
|
||||||
<template #form_fileList="{ form }">
|
<template #form_fileList="{ form }">
|
||||||
<a-upload-dragger
|
<a-upload-dragger
|
||||||
v-model:fileList="form.fileList"
|
v-model:file-list="form.fileList"
|
||||||
accept=".pdf"
|
|
||||||
:max-count="1"
|
|
||||||
name="file"
|
|
||||||
:before-upload="() => false"
|
:before-upload="() => false"
|
||||||
|
:max-count="1"
|
||||||
|
accept=".pdf"
|
||||||
|
name="file"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
|
|
|
@ -1,12 +1,163 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive } from 'vue';
|
||||||
|
|
||||||
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
|
const { xGridRef: xGrid2Ref, triggerProxy: triggerProxy2 } = useVxeTable({
|
||||||
|
ref: 'xGrid2Ref',
|
||||||
|
});
|
||||||
|
|
||||||
|
/** Hooks - 表格 */
|
||||||
|
const gridOptions = reactive(
|
||||||
|
gridProps({
|
||||||
|
columns: [
|
||||||
|
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
||||||
|
{ field: 'contractId', title: '编号', width: 100 },
|
||||||
|
{
|
||||||
|
field: 'title',
|
||||||
|
title: '名称',
|
||||||
|
minWidth: 200,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
// let text = row.title
|
||||||
|
// if (text) {
|
||||||
|
// let classArr: string[] = ["line-clamp-3"];
|
||||||
|
// return h(
|
||||||
|
// NTooltip,
|
||||||
|
// { trigger: 'hover' },
|
||||||
|
// {
|
||||||
|
// trigger: () => h('span', { class: classArr.join(' ') }, text),
|
||||||
|
// default: () => text
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'contractAmount', title: '模块', width: 150 },
|
||||||
|
{ field: 'contractSubject', title: '任务', width: 200 },
|
||||||
|
{ field: 'contractCounterparty', title: '分配时间', width: 150 },
|
||||||
|
{
|
||||||
|
field: 'cumulativeSettlementAmount',
|
||||||
|
title: '承办单位/部门',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{ field: 'changeCount', title: '承办人', width: 100 },
|
||||||
|
{ field: 'contractStatus', title: '交接给', width: 100 },
|
||||||
|
],
|
||||||
|
proxyConfig: {
|
||||||
|
autoLoad: true,
|
||||||
|
ajax: {
|
||||||
|
query: ({ page }) => {
|
||||||
|
return Apis.home.get_todo({
|
||||||
|
params: {
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Hooks - 表格 */
|
||||||
|
const grid2Options = reactive(
|
||||||
|
gridProps({
|
||||||
|
columns: [
|
||||||
|
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
||||||
|
{ field: 'contractId', title: '编号', width: 100 },
|
||||||
|
{
|
||||||
|
field: 'title',
|
||||||
|
title: '名称',
|
||||||
|
minWidth: 200,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
// let text = row.title
|
||||||
|
// if (text) {
|
||||||
|
// let classArr: string[] = ["line-clamp-3"];
|
||||||
|
// return h(
|
||||||
|
// NTooltip,
|
||||||
|
// { trigger: 'hover' },
|
||||||
|
// {
|
||||||
|
// trigger: () => h('span', { class: classArr.join(' ') }, text),
|
||||||
|
// default: () => text
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'contractAmount', title: '模块', width: 150 },
|
||||||
|
{ field: 'contractSubject', title: '任务', width: 200 },
|
||||||
|
{ field: 'contractCounterparty', title: '分配时间', width: 150 },
|
||||||
|
{
|
||||||
|
field: 'cumulativeSettlementAmount',
|
||||||
|
title: '承办单位/部门',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{ field: 'changeCount', title: '承办人', width: 100 },
|
||||||
|
{ field: 'contractStatus', title: '交接给', width: 100 },
|
||||||
|
],
|
||||||
|
proxyConfig: {
|
||||||
|
autoLoad: true,
|
||||||
|
ajax: {
|
||||||
|
query: ({ page }) => {
|
||||||
|
return Apis.home.get_done({
|
||||||
|
params: {
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page contentClass="h-full flex flex-col">
|
<Page content-class="h-full flex flex-col">
|
||||||
<a-space direction="vertical" size="small">
|
<a-space class="flex h-full flex-col" direction="vertical" size="small">
|
||||||
<a-card title="待办" size="small">
|
<a-card
|
||||||
|
:body-style="{ flex: '1' }"
|
||||||
|
class="flex h-full flex-col"
|
||||||
|
size="small"
|
||||||
|
title="待办"
|
||||||
|
>
|
||||||
<vxe-grid ref="xGridRef" v-bind="gridOptions">
|
<vxe-grid ref="xGridRef" v-bind="gridOptions">
|
||||||
<template #toolbar_buttons> </template>
|
<template #toolbar_buttons> </template>
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card title="已办" size="small" contentClass="">
|
<a-card
|
||||||
|
:body-style="{ flex: '1' }"
|
||||||
|
class="flex h-full flex-col"
|
||||||
|
size="small"
|
||||||
|
title="已办"
|
||||||
|
>
|
||||||
<vxe-grid ref="xGrid2Ref" v-bind="grid2Options">
|
<vxe-grid ref="xGrid2Ref" v-bind="grid2Options">
|
||||||
<template #toolbar_buttons> </template>
|
<template #toolbar_buttons> </template>
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
|
@ -15,168 +166,8 @@
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<style scoped>
|
||||||
import { defineComponent, ref, reactive, onMounted } from 'vue';
|
:deep(.ant-space-item) {
|
||||||
import { FsCrud } from '@fast-crud/fast-crud';
|
flex: 1;
|
||||||
import { type VxeGridProps } from 'vxe-table'
|
}
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
</style>
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
|
||||||
import {
|
|
||||||
type CreateCrudOptionsProps,
|
|
||||||
useColumns,
|
|
||||||
useFormWrapper,
|
|
||||||
useFs,
|
|
||||||
utils,
|
|
||||||
} from '@fast-crud/fast-crud';
|
|
||||||
import { MdiAdd, MdiUpdate, MdiDelete } from '@vben/icons';
|
|
||||||
import { dict } from "@fast-crud/fast-crud";
|
|
||||||
|
|
||||||
import Apis from '#/api'
|
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
|
||||||
|
|
||||||
const { xGridRef:xGrid2Ref, triggerProxy:triggerProxy2 } = useVxeTable({ ref: 'xGrid2Ref' });
|
|
||||||
|
|
||||||
|
|
||||||
const treeData = ref([]);
|
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
|
||||||
const gridOptions = reactive(gridProps({
|
|
||||||
columns: [
|
|
||||||
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
|
||||||
{ field: 'contractId', title: '编号', width: 100 },
|
|
||||||
{
|
|
||||||
field: 'title', title: '名称', minWidth: 200, slots: {
|
|
||||||
default: ({ row }) => {
|
|
||||||
// let text = row.title
|
|
||||||
// if (text) {
|
|
||||||
// let classArr: string[] = ["line-clamp-3"];
|
|
||||||
// return h(
|
|
||||||
// NTooltip,
|
|
||||||
// { trigger: 'hover' },
|
|
||||||
// {
|
|
||||||
// trigger: () => h('span', { class: classArr.join(' ') }, text),
|
|
||||||
// default: () => text
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ field: 'contractAmount', title: '模块', width: 150 },
|
|
||||||
{ field: 'contractSubject', title: '任务', width: 200 },
|
|
||||||
{ field: 'contractCounterparty', title: '分配时间', width: 150 },
|
|
||||||
{ field: 'cumulativeSettlementAmount', title: '承办单位/部门', width: 150 },
|
|
||||||
{ field: 'changeCount', title: '承办人', width: 100 },
|
|
||||||
{ field: 'contractStatus', title: '交接给', width: 100 }
|
|
||||||
],
|
|
||||||
proxyConfig: {
|
|
||||||
autoLoad: true,
|
|
||||||
ajax: {
|
|
||||||
query: ({ page }) => {
|
|
||||||
return Apis.ccsq.get_toDoPage({ params: { pageNum: page.currentPage, pageSize: page.pageSize, ...searchParams } })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pagerConfig: {
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
toolbarConfig: {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
|
||||||
const grid2Options = reactive(gridProps({
|
|
||||||
columns: [
|
|
||||||
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
|
||||||
{ field: 'contractId', title: '编号', width: 100 },
|
|
||||||
{
|
|
||||||
field: 'title', title: '名称', minWidth: 200, slots: {
|
|
||||||
default: ({ row }) => {
|
|
||||||
// let text = row.title
|
|
||||||
// if (text) {
|
|
||||||
// let classArr: string[] = ["line-clamp-3"];
|
|
||||||
// return h(
|
|
||||||
// NTooltip,
|
|
||||||
// { trigger: 'hover' },
|
|
||||||
// {
|
|
||||||
// trigger: () => h('span', { class: classArr.join(' ') }, text),
|
|
||||||
// default: () => text
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ field: 'contractAmount', title: '模块', width: 150 },
|
|
||||||
{ field: 'contractSubject', title: '任务', width: 200 },
|
|
||||||
{ field: 'contractCounterparty', title: '分配时间', width: 150 },
|
|
||||||
{ field: 'cumulativeSettlementAmount', title: '承办单位/部门', width: 150 },
|
|
||||||
{ field: 'changeCount', title: '承办人', width: 100 },
|
|
||||||
{ field: 'contractStatus', title: '交接给', width: 100 }
|
|
||||||
],
|
|
||||||
proxyConfig: {
|
|
||||||
autoLoad: true,
|
|
||||||
ajax: {
|
|
||||||
query: ({ page }) => {
|
|
||||||
return Apis.ccsq.get_donePage({ params: { pageNum: page.currentPage, pageSize: page.pageSize, ...searchParams } })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pagerConfig: {
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
toolbarConfig: {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
})
|
|
||||||
|
|
||||||
let searchParams = reactive({})
|
|
||||||
const searchForm = ref({
|
|
||||||
columns: {
|
|
||||||
name: {
|
|
||||||
component: {
|
|
||||||
name: 'a-input',
|
|
||||||
vModel: 'value',
|
|
||||||
allowClear: true,
|
|
||||||
props: {
|
|
||||||
type: 'text',
|
|
||||||
showWordLimit: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
title: '字典标签',
|
|
||||||
key: 'type',
|
|
||||||
autoSearchTrigger: 'enter',
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
age: {
|
|
||||||
component: {
|
|
||||||
name: 'a-input',
|
|
||||||
vModel: 'value',
|
|
||||||
allowClear: true,
|
|
||||||
},
|
|
||||||
title: '字典键值',
|
|
||||||
key: 'value',
|
|
||||||
autoSearchTrigger: 'enter',
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
onSearch(context: any) {
|
|
||||||
searchParams = context.form
|
|
||||||
triggerProxy('reload')
|
|
||||||
},
|
|
||||||
onReset(context: any) {
|
|
||||||
searchParams = context.form
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// 页面打开后获取列表数据
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import type { VxeGridPropTypes } from 'vxe-table';
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
|
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { Tooltip } from 'ant-design-vue';
|
import { Tooltip } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { DICT_TYPE, getDictObj } from '#/utils/dict';
|
||||||
|
|
||||||
export const PrimaryKey = 'guid';
|
export const PrimaryKey = 'guid';
|
||||||
|
|
||||||
/** 获取待办/已办列表的列 */
|
/** 获取待办/已办列表的列 */
|
||||||
|
@ -10,33 +14,35 @@ export function getTodoColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||||
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
||||||
{ field: 'contractId', title: '编号', width: 100 },
|
{ field: 'contractId', title: '编号', width: 100 },
|
||||||
{
|
{
|
||||||
field: 'title',
|
field: 'contractName',
|
||||||
title: '名称',
|
title: '名称',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
|
slots: { default: 'title_slot' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'module',
|
||||||
|
title: '模块',
|
||||||
|
width: 150,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
let text = row.title;
|
return (
|
||||||
if (text) {
|
getDictObj(DICT_TYPE.contract_todo_type, row.module)?.label || ''
|
||||||
let classArr: string[] = ['line-clamp-3'];
|
|
||||||
return h(
|
|
||||||
Tooltip,
|
|
||||||
{ trigger: 'hover' },
|
|
||||||
{
|
|
||||||
trigger: () => h('span', { class: classArr.join(' ') }, text),
|
|
||||||
default: () => text,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return '';
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: 'contractAmount', title: '模块', width: 150 },
|
{ field: 'taskName', title: '任务', width: 200 },
|
||||||
{ field: 'contractSubject', title: '任务', width: 200 },
|
{ field: 'createTime', title: '分配时间', width: 150 },
|
||||||
{ field: 'contractCounterparty', title: '分配时间', width: 150 },
|
{ field: 'inputDepartName', title: '承办单位/部门', width: 150 },
|
||||||
{ field: 'cumulativeSettlementAmount', title: '承办单位/部门', width: 150 },
|
{ field: 'assignee', title: '承办人', width: 100 },
|
||||||
{ field: 'changeCount', title: '承办人', width: 100 },
|
{
|
||||||
{ field: 'contractStatus', title: '交接给', width: 100 },
|
field: 'operate',
|
||||||
|
title: '操作',
|
||||||
|
width: 60,
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'operate' },
|
||||||
|
},
|
||||||
|
// { field: 'contractStatus', title: '交接给', width: 100 },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +59,9 @@ export function getApprovalColumns(
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
let text = row.title;
|
const text = row.title;
|
||||||
if (text) {
|
if (text) {
|
||||||
let classArr: string[] = ['line-clamp-3'];
|
const classArr: string[] = ['line-clamp-3'];
|
||||||
return h(
|
return h(
|
||||||
Tooltip,
|
Tooltip,
|
||||||
{ trigger: 'hover' },
|
{ trigger: 'hover' },
|
||||||
|
|
|
@ -3,10 +3,12 @@ import { ref } from 'vue';
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import dayjs, { type Dayjs } from 'dayjs';
|
||||||
import { VxeGrid, type VxeGridPropTypes } from 'vxe-table';
|
import { VxeGrid, type VxeGridPropTypes } from 'vxe-table';
|
||||||
|
|
||||||
import { unitComponentProps } from '#/common/unit';
|
import { unitComponentProps } from '#/common/unit';
|
||||||
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
import { DICT_TYPE, getDictObj, getDictOptions } from '#/utils/dict';
|
||||||
import chooseUserModal from '#/views/system/user/choose-user-modal.vue';
|
import chooseUserModal from '#/views/system/user/choose-user-modal.vue';
|
||||||
|
|
||||||
const [ChooseUserModal, chooseUserModalApi] = useVbenModal({
|
const [ChooseUserModal, chooseUserModalApi] = useVbenModal({
|
||||||
|
@ -23,7 +25,8 @@ export function getUserColumns(_params?: any): VxeGridPropTypes.Columns {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFormSchema(_params?: any): any {
|
export function getFormSchema(params?: any): any {
|
||||||
|
const { formRef } = params || {};
|
||||||
const xGridRef = ref();
|
const xGridRef = ref();
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
|
@ -38,67 +41,99 @@ export function getFormSchema(_params?: any): any {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const disabledDate = (current: Dayjs) => {
|
||||||
|
const form = formRef.value.form;
|
||||||
|
return current && current < dayjs(form.consignDateBegin);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdateFormattedValue = () => {
|
||||||
|
const { consignDateBegin, consignDateEnd } = formRef.value.form;
|
||||||
|
|
||||||
|
if (
|
||||||
|
consignDateBegin &&
|
||||||
|
consignDateEnd &&
|
||||||
|
consignDateEnd < consignDateBegin
|
||||||
|
) {
|
||||||
|
message.error('截止时间不能早于开始时间');
|
||||||
|
formRef.value.setFormData({
|
||||||
|
consignDateEnd: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
col: { span: 24 },
|
col: { span: 24 },
|
||||||
initialForm: {
|
initialForm: {
|
||||||
|
entrustUserName: '克拉玛依市热力有限责任公司',
|
||||||
|
lawUserId: '',
|
||||||
|
lawUserName: '吴兴明',
|
||||||
|
positionName: '经理',
|
||||||
contractName: '',
|
contractName: '',
|
||||||
priceType: 'CNY',
|
priceType: 'CNY',
|
||||||
isBid: '0',
|
isBid: '0',
|
||||||
},
|
},
|
||||||
labelCol: { style: { width: '120px' } },
|
labelCol: { style: { width: '120px' } },
|
||||||
columns: {
|
columns: {
|
||||||
projectNum: {
|
entrustUserName: {
|
||||||
title: '委托人',
|
title: '委托人',
|
||||||
key: 'projectNum',
|
key: 'entrustUserName',
|
||||||
col: { span: 12 },
|
col: { span: 8 },
|
||||||
component: {
|
component: {
|
||||||
name: 'a-input',
|
name: 'a-input',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
},
|
},
|
||||||
render({ form }) {
|
render({ form }) {
|
||||||
return <span>{form.projectNum}</span>;
|
return <span>{form.entrustUserName}</span>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
projectProp: {
|
lawUserName: {
|
||||||
title: '法定代表人',
|
title: '法定代表人',
|
||||||
key: 'projectProp',
|
key: 'lawUserName',
|
||||||
col: { span: 12 },
|
col: { span: 8 },
|
||||||
component: {
|
component: {
|
||||||
name: 'a-input',
|
name: 'a-input',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
},
|
},
|
||||||
render(_context) {
|
render({ form }) {
|
||||||
return <span></span>;
|
return <span>{form.lawUserName}</span>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
projectProp1: {
|
positionName: {
|
||||||
title: '职务',
|
title: '职务',
|
||||||
key: 'projectProp1',
|
key: 'positionName',
|
||||||
col: { span: 12 },
|
col: { span: 8 },
|
||||||
component: {
|
component: {
|
||||||
name: 'a-input',
|
name: 'a-input',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
},
|
},
|
||||||
render(_context) {
|
render({ form }) {
|
||||||
return <span></span>;
|
return <span>{form.positionName}</span>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
projectProp2: {
|
consignType: {
|
||||||
title: '授权类型',
|
title: '授权类型',
|
||||||
key: 'projectProp2',
|
key: 'consignType',
|
||||||
col: { span: 12 },
|
col: { span: 24 },
|
||||||
component: {
|
component: {
|
||||||
name: 'fs-dict-select',
|
name: 'fs-dict-radio',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
class: 'w-[200px]',
|
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: getDictOptions(DICT_TYPE.contract_authorization_type),
|
data: getDictOptions(DICT_TYPE.contract_authorization_type),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
valueChange: {
|
||||||
|
immediate: true, // 是否立即执行一次
|
||||||
|
handle({ form }) {
|
||||||
|
form.consignTypeName = getDictObj(
|
||||||
|
DICT_TYPE.contract_authorization_type,
|
||||||
|
form.consignType,
|
||||||
|
)?.label;
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
projectNum5: {
|
projectNum5: {
|
||||||
title: '受托人',
|
title: '受托人',
|
||||||
|
@ -142,9 +177,9 @@ export function getFormSchema(_params?: any): any {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isBid: {
|
isconsignDate: {
|
||||||
title: '授权期限',
|
title: '授权期限',
|
||||||
key: 'isBid',
|
key: 'isconsignDate',
|
||||||
col: { span: 24 },
|
col: { span: 24 },
|
||||||
render({ form }) {
|
render({ form }) {
|
||||||
// 注意此处的v-model写法
|
// 注意此处的v-model写法
|
||||||
|
@ -156,21 +191,48 @@ export function getFormSchema(_params?: any): any {
|
||||||
return (
|
return (
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<a-form-item class="!mb-0 inline-block">
|
<a-form-item class="!mb-0 inline-block">
|
||||||
<a-radio-group options={options1} v-model:value={form.isBid} />
|
<a-radio-group
|
||||||
|
options={options1}
|
||||||
|
v-model:value={form.isconsignDate}
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<div class="w-2"></div>
|
<div class="w-2"></div>
|
||||||
{form.isBid === 1 && (
|
{form.isconsignDate === '0' && (
|
||||||
|
<div class="flex">
|
||||||
|
<a-form-item class="!mb-0 inline-block">
|
||||||
|
<a-date-picker
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
onChange={handleUpdateFormattedValue}
|
||||||
|
placeholder=""
|
||||||
|
v-model:value={form.consignDateBegin}
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<span class="mx-1">至</span>
|
||||||
|
<a-form-item class="!mb-0 inline-block">
|
||||||
|
<a-date-picker
|
||||||
|
disabledDate={disabledDate}
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
onChange={handleUpdateFormattedValue}
|
||||||
|
placeholder=""
|
||||||
|
v-model:value={form.consignDateEnd}
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{form.isconsignDate === '1' && (
|
||||||
<a-form-item class="!mb-0 inline-block" label="">
|
<a-form-item class="!mb-0 inline-block" label="">
|
||||||
<a-input v-model:value={form.budgetSum2} />
|
<a-input v-model:value={form.consignDescribe} />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
remark: {
|
remarks: {
|
||||||
title: '备注',
|
title: '备注',
|
||||||
key: 'remark',
|
key: 'remarks',
|
||||||
col: { span: 24 },
|
col: { span: 24 },
|
||||||
component: {
|
component: {
|
||||||
name: 'a-textarea',
|
name: 'a-textarea',
|
||||||
|
@ -199,6 +261,8 @@ export function getFormSchemaByAuthRange(params?: any): any {
|
||||||
const { contractTypeData, readOnly = false } = params || {};
|
const { contractTypeData, readOnly = false } = params || {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
col: { span: 24 },
|
||||||
|
labelCol: { style: { width: '120px' } },
|
||||||
initialForm: {
|
initialForm: {
|
||||||
priceType: 'CNY',
|
priceType: 'CNY',
|
||||||
},
|
},
|
||||||
|
@ -218,7 +282,7 @@ export function getFormSchemaByAuthRange(params?: any): any {
|
||||||
component: {
|
component: {
|
||||||
name: 'fs-dict-select',
|
name: 'fs-dict-select',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
class: 'min-w-[200px]',
|
class: 'min-w-[180px]',
|
||||||
prototype: true,
|
prototype: true,
|
||||||
dict: dict({
|
dict: dict({
|
||||||
async getData(_context) {
|
async getData(_context) {
|
||||||
|
@ -255,7 +319,7 @@ export function getFormSchemaByAuthRange(params?: any): any {
|
||||||
component: {
|
component: {
|
||||||
name: 'fs-dict-select',
|
name: 'fs-dict-select',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
class: 'min-w-[200px]',
|
class: 'min-w-[180px]',
|
||||||
prototype: true,
|
prototype: true,
|
||||||
dict: dict({
|
dict: dict({
|
||||||
async getData({ form = {} }) {
|
async getData({ form = {} }) {
|
||||||
|
@ -288,14 +352,14 @@ export function getFormSchemaByAuthRange(params?: any): any {
|
||||||
<a-form-item class="!mb-0 inline-block">
|
<a-form-item class="!mb-0 inline-block">
|
||||||
<a-input-number
|
<a-input-number
|
||||||
placeholder=""
|
placeholder=""
|
||||||
v-model:value={form.budgetSum1}
|
v-model:value={form.contractMoneyDown}
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<span class="mx-1">至</span>
|
<span class="mx-1">至</span>
|
||||||
<a-form-item class="!mb-0 inline-block">
|
<a-form-item class="!mb-0 inline-block">
|
||||||
<a-input-number
|
<a-input-number
|
||||||
placeholder=""
|
placeholder=""
|
||||||
v-model:value={form.budgetSum2}
|
v-model:value={form.contractMoneyUp}
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<span class="mx-1"></span>
|
<span class="mx-1"></span>
|
||||||
|
|
|
@ -32,11 +32,17 @@ const formRef = ref();
|
||||||
const formRefByAuthRange = ref();
|
const formRefByAuthRange = ref();
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
const currData = ref<any>({});
|
||||||
|
const nodeInfo = ref<any>({});
|
||||||
|
|
||||||
const contractTypeData = ref([]);
|
const contractTypeData = ref<any>([]);
|
||||||
|
|
||||||
const formBinding = ref({
|
const formBinding = ref({
|
||||||
...(({ columns: _, ...rest }) => rest)(getFormSchema()),
|
...(({ columns: _, ...rest }) => rest)(
|
||||||
|
getFormSchema({
|
||||||
|
formRef,
|
||||||
|
}),
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
const formBindingByAuthRange = ref({
|
const formBindingByAuthRange = ref({
|
||||||
|
@ -81,6 +87,133 @@ function handleFold() {
|
||||||
collapseActiveKey.value = isFold.value ? collapses : [];
|
collapseActiveKey.value = isFold.value ? collapses : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleDelete() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '是否确认删除该条记录?',
|
||||||
|
okType: 'danger',
|
||||||
|
onOk: async () => {
|
||||||
|
await Apis.ccsq.post_deletes({
|
||||||
|
params: { ids: id.value },
|
||||||
|
});
|
||||||
|
message.success('删除成功');
|
||||||
|
back();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSave() {
|
||||||
|
const form = formRef.value.form;
|
||||||
|
const formByAuthRange = formRefByAuthRange.value.form;
|
||||||
|
|
||||||
|
console.log('提交表单', form, formBindingByAuthRange);
|
||||||
|
try {
|
||||||
|
await formRef.value.submit();
|
||||||
|
await formRefByAuthRange.value.submit();
|
||||||
|
} catch {
|
||||||
|
message.error('请完成必填项的填写');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合同附件
|
||||||
|
{
|
||||||
|
const tempFileList = form.fileList;
|
||||||
|
let tempFiles: any = [];
|
||||||
|
if (fileList.value && tempFileList && tempFileList.length > 0) {
|
||||||
|
tempFiles = await fileUploader.upload(tempFileList, { source: 'ht' });
|
||||||
|
}
|
||||||
|
if (tempFiles) {
|
||||||
|
form.fileUuid = (tempFiles.map((item) => item.fileUuid) || []).join(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取字典数据的name值
|
||||||
|
for (const item of contractTypeData.value) {
|
||||||
|
if (item.contrLevelId === form.ctrType) {
|
||||||
|
form.ctrTypeName = item.contrLevelName;
|
||||||
|
}
|
||||||
|
if (item.contrLevelId === form.ctrTwoType) {
|
||||||
|
form.ctrTwoTypeName = item.contrLevelName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const newForm = {
|
||||||
|
RlHtSqConsignPt: {
|
||||||
|
entrustUserId: 'xiong',
|
||||||
|
entrustUserName: form.entrustUserName,
|
||||||
|
lawUserId: form.lawUserName,
|
||||||
|
lawUserName: form.lawUserName,
|
||||||
|
unitName: '热力公司',
|
||||||
|
unitId: '0',
|
||||||
|
remarks: form.remarks,
|
||||||
|
positionId: '01',
|
||||||
|
positionName: form.positionName,
|
||||||
|
consignType: form.consignType,
|
||||||
|
consignDateBegin: form.consignDateBegin,
|
||||||
|
consignDateEnd: form.consignDateEnd,
|
||||||
|
consignDescribe: form.consignDescribe,
|
||||||
|
},
|
||||||
|
RlHtSqConsignUser: {
|
||||||
|
consignUserId: 'xiong',
|
||||||
|
userId: 'liu01',
|
||||||
|
userName: '柳柳',
|
||||||
|
userPerson: '柳柳',
|
||||||
|
unitId: '24352234',
|
||||||
|
unitName: '一分公司机关楼高压电缆更换。',
|
||||||
|
departId: '其他',
|
||||||
|
departName: '8',
|
||||||
|
positionTypeId: null,
|
||||||
|
positionTypeName: '1',
|
||||||
|
identityCardId: '657665462381112901',
|
||||||
|
status: '1',
|
||||||
|
remarks: '1',
|
||||||
|
},
|
||||||
|
RlHtSqConsignCqtype: {
|
||||||
|
consignCqtypeId: '3452345',
|
||||||
|
contractOneTypeId: form.ctrType,
|
||||||
|
contractOneTypeName: form.ctrTypeName,
|
||||||
|
contractTwoTypeId: form.ctrTwoType,
|
||||||
|
contractTwoTypeName: form.ctrTwoTypeName,
|
||||||
|
// inputDepartId: '2024',
|
||||||
|
// inputDepartName: 'xxxx',
|
||||||
|
// remark: '',
|
||||||
|
contractMoneyDown: form.contractMoneyDown,
|
||||||
|
contractMoneyUp: form.contractMoneyUp,
|
||||||
|
priceTypeId: form.priceType,
|
||||||
|
priceTypeName: getDictObj(
|
||||||
|
DICT_TYPE.contract_currency_unit,
|
||||||
|
form.priceType,
|
||||||
|
)?.label,
|
||||||
|
},
|
||||||
|
RlHtSqConsignDxtype: {
|
||||||
|
consignCqtypeId: '',
|
||||||
|
consignId: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(newForm);
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
await Apis.qdSign.post_save({
|
||||||
|
data: newForm,
|
||||||
|
});
|
||||||
|
|
||||||
|
message.success('保存成功');
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '保存成功!是否进行提交?',
|
||||||
|
onOk: () => {
|
||||||
|
handleSubmit();
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
back();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
message.error('保存失败,请稍候再试');
|
||||||
|
logger.error('签约申报报错失败', error);
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
|
|
||||||
|
@ -95,20 +228,6 @@ async function handleSubmit() {
|
||||||
|
|
||||||
const form = formRef.value.form;
|
const form = formRef.value.form;
|
||||||
|
|
||||||
// 合同附件
|
|
||||||
{
|
|
||||||
const tempFileList = form.fileList;
|
|
||||||
let tempFiles: any = [];
|
|
||||||
if (fileList.value && tempFileList.length > 0) {
|
|
||||||
tempFiles = await fileUploader.upload(tempFileList, { source: 'ht' });
|
|
||||||
}
|
|
||||||
if (tempFiles) {
|
|
||||||
form.fileUuid = (tempFiles.map((item) => item.fileUuid) || []).join(
|
|
||||||
',',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('提交表单', form);
|
console.log('提交表单', form);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -178,7 +297,9 @@ async function handleSubmit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
formBinding.value.columns = getFormSchema().columns;
|
formBinding.value.columns = getFormSchema({
|
||||||
|
formRef,
|
||||||
|
}).columns;
|
||||||
|
|
||||||
const contractReferTypeData: any = await Apis.contractReferType.get_list({
|
const contractReferTypeData: any = await Apis.contractReferType.get_list({
|
||||||
params: {},
|
params: {},
|
||||||
|
@ -254,9 +375,28 @@ onMounted(async () => {
|
||||||
>
|
>
|
||||||
<div class="flex w-full flex-row bg-white pl-1 pt-1">
|
<div class="flex w-full flex-row bg-white pl-1 pt-1">
|
||||||
<a-space class="flex-1">
|
<a-space class="flex-1">
|
||||||
<vben-button variant="primary" @click="handleSubmit()">
|
<vben-button
|
||||||
|
v-if="!id || ['填报'].includes(currData.status)"
|
||||||
|
variant="primary"
|
||||||
|
@click="handleSave()"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</vben-button>
|
||||||
|
<vben-button
|
||||||
|
v-if="!id || ['填报'].includes(currData.status)"
|
||||||
|
:disabled="!id"
|
||||||
|
variant="primary"
|
||||||
|
@click="handleSubmit()"
|
||||||
|
>
|
||||||
提交
|
提交
|
||||||
</vben-button>
|
</vben-button>
|
||||||
|
<vben-button
|
||||||
|
v-if="!isLoading && id && ['填报'].includes(currData.status)"
|
||||||
|
variant="destructive"
|
||||||
|
@click="handleDelete()"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</vben-button>
|
||||||
<vben-button variant="secondary" @click="handleBack()">
|
<vben-button variant="secondary" @click="handleBack()">
|
||||||
返回
|
返回
|
||||||
</vben-button>
|
</vben-button>
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import type { VxeGridPropTypes } from 'vxe-table';
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
|
|
||||||
export const PrimaryKey = 'guid';
|
export const PrimaryKey = 'guid';
|
||||||
|
|
||||||
export function getColumns(_params?: any): VxeGridPropTypes.Columns {
|
export function getColumns(_params?: any): VxeGridPropTypes.Columns {
|
||||||
|
@ -15,7 +13,7 @@ export function getColumns(_params?: any): VxeGridPropTypes.Columns {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '签约授权编号',
|
title: '签约授权编号',
|
||||||
field: 'authorizationCode',
|
field: 'consignId',
|
||||||
width: 200,
|
width: 200,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
|
@ -44,19 +42,19 @@ export function getColumns(_params?: any): VxeGridPropTypes.Columns {
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
field: 'operate',
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 80,
|
width: 60,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
|
slots: { default: 'operate' },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFormSchema(_params: any = {}) {
|
export function getFormSchema(_params: any = {}) {
|
||||||
return {
|
return {
|
||||||
initialForm: {
|
initialForm: {},
|
||||||
startDate: dayjs().startOf('month').format('YYYY-MM-DD'),
|
|
||||||
},
|
|
||||||
columns: {
|
columns: {
|
||||||
contractName: {
|
contractName: {
|
||||||
title: '受托人姓名',
|
title: '受托人姓名',
|
||||||
|
|
|
@ -33,7 +33,7 @@ const gridOptions = reactive(
|
||||||
autoLoad: false,
|
autoLoad: false,
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }) => {
|
query: async ({ page }) => {
|
||||||
const data = await Apis.contractBaseInfo.get_page({
|
const data = await Apis.sqConsignPt.get_SigningaAuthorizationSerch({
|
||||||
params: {
|
params: {
|
||||||
pageNum: page.currentPage,
|
pageNum: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
|
@ -67,7 +67,7 @@ function handleDelete(row) {
|
||||||
content: '是否确认删除该条记录?',
|
content: '是否确认删除该条记录?',
|
||||||
okType: 'danger',
|
okType: 'danger',
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
await Apis.contractBaseInfo.post_deletes({
|
await Apis.sqConsignPt.post_deletes({
|
||||||
params: { ids: row[PrimaryKey] },
|
params: { ids: row[PrimaryKey] },
|
||||||
});
|
});
|
||||||
message.success('删除成功');
|
message.success('删除成功');
|
||||||
|
@ -166,7 +166,12 @@ function toDetailPage(_row) {}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #operate="{ row }">
|
<template #operate="{ row }">
|
||||||
<a-button size="small" type="primary" @click="toDetailPage(row)">
|
<a-button
|
||||||
|
class="text-primary"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="toDetailPage(row)"
|
||||||
|
>
|
||||||
查看
|
查看
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
import type { Component } from 'vue';
|
||||||
|
|
||||||
|
interface AnalysisOverviewItem {
|
||||||
|
icon: Component | string;
|
||||||
|
title: string;
|
||||||
|
totalTitle: string;
|
||||||
|
totalValue: number;
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkbenchProjectItem {
|
||||||
|
color?: string;
|
||||||
|
content: string;
|
||||||
|
date: string;
|
||||||
|
group: string;
|
||||||
|
icon: Component | string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkbenchTrendItem {
|
||||||
|
avatar: string;
|
||||||
|
content: string;
|
||||||
|
date: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkbenchTodoItem {
|
||||||
|
completed: boolean;
|
||||||
|
content: string;
|
||||||
|
date: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkbenchQuickNavItem {
|
||||||
|
color?: string;
|
||||||
|
icon: Component | string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type {
|
||||||
|
AnalysisOverviewItem,
|
||||||
|
WorkbenchProjectItem,
|
||||||
|
WorkbenchQuickNavItem,
|
||||||
|
WorkbenchTodoItem,
|
||||||
|
WorkbenchTrendItem,
|
||||||
|
};
|
|
@ -0,0 +1,74 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { WorkbenchTodoItem } from './typing';
|
||||||
|
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
VbenButton,
|
||||||
|
} from '@vben-core/shadcn-ui';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'WorkbenchTodo',
|
||||||
|
});
|
||||||
|
|
||||||
|
withDefaults(defineProps<Props>(), {
|
||||||
|
items: () => [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
items: WorkbenchTodoItem[];
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleViewAll() {
|
||||||
|
router.push('/user/todo');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Card>
|
||||||
|
<CardHeader class="py-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<CardTitle class="text-lg">{{ title }}</CardTitle>
|
||||||
|
|
||||||
|
<VbenButton size="sm" @click="handleViewAll"> 查看所有待办 </VbenButton>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent class="flex h-[60vh] flex-wrap overflow-auto p-5 pt-0">
|
||||||
|
<ul class="divide-border w-full divide-y" role="list">
|
||||||
|
<li
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item.title"
|
||||||
|
:class="{
|
||||||
|
'select-none line-through opacity-60': item.completed,
|
||||||
|
}"
|
||||||
|
class="flex cursor-pointer justify-between gap-x-6 px-4 py-2"
|
||||||
|
>
|
||||||
|
<div class="flex min-w-0 items-center gap-x-4">
|
||||||
|
<div class="min-w-0 flex-auto">
|
||||||
|
<p class="text-foreground text-sm font-semibold leading-6">
|
||||||
|
{{ item.module }} {{ item.title }}
|
||||||
|
</p>
|
||||||
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
|
<p
|
||||||
|
class="text-foreground/80 *:text-primary mt-1 truncate text-xs leading-5"
|
||||||
|
v-html="item.message"
|
||||||
|
></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hidden h-full shrink-0 sm:flex sm:flex-col sm:items-end">
|
||||||
|
<span class="text-foreground/80 mt-6 text-xs leading-6">
|
||||||
|
{{ item.date }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</template>
|
|
@ -1,13 +1,17 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted } from "vue";
|
import type { WorkbenchTodoItem } from '../components/typing';
|
||||||
import { preferences } from "@vben/preferences";
|
|
||||||
import { useUserStore } from "@vben/stores";
|
|
||||||
|
|
||||||
import WorkbenchHeader from "../components/workbench-header.vue";
|
import { onMounted, ref } from 'vue';
|
||||||
import WorkbenchQuickNav from "../components/workbench-quick-nav.vue";
|
import { useRouter } from 'vue-router';
|
||||||
import { useAccessStore } from "@vben/stores";
|
|
||||||
import { useRouter } from "vue-router";
|
import { preferences } from '@vben/preferences';
|
||||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from "@vben/constants";
|
import { useUserStore } from '@vben/stores';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { DICT_TYPE, getDictObj } from '#/utils/dict';
|
||||||
|
|
||||||
|
import WorkbenchHeader from '../components/workbench-header.vue';
|
||||||
|
import WorkbenchTodo from '../components/workbench-todo.vue';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -22,11 +26,11 @@ const quickNavItems: WorkbenchQuickNavItem[] = [
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
color: "#bf0c2c",
|
color: '#bf0c2c',
|
||||||
icon: "ion:grid-outline",
|
icon: 'ion:grid-outline',
|
||||||
title: "订餐",
|
title: '订餐',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
router.push("/canteen/orderfood");
|
router.push('/canteen/orderfood');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
|
@ -55,9 +59,31 @@ const quickNavItems: WorkbenchQuickNavItem[] = [
|
||||||
// },
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
onMounted(() => {
|
const todoItems = ref<WorkbenchTodoItem[]>([]);
|
||||||
const accessStore = useAccessStore();
|
|
||||||
console.log(accessStore.accessMenus);
|
onMounted(async () => {
|
||||||
|
const data = await Apis.home.get_todo({
|
||||||
|
params: { pageNum: 1, pageSize: 20 },
|
||||||
|
});
|
||||||
|
|
||||||
|
todoItems.value = data.rows.map((item) => {
|
||||||
|
let module =
|
||||||
|
getDictObj(DICT_TYPE.contract_todo_type, item.module)?.label || '';
|
||||||
|
|
||||||
|
if (module) {
|
||||||
|
module = `[${module}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
module,
|
||||||
|
avatar: '',
|
||||||
|
date: item.createTime,
|
||||||
|
isRead: true,
|
||||||
|
message: item.contractName,
|
||||||
|
title: item.taskName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// resetAllStores();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -75,5 +101,7 @@ onMounted(() => {
|
||||||
<div class="mt-5 flex flex-col lg:flex-row">
|
<div class="mt-5 flex flex-col lg:flex-row">
|
||||||
<!-- <WorkbenchQuickNav :items="quickNavItems" title="快捷导航" /> -->
|
<!-- <WorkbenchQuickNav :items="quickNavItems" title="快捷导航" /> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,22 +1,166 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
||||||
|
import { getTodoColumns } from '#/views/contract/schema';
|
||||||
|
|
||||||
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
const { xGridRef: xGrid2Ref, triggerProxy: triggerProxy2 } = useVxeTable({
|
||||||
|
ref: 'xGrid2Ref',
|
||||||
|
});
|
||||||
|
const treeData = ref();
|
||||||
|
|
||||||
|
const selectedKeys = ref<string[]>([]);
|
||||||
|
|
||||||
|
/** Hooks - 表格 */
|
||||||
|
const gridOptions = reactive(
|
||||||
|
gridProps({
|
||||||
|
columns: getTodoColumns(),
|
||||||
|
proxyConfig: {
|
||||||
|
autoLoad: true,
|
||||||
|
ajax: {
|
||||||
|
query: ({ page }) => {
|
||||||
|
return Apis.home.get_todo({
|
||||||
|
params: {
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
moduleId: selectedKeys.value[0],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Hooks - 表格 */
|
||||||
|
const grid2Options = reactive(
|
||||||
|
gridProps({
|
||||||
|
columns: getTodoColumns(),
|
||||||
|
proxyConfig: {
|
||||||
|
autoLoad: true,
|
||||||
|
ajax: {
|
||||||
|
query: ({ page }) => {
|
||||||
|
return Apis.home.get_done({
|
||||||
|
params: {
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
moduleId: selectedKeys.value[0],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
function onTreeSelect() {
|
||||||
|
triggerProxy('reload');
|
||||||
|
triggerProxy2('reload');
|
||||||
|
}
|
||||||
|
|
||||||
|
const expandedKeys = ref<string[]>([]);
|
||||||
|
|
||||||
|
async function loadDataByDictType() {
|
||||||
|
const data = getDictOptions(DICT_TYPE.contract_todo_type);
|
||||||
|
|
||||||
|
data.forEach((item) => {
|
||||||
|
item.key = item.value;
|
||||||
|
item.title = item.label;
|
||||||
|
});
|
||||||
|
expandedKeys.value = ['all'];
|
||||||
|
|
||||||
|
treeData.value = [{ title: '全部', key: 'all', children: data }];
|
||||||
|
}
|
||||||
|
|
||||||
|
function toDetail(row) {}
|
||||||
|
|
||||||
|
function toDetailPage(row) {}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadDataByDictType();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page contentClass="h-full">
|
<Page content-class="h-full">
|
||||||
<a-row class="h-full" :gutter="[8, 8]">
|
<a-row :gutter="[8, 8]" class="h-full">
|
||||||
<a-col :span="5" class="min-w-[200px]">
|
<a-col :span="5" class="min-w-[200px]">
|
||||||
<a-card title="事项类型" size="small" contentClass="">
|
<a-card content-class="" size="small" title="事项类型">
|
||||||
<div class="min-h-[500px]">
|
<div class="min-h-[500px]">
|
||||||
<a-tree class="draggable-tree" block-node :tree-data="treeData" />
|
<a-tree
|
||||||
|
v-model:expanded-keys="expandedKeys"
|
||||||
|
v-model:selected-keys="selectedKeys"
|
||||||
|
:tree-data="treeData"
|
||||||
|
block-node
|
||||||
|
class="draggable-tree"
|
||||||
|
@select="onTreeSelect"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="19" class="flex flex-col min-w-700px">
|
<a-col :span="19" class="min-w-700px flex flex-col">
|
||||||
<a-card title="待办" size="small" class=" flex-1">
|
<a-card
|
||||||
<vxe-grid ref="xGridRef" v-bind="gridOptions" class=" flex-1">
|
:body-style="{ flex: '1' }"
|
||||||
|
class="flex h-full flex-col"
|
||||||
|
size="small"
|
||||||
|
title="待办"
|
||||||
|
>
|
||||||
|
<vxe-grid ref="xGridRef" v-bind="gridOptions" class="flex-1">
|
||||||
<template #toolbar_buttons> </template>
|
<template #toolbar_buttons> </template>
|
||||||
|
<template #title_slot="{ row }">
|
||||||
|
<span
|
||||||
|
class="cursor-pointer text-blue-500 hover:underline"
|
||||||
|
@click="toDetail(row)"
|
||||||
|
>
|
||||||
|
{{ row.contractName }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #operate="{ row }">
|
||||||
|
<a-button
|
||||||
|
class="text-blue-500"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="toDetailPage(row)"
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card title="已办" size="small" class=" flex-1 mt-[8px]">
|
<a-card
|
||||||
<vxe-grid ref="xGridRef" v-bind="gridOptions" class=" flex-1">
|
:body-style="{ flex: '1' }"
|
||||||
|
class="flex h-full flex-col"
|
||||||
|
size="small"
|
||||||
|
title="已办"
|
||||||
|
>
|
||||||
|
<vxe-grid ref="xGridRef" v-bind="grid2Options" class="flex-1">
|
||||||
<template #toolbar_buttons> </template>
|
<template #toolbar_buttons> </template>
|
||||||
|
<template #operate="{ row }">
|
||||||
|
<a-button
|
||||||
|
class="text-blue-500"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="toDetailPage(row)"
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -24,201 +168,8 @@
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<style scoped>
|
||||||
import { defineComponent, ref, reactive, onMounted } from 'vue';
|
:deep(.ant-space-item) {
|
||||||
import { FsCrud } from '@fast-crud/fast-crud';
|
flex: 1;
|
||||||
import { type VxeGridProps } from 'vxe-table'
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
|
||||||
import {
|
|
||||||
type CreateCrudOptionsProps,
|
|
||||||
useColumns,
|
|
||||||
useFormWrapper,
|
|
||||||
useFs,
|
|
||||||
utils,
|
|
||||||
} from '@fast-crud/fast-crud';
|
|
||||||
import { MdiAdd, MdiUpdate, MdiDelete } from '@vben/icons';
|
|
||||||
import { dict } from "@fast-crud/fast-crud";
|
|
||||||
|
|
||||||
import Apis from '#/api'
|
|
||||||
|
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
|
||||||
|
|
||||||
const treeData = ref([]);
|
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
|
||||||
const gridOptions = reactive(gridProps({
|
|
||||||
columns: [
|
|
||||||
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
|
||||||
{ field: 'contractId', title: '编号', width: 100 },
|
|
||||||
{
|
|
||||||
field: 'title', title: '名称', minWidth: 200, slots: {
|
|
||||||
default: ({ row }) => {
|
|
||||||
// let text = row.title
|
|
||||||
// if (text) {
|
|
||||||
// let classArr: string[] = ["line-clamp-3"];
|
|
||||||
// return h(
|
|
||||||
// NTooltip,
|
|
||||||
// { trigger: 'hover' },
|
|
||||||
// {
|
|
||||||
// trigger: () => h('span', { class: classArr.join(' ') }, text),
|
|
||||||
// default: () => text
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ field: 'contractAmount', title: '模块', width: 150 },
|
|
||||||
{ field: 'contractSubject', title: '任务', width: 200 },
|
|
||||||
{ field: 'contractCounterparty', title: '分配时间', width: 150 },
|
|
||||||
{ field: 'cumulativeSettlementAmount', title: '承办单位/部门', width: 150 },
|
|
||||||
{ field: 'changeCount', title: '承办人', width: 100 },
|
|
||||||
{ field: 'contractStatus', title: '交接给', width: 100 }
|
|
||||||
],
|
|
||||||
proxyConfig: {
|
|
||||||
autoLoad: false,
|
|
||||||
ajax: {
|
|
||||||
query: ({ page }) => {
|
|
||||||
return Apis.dictData.get_page({ params: { pageNum: page.currentPage, pageSize: page.pageSize, ...searchParams } })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pagerConfig: {
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
toolbarConfig: {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 转换树行数据的方法
|
|
||||||
function transTree(list) {
|
|
||||||
// 最终生成的树行结构
|
|
||||||
const _treeData = [];
|
|
||||||
|
|
||||||
// 对传入进来的 数据进行遍历,查找对应的子级
|
|
||||||
list.forEach((item) => {
|
|
||||||
// 给每一项添加子节点
|
|
||||||
// item.children = []
|
|
||||||
item.key = item.code;
|
|
||||||
item.title = item.name;
|
|
||||||
// 如果 pid 为空,说明是最顶级,直接放到 _treeData 中即可
|
|
||||||
if (!item.parentId || item.parentId == 0) {
|
|
||||||
_treeData.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据前面的分析,pid 代表的是父级的 id,从而可以进行筛选子级
|
|
||||||
// filter 方法会把满足条件到的每一项,组成一个数组进行返回
|
|
||||||
const children = list.filter((data) => data.parentId === item.id);
|
|
||||||
|
|
||||||
// 如果没有子节点,直接 return 不做任何处理
|
|
||||||
if (!children.length) return;
|
|
||||||
|
|
||||||
// 将返回的子级进行赋值给父级(item)的 children 属性
|
|
||||||
item.children = children;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 将最终生成的数据返回出去
|
|
||||||
return _treeData;
|
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
let DictTypeData = ref([])
|
|
||||||
|
|
||||||
async function loadDataByDictType() {
|
|
||||||
// try {
|
|
||||||
// let data = await Apis.dictType.get_list();
|
|
||||||
// console.log(data);
|
|
||||||
|
|
||||||
// treeData.value = transTree(data.rows)
|
|
||||||
// console.log(treeData.value);
|
|
||||||
|
|
||||||
// } catch (error) {
|
|
||||||
// console.log(error)
|
|
||||||
// } finally {
|
|
||||||
// triggerProxy('reload')
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
loadDataByDictType()
|
|
||||||
})
|
|
||||||
|
|
||||||
let searchParams = reactive({})
|
|
||||||
const searchForm = ref({
|
|
||||||
columns: {
|
|
||||||
tree: {
|
|
||||||
title: "树形选择",
|
|
||||||
|
|
||||||
show: true,
|
|
||||||
|
|
||||||
valueChange({ getComponentRef }) {
|
|
||||||
const compRef = getComponentRef("tree");
|
|
||||||
console.log("tree ref:", compRef, compRef.$refs.treeRef);
|
|
||||||
},
|
|
||||||
component: {
|
|
||||||
name: "fs-dict-tree",
|
|
||||||
dict: dict({
|
|
||||||
isTree: true,
|
|
||||||
async getData(dict, context) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
on: {
|
|
||||||
selectedChange({ form, $event }) {
|
|
||||||
// $event就是原始的事件值,也就是选中的 option对象
|
|
||||||
// utils.logger.info("onSelectedChange", form, $event);
|
|
||||||
// ui.message.info(`你选择了${JSON.stringify($event.label)}`);
|
|
||||||
// 你还可以将选中的label值赋值给表单里其他字段
|
|
||||||
// context.form.xxxLabel = context.$event.label
|
|
||||||
}
|
|
||||||
},
|
|
||||||
slots: {
|
|
||||||
title({ scope }) {
|
|
||||||
//自定义选项text
|
|
||||||
return `${scope.label}(${scope.value})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
component: {
|
|
||||||
name: 'a-input',
|
|
||||||
vModel: 'value',
|
|
||||||
allowClear: true,
|
|
||||||
props: {
|
|
||||||
type: 'text',
|
|
||||||
showWordLimit: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
title: '字典标签',
|
|
||||||
key: 'type',
|
|
||||||
autoSearchTrigger: 'enter',
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
age: {
|
|
||||||
component: {
|
|
||||||
name: 'a-input',
|
|
||||||
vModel: 'value',
|
|
||||||
allowClear: true,
|
|
||||||
},
|
|
||||||
title: '字典键值',
|
|
||||||
key: 'value',
|
|
||||||
autoSearchTrigger: 'enter',
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
onSearch(context: any) {
|
|
||||||
searchParams = context.form
|
|
||||||
triggerProxy('reload')
|
|
||||||
},
|
|
||||||
onReset(context: any) {
|
|
||||||
searchParams = context.form
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// 页面打开后获取列表数据
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ export function transferResponse(response: any) {
|
||||||
code = 0;
|
code = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == 'failure' || (msg && msg.includes('token无效'))) {
|
if (code == 'failure' && msg && msg.includes('token无效')) {
|
||||||
code = 401;
|
code = 401;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
import { merge } from "lodash-es";
|
import { ref } from 'vue';
|
||||||
import { ref } from "vue";
|
|
||||||
import { type VxeGridInstance, type VxeGridProps } from "vxe-table";
|
|
||||||
|
|
||||||
export function useVxeTable(props: {
|
|
||||||
ref: string,
|
|
||||||
}) {
|
|
||||||
|
|
||||||
|
import { merge } from 'lodash-es';
|
||||||
|
import { type VxeGridInstance, type VxeGridProps } from 'vxe-table';
|
||||||
|
|
||||||
|
export function useVxeTable(props: { ref: string }) {
|
||||||
const xGridRef = ref<VxeGridInstance<any>>();
|
const xGridRef = ref<VxeGridInstance<any>>();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -19,10 +16,10 @@ export function useVxeTable(props: {
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
border: true,
|
border: true,
|
||||||
editConfig: {
|
editConfig: {
|
||||||
mode: 'row'
|
mode: 'row',
|
||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
isCurrent: true
|
isCurrent: true,
|
||||||
},
|
},
|
||||||
// 斑马条纹
|
// 斑马条纹
|
||||||
stripe: false,
|
stripe: false,
|
||||||
|
@ -30,7 +27,7 @@ export function useVxeTable(props: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
size: 'mini',
|
size: 'mini',
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
autoHidden: false
|
autoHidden: false,
|
||||||
},
|
},
|
||||||
// 列设置
|
// 列设置
|
||||||
columnConfig: {
|
columnConfig: {
|
||||||
|
@ -38,7 +35,7 @@ export function useVxeTable(props: {
|
||||||
isCurrent: false,
|
isCurrent: false,
|
||||||
isHover: false,
|
isHover: false,
|
||||||
// 取消列宽拖动功能
|
// 取消列宽拖动功能
|
||||||
resizable: false
|
resizable: false,
|
||||||
},
|
},
|
||||||
toolbarConfig: {
|
toolbarConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -48,11 +45,11 @@ export function useVxeTable(props: {
|
||||||
custom: true,
|
custom: true,
|
||||||
refresh: true,
|
refresh: true,
|
||||||
slots: {
|
slots: {
|
||||||
buttons: 'toolbar_buttons'
|
buttons: 'toolbar_buttons',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
headerAlign: 'left',
|
headerAlign: 'left',
|
||||||
align: 'left'
|
align: 'left',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 如果mergedProps.proxyConfig是空对象,则删除该字段,不然 vxetable 可能会误判断
|
// 如果mergedProps.proxyConfig是空对象,则删除该字段,不然 vxetable 可能会误判断
|
||||||
|
@ -61,8 +58,8 @@ export function useVxeTable(props: {
|
||||||
props: {
|
props: {
|
||||||
list: 'rows',
|
list: 'rows',
|
||||||
result: 'rows',
|
result: 'rows',
|
||||||
total: 'total'
|
total: 'total',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +71,6 @@ export function useVxeTable(props: {
|
||||||
if ($grid) {
|
if ($grid) {
|
||||||
$grid.commitProxy(code);
|
$grid.commitProxy(code);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, reactive, ref } from 'vue';
|
import { computed, onMounted, reactive, ref } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
|
||||||
import { MdiRadioChecked, MdiRadioUnchecked } from '@vben/icons';
|
import { MdiRadioChecked, MdiRadioUnchecked } from '@vben/icons';
|
||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import Apis from '#/api';
|
import Apis from '#/api';
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
import { getMonthStartAndEnd } from '#/utils/time';
|
|
||||||
|
|
||||||
import { getColumns } from './crud.tsx';
|
import { getColumns } from './crud.tsx';
|
||||||
|
|
||||||
|
@ -17,7 +14,7 @@ const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
const currentDate = ref(dayjs());
|
const currentDate = ref(dayjs());
|
||||||
|
|
||||||
const currentMonth = computed(() => currentDate.value.format('YYYY年MM月'));
|
const currentMonth = computed(() => currentDate.value.format('YYYY年M月'));
|
||||||
|
|
||||||
const prevMonth = () => {
|
const prevMonth = () => {
|
||||||
currentDate.value = currentDate.value.subtract(1, 'month');
|
currentDate.value = currentDate.value.subtract(1, 'month');
|
||||||
|
@ -29,48 +26,6 @@ const nextMonth = () => {
|
||||||
triggerProxy('reload');
|
triggerProxy('reload');
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkedValue = ref('all');
|
|
||||||
const exportSearchParams = ref<any>({
|
|
||||||
daterange: getMonthStartAndEnd(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const searchRef = ref();
|
|
||||||
const isConfirmLoading = ref(false);
|
|
||||||
const [_Modal, modalApi] = useVbenModal({
|
|
||||||
async onConfirm() {
|
|
||||||
isConfirmLoading.value = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
let params = {};
|
|
||||||
if (checkedValue.value == 'daterange') {
|
|
||||||
params = {
|
|
||||||
startDate: exportSearchParams.value.daterange[0],
|
|
||||||
endDate: exportSearchParams.value.daterange[1],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const res = await Apis.zbgl
|
|
||||||
.post_export({
|
|
||||||
params,
|
|
||||||
config: {
|
|
||||||
meta: {
|
|
||||||
responseType: 'blob',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.send();
|
|
||||||
message.success('导出成功');
|
|
||||||
modalApi.close();
|
|
||||||
showExportModal.value = false;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
} finally {
|
|
||||||
isConfirmLoading.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.info('onConfirm');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const tableData = ref([]);
|
const tableData = ref([]);
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
|
@ -231,12 +186,12 @@ const gridOptions = reactive(
|
||||||
);
|
);
|
||||||
|
|
||||||
/** 选中数据 */
|
/** 选中数据 */
|
||||||
const selectRow: Recordable = computed(() => {
|
const selectRow: any = computed(() => {
|
||||||
return xGridRef.value?.getRadioRecord() || null;
|
return xGridRef.value?.getRadioRecord() || null;
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 单选框选中事件 */
|
/** 单选框选中事件 */
|
||||||
const setSelectRow = (row: Recordable) => {
|
const setSelectRow = (row: any) => {
|
||||||
if (selectRow.value && selectRow.value.guid === row.guid) {
|
if (selectRow.value && selectRow.value.guid === row.guid) {
|
||||||
xGridRef.value?.clearRadioRow();
|
xGridRef.value?.clearRadioRow();
|
||||||
} else {
|
} else {
|
||||||
|
@ -258,7 +213,7 @@ onMounted(() => {
|
||||||
<div class="mx-auto flex h-screen flex-col bg-gray-100 px-8">
|
<div class="mx-auto flex h-screen flex-col bg-gray-100 px-8">
|
||||||
<p class="my-6 text-center text-3xl font-bold text-gray-800">值班信息栏</p>
|
<p class="my-6 text-center text-3xl font-bold text-gray-800">值班信息栏</p>
|
||||||
|
|
||||||
<div class="mb-6 flex items-center justify-center h-4">
|
<div class="mb-6 flex h-4 items-center justify-center">
|
||||||
<!-- 增加按钮区域的高度 -->
|
<!-- 增加按钮区域的高度 -->
|
||||||
<button
|
<button
|
||||||
class="bg-primary hover:bg-primary/90 rounded-l-xl px-4 py-2 text-white"
|
class="bg-primary hover:bg-primary/90 rounded-l-xl px-4 py-2 text-white"
|
||||||
|
@ -275,12 +230,15 @@ onMounted(() => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-1 rounded-lg bg-white p-4 shadow-md overflow-auto" style="flex-grow: 2;">
|
<div
|
||||||
|
class="flex-1 overflow-auto rounded-lg bg-white p-4 shadow-md"
|
||||||
|
style="flex-grow: 2"
|
||||||
|
>
|
||||||
<vxe-grid
|
<vxe-grid
|
||||||
ref="xGridRef"
|
ref="xGridRef"
|
||||||
v-bind="gridOptions"
|
v-bind="gridOptions"
|
||||||
|
style="min-height: 40vh; max-height: 60vh"
|
||||||
@cell-click="handleCellClick"
|
@cell-click="handleCellClick"
|
||||||
style="min-height: 40vh; max-height: 60vh;"
|
|
||||||
>
|
>
|
||||||
<template #toolbar_buttons>
|
<template #toolbar_buttons>
|
||||||
<!-- 可添加工具栏按钮 -->
|
<!-- 可添加工具栏按钮 -->
|
||||||
|
@ -298,7 +256,7 @@ onMounted(() => {
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4" style="width: 100%; min-height: 120px;">
|
<div class="mt-4" style="width: 100%; min-height: 120px">
|
||||||
<p>
|
<p>
|
||||||
1.公司机关值班人员(包括值班司机)都必须严格遵守值班管理要求,值班期间保持值班电话畅通。
|
1.公司机关值班人员(包括值班司机)都必须严格遵守值班管理要求,值班期间保持值班电话畅通。
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import { useRender } from '#/hooks/useRender';
|
||||||
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
||||||
|
|
||||||
export const PrimaryKey = 'guid';
|
export const PrimaryKey = 'guid';
|
||||||
|
@ -61,7 +62,16 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: 'conferee', title: '参会人员', minWidth: 200 },
|
{
|
||||||
|
field: 'conferee',
|
||||||
|
title: '参会人员',
|
||||||
|
minWidth: 200,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return useRender.renderMultiLineText(row.conferee, { maxLine: 3 });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'otherEquipment',
|
field: 'otherEquipment',
|
||||||
title: '备注',
|
title: '备注',
|
||||||
|
@ -176,9 +186,7 @@ export function getFormSchema(_params: any = {}) {
|
||||||
class: 'min-w-[180px]',
|
class: 'min-w-[180px]',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: getDictOptions(DICT_TYPE.meeting_type).filter(
|
data: getDictOptions(DICT_TYPE.meeting_type),
|
||||||
(option) => option.value !== '生产会议',
|
|
||||||
),
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
autoSearchTrigger: 'enter',
|
autoSearchTrigger: 'enter',
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { useUserStore } from '@vben/stores';
|
||||||
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
import { message, Modal, type UploadChangeParam } from 'ant-design-vue';
|
import { message, Modal, type UploadChangeParam } from 'ant-design-vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
import Sortable from 'sortablejs';
|
import Sortable from 'sortablejs';
|
||||||
|
|
||||||
import Apis from '#/api';
|
import Apis from '#/api';
|
||||||
|
@ -71,7 +72,6 @@ const formBinding = ref({
|
||||||
return <span class="">{form.meetingTheme}</span>;
|
return <span class="">{form.meetingTheme}</span>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '请输入会议主题' }],
|
|
||||||
},
|
},
|
||||||
meetingType: {
|
meetingType: {
|
||||||
title: '会议类型',
|
title: '会议类型',
|
||||||
|
@ -97,7 +97,6 @@ const formBinding = ref({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '请选择会议类型' }],
|
|
||||||
},
|
},
|
||||||
isEmployeeRepresentatives: {
|
isEmployeeRepresentatives: {
|
||||||
title: '职工代表会',
|
title: '职工代表会',
|
||||||
|
@ -151,7 +150,6 @@ const formBinding = ref({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '请选择会议室' }],
|
|
||||||
},
|
},
|
||||||
meetingDate: {
|
meetingDate: {
|
||||||
title: '会议时间',
|
title: '会议时间',
|
||||||
|
@ -178,7 +176,6 @@ const formBinding = ref({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '请选择会议时间' }],
|
|
||||||
},
|
},
|
||||||
compere: {
|
compere: {
|
||||||
title: '主持人',
|
title: '主持人',
|
||||||
|
|
|
@ -2,11 +2,13 @@ import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import { useRender } from '#/hooks/useRender';
|
||||||
|
|
||||||
export const PrimaryKey = 'guid';
|
export const PrimaryKey = 'guid';
|
||||||
|
|
||||||
export function getColumns(_params?: any): VxeGridPropTypes.Columns {
|
export function getColumns(_params?: any): VxeGridPropTypes.Columns {
|
||||||
const columns: VxeGridPropTypes.Columns = [
|
const columns: VxeGridPropTypes.Columns = [
|
||||||
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
{ type: 'seq', width: 60, align: 'center', fixed: 'left' },
|
||||||
{
|
{
|
||||||
field: 'meetingDate',
|
field: 'meetingDate',
|
||||||
title: '会议时间',
|
title: '会议时间',
|
||||||
|
@ -33,8 +35,16 @@ export function getColumns(_params?: any): VxeGridPropTypes.Columns {
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{ field: 'compere', title: '主持人', width: 80 },
|
{ field: 'compere', title: '主持人', width: 80 },
|
||||||
{ field: 'conferee', title: '参会人员', minWidth: 200 },
|
{
|
||||||
|
field: 'conferee',
|
||||||
|
title: '参会人员',
|
||||||
|
minWidth: 200,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return useRender.renderMultiLineText(row.conferee, { maxLine: 3 });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{ field: 'meetingType', title: '会议类型', width: 120 },
|
{ field: 'meetingType', title: '会议类型', width: 120 },
|
||||||
{
|
{
|
||||||
field: 'otherEquipment',
|
field: 'otherEquipment',
|
||||||
|
|
|
@ -15,10 +15,10 @@ const searchRef = ref();
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
const treeData = ref([]);
|
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
const gridOptions = reactive(
|
const gridOptions = reactive(
|
||||||
gridProps({
|
gridProps({
|
||||||
|
size: 'medium',
|
||||||
columns: getColumns({ type: 'taizhang' }),
|
columns: getColumns({ type: 'taizhang' }),
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
autoLoad: false,
|
autoLoad: false,
|
||||||
|
@ -36,6 +36,7 @@ const gridOptions = reactive(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pagerConfig: {
|
pagerConfig: {
|
||||||
|
size: 'medium',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
toolbarConfig: {
|
toolbarConfig: {
|
||||||
|
@ -140,4 +141,11 @@ const searchForm = ref({
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style></style>
|
<style scoped>
|
||||||
|
:deep(.vxe-table--render-default.size--medium) {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
:deep(.ant-form-item .ant-form-item-label > label) {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -359,7 +359,7 @@ function downloadFile(fileUrl) {
|
||||||
|
|
||||||
<div
|
<div
|
||||||
:class="[bgColor]"
|
:class="[bgColor]"
|
||||||
class="content-area mb-4 flex h-[55vh] items-center justify-center overflow-y-auto rounded-lg p-4"
|
class="content-area mb-4 flex h-[50vh] items-center justify-center overflow-y-auto rounded-lg p-4"
|
||||||
>
|
>
|
||||||
<p :class="[textColor, textSize]" class="text-center">
|
<p :class="[textColor, textSize]" class="text-center">
|
||||||
{{ currentSpeaker.abstracts }}
|
{{ currentSpeaker.abstracts }}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Send request and capture response data
|
||||||
|
response=$(curl -s http://192.168.147.164:8083/rl/dictData/page)
|
||||||
|
|
||||||
|
# Check if response is not empty
|
||||||
|
if [ -z "$response" ]; then
|
||||||
|
echo "请求失败,未收到响应"
|
||||||
|
echo "export const responseStatus = '请求失败,未收到响应';" > response.ts
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract status code and records using grep and sed
|
||||||
|
http_code=$(echo "$response" | grep -o '"code":[0-9]*' | sed 's/"code"://')
|
||||||
|
records=$(echo "$response" | grep -o '"records":\[[^]]*\]' | sed 's/"records"://')
|
||||||
|
|
||||||
|
# Define the TypeScript file path
|
||||||
|
ts_file="response.ts"
|
||||||
|
|
||||||
|
# Write to the TypeScript file
|
||||||
|
echo "请求成功"
|
||||||
|
echo "export const records = $records;" > $ts_file
|
||||||
|
|
|
@ -42,9 +42,9 @@ function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) {
|
||||||
nitroMock: !isBuild,
|
nitroMock: !isBuild,
|
||||||
nitroMockOptions: {},
|
nitroMockOptions: {},
|
||||||
print: !isBuild,
|
print: !isBuild,
|
||||||
printInfoMap: {
|
// printInfoMap: {
|
||||||
'Vben Admin Docs': 'https://doc.vben.pro',
|
// 'Vben Admin Docs': 'https://doc.vben.pro',
|
||||||
},
|
// },
|
||||||
pwa: true,
|
pwa: true,
|
||||||
pwaOptions: getDefaultPwaOptions(appTitle),
|
pwaOptions: getDefaultPwaOptions(appTitle),
|
||||||
...envConfig,
|
...envConfig,
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
type RequestMethod = (url: string) => Promise<any>;
|
||||||
|
|
||||||
|
interface DictionaryItem {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DictionaryOptions {
|
||||||
|
baseUrl: string;
|
||||||
|
endpoints?: {
|
||||||
|
all: string;
|
||||||
|
byId: (id: number) => string;
|
||||||
|
byType: (type: string) => string;
|
||||||
|
};
|
||||||
|
parseResponse?: (response: any) => any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Dictionary {
|
||||||
|
private options: DictionaryOptions;
|
||||||
|
private request: RequestMethod;
|
||||||
|
|
||||||
|
constructor(requestMethod: RequestMethod, options: DictionaryOptions) {
|
||||||
|
this.request = requestMethod;
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseResponse(response: any): any {
|
||||||
|
return this.options.parseResponse
|
||||||
|
? this.options.parseResponse(response)
|
||||||
|
: response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch all dictionary items
|
||||||
|
async getAll(): Promise<DictionaryItem[]> {
|
||||||
|
// try {
|
||||||
|
const response = await this.request(`123`);
|
||||||
|
// return this.parseResponse(response);
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error fetching all dictionaries', error);
|
||||||
|
// throw error;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch a specific dictionary item by ID
|
||||||
|
async getById(id: number): Promise<DictionaryItem> {
|
||||||
|
try {
|
||||||
|
const endpoint = this.options.endpoints?.byId(id) || `/id/${id}`;
|
||||||
|
const response = await this.request(`${this.options.baseUrl}${endpoint}`);
|
||||||
|
return this.parseResponse(response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching dictionary by ID: ${id}`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch dictionary items by type
|
||||||
|
async getByType(type: string): Promise<DictionaryItem[]> {
|
||||||
|
try {
|
||||||
|
const endpoint = this.options.endpoints?.byType(type) || `/type/${type}`;
|
||||||
|
const response = await this.request(`${this.options.baseUrl}${endpoint}`);
|
||||||
|
return this.parseResponse(response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching dictionaries by type: ${type}`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
// export * from './logger/index';
|
// export * from './logger/index';
|
||||||
|
export * from './dict/index';
|
||||||
export * from './utils/index';
|
export * from './utils/index';
|
||||||
|
|
||||||
// export const logger = {
|
// export const logger = {
|
||||||
// log(level: string, message: any, error?: any) {
|
// log(level: string, message: any, error?: any) {
|
||||||
// const timestamp = new Date().toISOString();
|
// const timestamp = new Date().toISOString();
|
||||||
|
|
|
@ -284,6 +284,9 @@ export default {
|
||||||
/** 协同办公/督查督办/执行反馈 执行反馈已办查询 */
|
/** 协同办公/督查督办/执行反馈 执行反馈已办查询 */
|
||||||
get_pageDone: (data?: QueryOptions) =>
|
get_pageDone: (data?: QueryOptions) =>
|
||||||
http.get('/app/feedback/pageDone', data),
|
http.get('/app/feedback/pageDone', data),
|
||||||
|
/** 协同办公/督查督办/立项发起 查询立项对应的反馈 */
|
||||||
|
get_queryFeedback: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/feedback/queryFeedback', data),
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
/** 协同办公/文件上传/下载 多文件上传 */
|
/** 协同办公/文件上传/下载 多文件上传 */
|
||||||
|
@ -637,8 +640,8 @@ export default {
|
||||||
get_getContractSignInfo: (data?: QueryOptions) =>
|
get_getContractSignInfo: (data?: QueryOptions) =>
|
||||||
http.get('/app/qdSign/getContractSignInfo', data),
|
http.get('/app/qdSign/getContractSignInfo', data),
|
||||||
/** 合同系统/签订 打印签订审批表 */
|
/** 合同系统/签订 打印签订审批表 */
|
||||||
get_createUserListWord: (data?: QueryOptions) =>
|
get_printApprove: (data?: QueryOptions) =>
|
||||||
http.get('/app/qdSign/createUserListWord', data),
|
http.get('/app/qdSign/printApprove', data),
|
||||||
/** 合同系统/签订 打印文本 */
|
/** 合同系统/签订 打印文本 */
|
||||||
get_textPrint: (data?: QueryOptions) =>
|
get_textPrint: (data?: QueryOptions) =>
|
||||||
http.get('/app/qdSign/textPrint', data),
|
http.get('/app/qdSign/textPrint', data),
|
||||||
|
@ -733,6 +736,9 @@ export default {
|
||||||
/** 公共 获取请求ip */
|
/** 公共 获取请求ip */
|
||||||
get_getClientIp: (data?: QueryOptions) =>
|
get_getClientIp: (data?: QueryOptions) =>
|
||||||
http.get('/app/common/getClientIp', data),
|
http.get('/app/common/getClientIp', data),
|
||||||
|
/** 公共 获取项目地址 */
|
||||||
|
get_getProjectAddress: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/common/getProjectAddress', data),
|
||||||
},
|
},
|
||||||
address: {
|
address: {
|
||||||
/** 协同办公/订餐管理/订餐地址 查询(分页) */
|
/** 协同办公/订餐管理/订餐地址 查询(分页) */
|
||||||
|
@ -776,6 +782,9 @@ export default {
|
||||||
/** 合同系统 流程已办 */
|
/** 合同系统 流程已办 */
|
||||||
get_getDoneTaskByUserID: (data?: QueryOptions) =>
|
get_getDoneTaskByUserID: (data?: QueryOptions) =>
|
||||||
http.get('/app/workFlow/getDoneTaskByUserID', data),
|
http.get('/app/workFlow/getDoneTaskByUserID', data),
|
||||||
|
/** 合同系统 获取流程图 */
|
||||||
|
get_getFlowImg: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/workFlow/getFlowImg', data),
|
||||||
},
|
},
|
||||||
biddingResult: {
|
biddingResult: {
|
||||||
/** 合同系统/选商/选商结果 分页查询 */
|
/** 合同系统/选商/选商结果 分页查询 */
|
||||||
|
@ -784,17 +793,40 @@ export default {
|
||||||
/** 合同系统/选商/选商结果 保存 */
|
/** 合同系统/选商/选商结果 保存 */
|
||||||
post_save: (data?: BodyOptions) =>
|
post_save: (data?: BodyOptions) =>
|
||||||
http.post('/app/biddingResult/save', data),
|
http.post('/app/biddingResult/save', data),
|
||||||
|
/** 合同系统/选商/选商结果 查询流程审核节点 */
|
||||||
|
get_getFlowNodeUserConfig: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/biddingResult/getFlowNodeUserConfig', data),
|
||||||
|
/** 合同系统/选商/选商结果 启动流程 */
|
||||||
|
post_startWorkFlow: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/biddingResult/startWorkFlow', data),
|
||||||
|
/** 合同系统/选商/选商结果 审核通过 */
|
||||||
|
post_submit: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/biddingResult/submit', data),
|
||||||
|
/** 合同系统/选商/选商结果 退回 */
|
||||||
|
post_rollback: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/biddingResult/rollback', data),
|
||||||
|
/** 合同系统/选商/选商结果 待审核 */
|
||||||
|
get_toDoPage: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/biddingResult/toDoPage', data),
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
/** 合同系统/首页待办/已办 待办 */
|
/** 合同系统/首页待办/已办 首页待办 */
|
||||||
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
||||||
|
/** 合同系统/首页待办/已办 首页已办 */
|
||||||
|
get_done: (data?: QueryOptions) => http.get('/app/home/done', data),
|
||||||
},
|
},
|
||||||
sqConsignPt: {
|
sqConsignPt: {
|
||||||
/** 合同系统/签约授权 签约授权保存 */
|
/** 合同系统/签约授权 签约授权保存 */
|
||||||
post_saveSignMultiEntity: (data?: BodyOptions) =>
|
post_saveSignMultiEntity: (data?: BodyOptions) =>
|
||||||
http.post('/app/sqConsignPt/saveSignMultiEntity', data),
|
http.post('/app/sqConsignPt/saveSignMultiEntity', data),
|
||||||
/** 合同系统/签约授权 签约依据查询 */
|
/** 合同系统/签约授权 签约授权查询 */
|
||||||
get_SigningaAuthorizationSerch: (data?: QueryOptions) =>
|
get_SigningaAuthorizationSerch: (data?: QueryOptions) =>
|
||||||
http.get('/app/sqConsignPt/SigningaAuthorizationSerch', data),
|
http.get('/app/sqConsignPt/SigningaAuthorizationSerch', data),
|
||||||
|
/** 合同系统/签约授权 查询单条签约授权数据 */
|
||||||
|
get_getOne: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/sqConsignPt/getOne', data),
|
||||||
|
/** 合同系统/签约授权 签约授权提交 */
|
||||||
|
post_flowStart: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/sqConsignPt/flowStart', data),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue