协同办公优化
This commit is contained in:
parent
0149f4b10b
commit
3b1197f9ec
|
@ -1,101 +1,119 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, reactive, onMounted } from 'vue';
|
import { computed, onMounted, reactive, ref } from 'vue';
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { useRouter } from 'vue-router';
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
|
||||||
import { MdiAdd, MdiUpdate, MdiDelete, MdiImport, MdiExport, MdiRadioUnchecked, MdiRadioChecked } from '@vben/icons';
|
|
||||||
import { getFormSchema, getColumns, PrimaryKey } from './crud.tsx';
|
|
||||||
import { getMonthStartAndEnd } from '#/utils/time'
|
|
||||||
import Apis from '#/api'
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { message } from "ant-design-vue";
|
|
||||||
import { Modal } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { useRouter } from 'vue-router'
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
import {
|
||||||
|
MdiAdd,
|
||||||
|
MdiDelete,
|
||||||
|
MdiExport,
|
||||||
|
MdiRadioChecked,
|
||||||
|
MdiRadioUnchecked,
|
||||||
|
MdiUpdate,
|
||||||
|
} from '@vben/icons';
|
||||||
|
|
||||||
|
import { message, Modal } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
import { getMonthStartAndEnd } from '#/utils/time';
|
||||||
|
|
||||||
|
import { getColumns, getFormSchema, PrimaryKey } from './crud.tsx';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const checkedValue = ref('all')
|
const checkedValue = ref('all');
|
||||||
const exportSearchParams = ref<any>({
|
const exportSearchParams = ref<any>({
|
||||||
daterange: getMonthStartAndEnd(),
|
daterange: getMonthStartAndEnd(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchRef = ref()
|
const searchRef = ref();
|
||||||
let isConfirmLoading = ref(false)
|
const isConfirmLoading = ref(false);
|
||||||
const [_Modal, modalApi] = useVbenModal({
|
const [_Modal, modalApi] = useVbenModal({
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
isConfirmLoading.value = true
|
isConfirmLoading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let params = {};
|
let params = {};
|
||||||
if (checkedValue.value == "daterange") {
|
if (checkedValue.value == 'daterange') {
|
||||||
params = {
|
params = {
|
||||||
startDate: exportSearchParams.value.daterange[0],
|
startDate: exportSearchParams.value.daterange[0],
|
||||||
endDate: exportSearchParams.value.daterange[1],
|
endDate: exportSearchParams.value.daterange[1],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let res = await Apis.zbgl.post_export({
|
const res = await Apis.zbgl
|
||||||
params: params, config: {
|
.post_export({
|
||||||
meta: {
|
params,
|
||||||
responseType: 'blob'
|
config: {
|
||||||
}
|
meta: {
|
||||||
}
|
responseType: 'blob',
|
||||||
}).send();
|
},
|
||||||
message.success("导出成功");
|
},
|
||||||
modalApi.close()
|
})
|
||||||
|
.send();
|
||||||
|
message.success('导出成功');
|
||||||
|
modalApi.close();
|
||||||
showExportModal.value = false;
|
showExportModal.value = false;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
isConfirmLoading.value = false
|
isConfirmLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.info('onConfirm');
|
||||||
console.info("onConfirm");
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
const treeData = ref([]);
|
const treeData = ref([]);
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
const gridOptions = reactive(gridProps({
|
const gridOptions = reactive(
|
||||||
columns: getColumns(),
|
gridProps({
|
||||||
proxyConfig: {
|
columns: getColumns(),
|
||||||
autoLoad: false,
|
proxyConfig: {
|
||||||
ajax: {
|
autoLoad: false,
|
||||||
query: ({ page }) => {
|
ajax: {
|
||||||
return Apis.contractBaseInfo.get_page({ params: { pageNum: page.currentPage, pageSize: page.pageSize, ...searchRef.value?.formData } })
|
query: ({ page }) => {
|
||||||
}
|
return Apis.contractBaseInfo.get_page({
|
||||||
|
params: {
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
...searchRef.value?.formData,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
pagerConfig: {
|
||||||
pagerConfig: {
|
enabled: true,
|
||||||
enabled: true
|
},
|
||||||
},
|
toolbarConfig: {
|
||||||
toolbarConfig: {
|
enabled: true,
|
||||||
enabled: true
|
},
|
||||||
},
|
}),
|
||||||
}));
|
);
|
||||||
|
|
||||||
function handleEdit(record?: any) {
|
function handleEdit(record?: any) {
|
||||||
if (record && record[PrimaryKey]) {
|
if (record && record[PrimaryKey]) {
|
||||||
router.push("/contract/approval/edit/" + record[PrimaryKey]);
|
router.push(`/contract/approval/edit/${record[PrimaryKey]}`);
|
||||||
} else {
|
} else {
|
||||||
router.push("/contract/approval/edit");
|
router.push('/contract/approval/edit');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete(row) {
|
function handleDelete(row) {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: "是否确认删除该条记录?",
|
content: '是否确认删除该条记录?',
|
||||||
okType: 'danger',
|
okType: 'danger',
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
await Apis.contractBaseInfo.post_deletes({ params: { ids: row[PrimaryKey] } })
|
await Apis.contractBaseInfo.post_deletes({
|
||||||
message.success("删除成功");
|
params: { ids: row[PrimaryKey] },
|
||||||
triggerProxy("reload");
|
});
|
||||||
|
message.success('删除成功');
|
||||||
|
triggerProxy('reload');
|
||||||
},
|
},
|
||||||
onCancel() {
|
onCancel() {
|
||||||
console.log('Cancel');
|
console.log('Cancel');
|
||||||
|
@ -107,9 +125,9 @@ function handleExport() {
|
||||||
const $grid = xGridRef.value;
|
const $grid = xGridRef.value;
|
||||||
if ($grid) {
|
if ($grid) {
|
||||||
$grid.exportData({
|
$grid.exportData({
|
||||||
type: "xlsx",
|
type: 'xlsx',
|
||||||
});
|
});
|
||||||
message.success("导出成功");
|
message.success('导出成功');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,66 +151,81 @@ function handleCellClick({ row }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
triggerProxy('reload')
|
triggerProxy('reload');
|
||||||
})
|
});
|
||||||
|
|
||||||
const searchForm = ref({
|
const searchForm = ref({
|
||||||
...getFormSchema(),
|
...getFormSchema(),
|
||||||
onSearch(context: any) {
|
onSearch(context: any) {
|
||||||
triggerProxy('reload')
|
triggerProxy('reload');
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function toPage() {
|
function toPage() {
|
||||||
window.open("/iframe/meeting/standing-book", "_blank");
|
window.open('/iframe/meeting/standing-book', '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function toDetail(row) {
|
function toDetail(row) {
|
||||||
window.open("/iframe/meeting/start/" + row.guid, "_blank");
|
window.open(`/iframe/meeting/start/${row.guid}`, '_blank');
|
||||||
}
|
}
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page contentClass="h-full flex flex-col">
|
<Page content-class="h-full flex flex-col">
|
||||||
<fs-search ref="searchRef" v-bind="searchForm">
|
<fs-search ref="searchRef" v-bind="searchForm">
|
||||||
<template #search_price="{ row }">
|
<template #search_price="{ row }">
|
||||||
<a-input-number v-model:value="row.budgetSum1" placeholder="">
|
<a-input-number v-model:value="row.budgetSum1" placeholder="" />
|
||||||
</a-input-number>
|
|
||||||
<span class="mx-1">至</span>
|
<span class="mx-1">至</span>
|
||||||
<a-input-number v-model:value="row.budgetSum2" placeholder="">
|
<a-input-number v-model:value="row.budgetSum2" placeholder="" />
|
||||||
</a-input-number>
|
|
||||||
</template>
|
</template>
|
||||||
<template #form_time="{ row }">
|
<template #form_time="{ row }">
|
||||||
<a-date-picker v-model:value="row.startTime" placeholder="" format="YYYY-MM-DD" value-format="YYYY-MM-DD">
|
<a-date-picker
|
||||||
</a-date-picker>
|
v-model:value="row.startTime"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
placeholder=""
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
<span class="mx-1">至</span>
|
<span class="mx-1">至</span>
|
||||||
<a-date-picker v-model:value="row.endTime" placeholder="" format="YYYY-MM-DD" value-format="YYYY-MM-DD">
|
<a-date-picker
|
||||||
</a-date-picker>
|
v-model:value="row.endTime"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
placeholder=""
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</fs-search>
|
</fs-search>
|
||||||
|
|
||||||
<div class="flex-1 min-h-300px">
|
<div class="min-h-300px flex-1">
|
||||||
<vxe-grid ref="xGridRef" v-bind="gridOptions" @cell-click="handleCellClick">
|
<vxe-grid
|
||||||
|
ref="xGridRef"
|
||||||
|
v-bind="gridOptions"
|
||||||
|
@cell-click="handleCellClick"
|
||||||
|
>
|
||||||
<template #toolbar_buttons>
|
<template #toolbar_buttons>
|
||||||
<a-space>
|
<a-space>
|
||||||
<vben-button variant="primary" @click="handleEdit()">
|
<vben-button variant="primary" @click="handleEdit()">
|
||||||
<MdiAdd class="text-lg mr-0.5" />
|
<MdiAdd class="mr-0.5 text-lg" />
|
||||||
新增
|
新增
|
||||||
</vben-button>
|
</vben-button>
|
||||||
<vben-button variant="warning" :disabled="!selectRow || !selectRow[PrimaryKey]"
|
<vben-button
|
||||||
@click="handleEdit(selectRow)">
|
:disabled="!selectRow || !selectRow[PrimaryKey]"
|
||||||
<MdiUpdate class="text-lg mr-0.5" />
|
variant="warning"
|
||||||
|
@click="handleEdit(selectRow)"
|
||||||
|
>
|
||||||
|
<MdiUpdate class="mr-0.5 text-lg" />
|
||||||
修改
|
修改
|
||||||
</vben-button>
|
</vben-button>
|
||||||
<vben-button variant="primary" @click="handleExport()">
|
<vben-button variant="primary" @click="handleExport()">
|
||||||
<MdiExport class="text-lg mr-0.5" />
|
<MdiExport class="mr-0.5 text-lg" />
|
||||||
导出
|
导出
|
||||||
</vben-button>
|
</vben-button>
|
||||||
<vben-button variant="destructive" :disabled="!selectRow || !selectRow[PrimaryKey]"
|
<vben-button
|
||||||
@click="handleDelete(selectRow)">
|
:disabled="!selectRow || !selectRow[PrimaryKey]"
|
||||||
<MdiDelete class="text-lg mr-0.5" />
|
variant="destructive"
|
||||||
|
@click="handleDelete(selectRow)"
|
||||||
|
>
|
||||||
|
<MdiDelete class="mr-0.5 text-lg" />
|
||||||
删除
|
删除
|
||||||
</vben-button>
|
</vben-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
@ -204,7 +237,6 @@ function toDetail(row) {
|
||||||
<MdiRadioUnchecked v-else />
|
<MdiRadioUnchecked v-else />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
@ -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),
|
||||||
|
@ -381,6 +384,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: {
|
||||||
/** 合同系统/立项 合同立项保存 */
|
/** 合同系统/立项 合同立项保存 */
|
||||||
|
@ -777,4 +786,12 @@ export default {
|
||||||
/** 合同系统/首页待办/已办 待办 */
|
/** 合同系统/首页待办/已办 待办 */
|
||||||
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
||||||
},
|
},
|
||||||
|
sqConsignPt: {
|
||||||
|
/** 合同系统/签约授权 签约授权保存 */
|
||||||
|
post_saveSignMultiEntity: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/sqConsignPt/saveSignMultiEntity', data),
|
||||||
|
/** 合同系统/签约授权 签约依据查询 */
|
||||||
|
get_SigningaAuthorizationSerch: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/sqConsignPt/SigningaAuthorizationSerch', data),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
* 该文件可自行根据业务逻辑进行调整
|
* 该文件可自行根据业务逻辑进行调整
|
||||||
*/
|
*/
|
||||||
import { preferences } from '@vben/preferences';
|
import { preferences } from '@vben/preferences';
|
||||||
|
|
||||||
import { useAccessStore } from '@vben/stores';
|
import { useAccessStore } from '@vben/stores';
|
||||||
|
|
||||||
|
import { createAlova } from 'alova';
|
||||||
|
import { createServerTokenAuthentication } from 'alova/client';
|
||||||
|
import fetchAdapter from 'alova/fetch';
|
||||||
|
import vueHook from 'alova/vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { merge } from 'lodash-es';
|
||||||
|
|
||||||
import { useAuthStore } from '#/store';
|
import { useAuthStore } from '#/store';
|
||||||
|
|
||||||
import { transferResponse } from './transferResponse';
|
import { type BodyOptions, type QueryOptions } from '../global.d';
|
||||||
import { type QueryOptions, type BodyOptions } from '../global.d';
|
|
||||||
import { merge } from 'lodash-es';
|
|
||||||
|
|
||||||
import { createAlova } from 'alova';
|
|
||||||
import fetchAdapter from 'alova/fetch';
|
|
||||||
import vueHook from 'alova/vue';
|
|
||||||
import { ACCESS_TOKEN_FIELD, getBaseURL } from './config';
|
import { ACCESS_TOKEN_FIELD, getBaseURL } from './config';
|
||||||
import { createServerTokenAuthentication } from 'alova/client';
|
import { transferResponse } from './transferResponse';
|
||||||
|
|
||||||
/** 储存过期的token */
|
/** 储存过期的token */
|
||||||
let expireTokenCache = [];
|
const expireTokenCache = [];
|
||||||
|
|
||||||
/** 服务端 Token 校验 */
|
/** 服务端 Token 校验 */
|
||||||
const { onAuthRequired, onResponseRefreshToken } =
|
const { onAuthRequired, onResponseRefreshToken } =
|
||||||
|
@ -37,10 +35,10 @@ const { onAuthRequired, onResponseRefreshToken } =
|
||||||
}
|
}
|
||||||
|
|
||||||
const responseClone = response.clone();
|
const responseClone = response.clone();
|
||||||
let data = await responseClone.json();
|
const data = await responseClone.json();
|
||||||
|
|
||||||
// 当服务端返回401时,表示token过期
|
// 当服务端返回401时,表示token过期
|
||||||
let isExpired = ['401'].includes(data.code);
|
const isExpired = ['401'].includes(data.code);
|
||||||
if (isExpired) {
|
if (isExpired) {
|
||||||
console.log('AccessToken已过期', data.code);
|
console.log('AccessToken已过期', data.code);
|
||||||
expireTokenCache.push(method.config.headers[ACCESS_TOKEN_FIELD]);
|
expireTokenCache.push(method.config.headers[ACCESS_TOKEN_FIELD]);
|
||||||
|
@ -93,14 +91,14 @@ export const alovaInstance = createAlova({
|
||||||
// // 统一设置POST的缓存模式
|
// // 统一设置POST的缓存模式
|
||||||
// GET: {
|
// GET: {
|
||||||
// mode: 'restore',
|
// mode: 'restore',
|
||||||
// expire: 60 * 10 * 1000
|
// expire: 60 * 10 * 1000,
|
||||||
// },
|
// },
|
||||||
// POST: {
|
// POST: {
|
||||||
// mode: 'restore',
|
// mode: 'restore',
|
||||||
// expire: 60 * 10 * 1000
|
// expire: 60 * 10 * 1000
|
||||||
// },
|
// },
|
||||||
// // 统一设置HEAD请求的缓存模式
|
// // 统一设置HEAD请求的缓存模式
|
||||||
// HEAD: 60 * 10 * 1000
|
// HEAD: 60 * 10 * 1000
|
||||||
// },
|
// },
|
||||||
/** 请求拦截器 */
|
/** 请求拦截器 */
|
||||||
beforeRequest: onAuthRequired((method) => {
|
beforeRequest: onAuthRequired((method) => {
|
||||||
|
@ -136,7 +134,7 @@ export const alovaInstance = createAlova({
|
||||||
/** 响应拦截器 */
|
/** 响应拦截器 */
|
||||||
responded: onResponseRefreshToken(async (response, method) => {
|
responded: onResponseRefreshToken(async (response, method) => {
|
||||||
if (method.meta?.responseType === 'blob') {
|
if (method.meta?.responseType === 'blob') {
|
||||||
let blob = await response.blob();
|
const blob = await response.blob();
|
||||||
const url = window.URL.createObjectURL(blob);
|
const url = window.URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = url;
|
a.href = url;
|
||||||
|
@ -150,14 +148,14 @@ export const alovaInstance = createAlova({
|
||||||
}
|
}
|
||||||
a.download = fileName;
|
a.download = fileName;
|
||||||
// 触发下载
|
// 触发下载
|
||||||
document.body.appendChild(a);
|
document.body.append(a);
|
||||||
a.click();
|
a.click();
|
||||||
// 移除链接
|
// 移除链接
|
||||||
document.body.removeChild(a);
|
a.remove();
|
||||||
window.URL.revokeObjectURL(url);
|
window.URL.revokeObjectURL(url);
|
||||||
return {
|
return {
|
||||||
blob: blob,
|
blob,
|
||||||
url: url,
|
url,
|
||||||
filename: fileName,
|
filename: fileName,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -197,14 +195,14 @@ export const alovaInstance = createAlova({
|
||||||
});
|
});
|
||||||
|
|
||||||
class Http {
|
class Http {
|
||||||
/**
|
private appendParamsToUrl(url: string, params: any): string {
|
||||||
* 适配swagger路径参数,针对于pathParams
|
let queryString = '';
|
||||||
* 输入参数 "/api/v1/user/{id}",{ pathParams:{ id :1 },params:{ id:2 } }
|
for (const key in params) {
|
||||||
* 输出请求 /api/v1/user/1?id=2
|
if (Object.prototype.hasOwnProperty.call(params, key)) {
|
||||||
*/
|
queryString += `${queryString ? '&' : '?'}${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`;
|
||||||
private replacePathParams(url: string, pathParams?: any): string {
|
}
|
||||||
if (!pathParams) return url;
|
}
|
||||||
return url.replace(/{(\w+)}/g, (_, key) => pathParams[key] || `{${key}}`);
|
return url + queryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,11 +230,24 @@ class Http {
|
||||||
return (options as BodyOptions).data !== undefined;
|
return (options as BodyOptions).data !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 适配swagger路径参数,针对于pathParams
|
||||||
|
* 输入参数 "/api/v1/user/{id}",{ pathParams:{ id :1 },params:{ id:2 } }
|
||||||
|
* 输出请求 /api/v1/user/1?id=2
|
||||||
|
*/
|
||||||
|
private replacePathParams(url: string, pathParams?: any): string {
|
||||||
|
if (!pathParams) return url;
|
||||||
|
return url.replaceAll(
|
||||||
|
/\{(\w+)\}/g,
|
||||||
|
(_, key) => pathParams[key] || `{${key}}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private request(
|
private request(
|
||||||
method: string,
|
method: string,
|
||||||
url: string,
|
url: string,
|
||||||
data?: BodyOptions | QueryOptions,
|
data?: BodyOptions | QueryOptions,
|
||||||
) {
|
): Promise<any> {
|
||||||
let finalUrl = this.replacePathParams(url, data?.pathParams);
|
let finalUrl = this.replacePathParams(url, data?.pathParams);
|
||||||
const config = this.getConfig(data?.config);
|
const config = this.getConfig(data?.config);
|
||||||
|
|
||||||
|
@ -256,7 +267,7 @@ class Http {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let alovaMethod: 'Get' | 'Post' | 'Delete' | 'Put' = 'Get';
|
let alovaMethod: 'Delete' | 'Get' | 'Post' | 'Put' = 'Get';
|
||||||
|
|
||||||
if (method === 'get' || method === 'delete') {
|
if (method === 'get' || method === 'delete') {
|
||||||
if (method === 'get') {
|
if (method === 'get') {
|
||||||
|
@ -285,20 +296,18 @@ class Http {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private appendParamsToUrl(url: string, params: any): string {
|
delete(url: string, data?: QueryOptions) {
|
||||||
let queryString = '';
|
return this.request('delete', url, data);
|
||||||
for (const key in params) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(params, key)) {
|
|
||||||
queryString += `${queryString ? '&' : '?'}${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return url + queryString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get(url: string, data?: QueryOptions) {
|
get(url: string, data?: QueryOptions) {
|
||||||
return this.request('get', url, data);
|
return this.request('get', url, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patch(url: string, data?: BodyOptions) {
|
||||||
|
return this.request('patch', url, data);
|
||||||
|
}
|
||||||
|
|
||||||
post(url: string, data?: BodyOptions) {
|
post(url: string, data?: BodyOptions) {
|
||||||
return this.request('post', url, data);
|
return this.request('post', url, data);
|
||||||
}
|
}
|
||||||
|
@ -306,14 +315,6 @@ class Http {
|
||||||
put(url: string, data?: BodyOptions) {
|
put(url: string, data?: BodyOptions) {
|
||||||
return this.request('put', url, data);
|
return this.request('put', url, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
patch(url: string, data?: BodyOptions) {
|
|
||||||
return this.request('patch', url, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(url: string, data?: QueryOptions) {
|
|
||||||
return this.request('delete', url, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const http = new Http();
|
export const http = new Http();
|
||||||
|
|
|
@ -1,7 +1,85 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { DictDataType } from '#/utils/dict';
|
||||||
|
|
||||||
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import { getDictOpts } from '#/utils/dict';
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
icon?: string;
|
||||||
|
labelField?: string;
|
||||||
|
multiple?: boolean;
|
||||||
|
options: DictDataType[];
|
||||||
|
selectable?: boolean;
|
||||||
|
type?: string;
|
||||||
|
value?: Array<boolean | number | string> | boolean | number | string;
|
||||||
|
valueField?: string;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
type: '',
|
||||||
|
options: () => [],
|
||||||
|
multiple: false,
|
||||||
|
selectable: false,
|
||||||
|
labelField: 'label',
|
||||||
|
valueField: 'value',
|
||||||
|
value: '',
|
||||||
|
icon: '',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:value', 'tag-click']);
|
||||||
|
|
||||||
|
const dictData = ref<DictDataType | null>(null);
|
||||||
|
|
||||||
|
const selectedValues = ref<Array<number | string>>(
|
||||||
|
Array.isArray(props.value) ? props.value : [],
|
||||||
|
);
|
||||||
|
|
||||||
|
const dicts = computed(() => {
|
||||||
|
return props.type ? getDictOpts(props.type) : props.options;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleClick = (dict: DictDataType) => {
|
||||||
|
emit('tag-click', dict);
|
||||||
|
if (props.selectable) {
|
||||||
|
if (props.multiple) {
|
||||||
|
const index = selectedValues.value.indexOf(dict.value);
|
||||||
|
if (index === -1) {
|
||||||
|
selectedValues.value.push(dict.value);
|
||||||
|
} else {
|
||||||
|
selectedValues.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
emit('update:value', selectedValues.value);
|
||||||
|
} else {
|
||||||
|
emit('update:value', dict.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTagColor = (dict: DictDataType) => {
|
||||||
|
return (props.multiple && selectedValues.value.includes(dict.value)) ||
|
||||||
|
(!props.multiple && props.value == dict.value)
|
||||||
|
? 'blue'
|
||||||
|
: '';
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
dictData.value =
|
||||||
|
(props.options || []).find(
|
||||||
|
(dict: DictDataType) => dict.value === props.value.toString(),
|
||||||
|
) || null;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<template v-if="props.selectable">
|
<template v-if="props.selectable">
|
||||||
<div v-for="(dict, index) in dicts" :key="index" @click="handleClick(dict)"
|
<div
|
||||||
:class="{ 'cursor-pointer': selectable }">
|
v-for="(dict, index) in dicts"
|
||||||
|
:key="index"
|
||||||
|
:class="{ 'cursor-pointer': selectable }"
|
||||||
|
@click="handleClick(dict)"
|
||||||
|
>
|
||||||
<a-tag :color="getTagColor(dict)" :round="!multiple">
|
<a-tag :color="getTagColor(dict)" :round="!multiple">
|
||||||
{{ dict[labelField] }}
|
{{ dict[labelField] }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
|
@ -17,81 +95,12 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<!-- <a-tag :color="dictData?.colorType || ''">
|
<a-tag :color="dictData?.colorType || ''">
|
||||||
{{ (dictData && dictData[labelField]) || value }}
|
{{ (dictData && dictData[labelField]) || value }}
|
||||||
</a-tag> -->
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed, onMounted } from "vue";
|
|
||||||
import { Tag, Space } from "ant-design-vue";
|
|
||||||
import { getDictOpts } from "#/utils/dict";
|
|
||||||
import type { DictDataType } from "#/utils/dict";
|
|
||||||
|
|
||||||
const props = withDefaults(
|
|
||||||
defineProps<{
|
|
||||||
type?: string;
|
|
||||||
options: DictDataType[];
|
|
||||||
value?: string | number | boolean | Array<string | number | boolean>;
|
|
||||||
icon?: string;
|
|
||||||
multiple?: boolean;
|
|
||||||
selectable?: boolean;
|
|
||||||
labelField?: string;
|
|
||||||
valueField?: string;
|
|
||||||
}>(),
|
|
||||||
{
|
|
||||||
type: "",
|
|
||||||
options: () => [],
|
|
||||||
multiple: false,
|
|
||||||
selectable: false,
|
|
||||||
labelField: "label",
|
|
||||||
valueField: "value",
|
|
||||||
value: "",
|
|
||||||
icon: "",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const emit = defineEmits(["update:value", "tag-click"]);
|
|
||||||
|
|
||||||
const dictData = ref<DictDataType | null>(null);
|
|
||||||
const selectedValues = ref<Array<string | number>>(
|
|
||||||
Array.isArray(props.value) ? props.value : []
|
|
||||||
);
|
|
||||||
|
|
||||||
const dicts = computed(() => {
|
|
||||||
return props.type ? getDictOpts(props.type) : props.options;
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleClick = (dict: DictDataType) => {
|
|
||||||
emit("tag-click", dict);
|
|
||||||
if (props.selectable) {
|
|
||||||
if (props.multiple) {
|
|
||||||
const index = selectedValues.value.indexOf(dict.value);
|
|
||||||
if (index === -1) {
|
|
||||||
selectedValues.value.push(dict.value);
|
|
||||||
} else {
|
|
||||||
selectedValues.value.splice(index, 1);
|
|
||||||
}
|
|
||||||
emit("update:value", selectedValues.value);
|
|
||||||
} else {
|
|
||||||
emit("update:value", dict.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getTagColor = (dict: DictDataType) => {
|
|
||||||
return (props.multiple && selectedValues.value.includes(dict.value)) ||
|
|
||||||
(!props.multiple && props.value == dict.value)
|
|
||||||
? "blue"
|
|
||||||
: "";
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.cursor-pointer {
|
.cursor-pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { Button, Tag } from 'ant-design-vue';
|
import { Button, Tag } from 'ant-design-vue';
|
||||||
import { isArray, isString } from 'lodash-es';
|
|
||||||
import { DictTag } from '#/components/dict-tag';
|
|
||||||
// import { Icon } from '@/components/Icon';
|
// import { Icon } from '@/components/Icon';
|
||||||
import { Tooltip } from 'ant-design-vue'
|
import { Tooltip } from 'ant-design-vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import { DictTag } from '#/components/dict-tag';
|
||||||
import { getDictOpts } from '#/utils/dict';
|
import { getDictOpts } from '#/utils/dict';
|
||||||
|
|
||||||
export const useRender = {
|
export const useRender = {
|
||||||
/**
|
/**
|
||||||
* 渲染图片
|
* 渲染图片
|
||||||
|
@ -26,7 +28,12 @@ export const useRender = {
|
||||||
* @returns link 按钮
|
* @returns link 按钮
|
||||||
*/
|
*/
|
||||||
renderLink: (url: string, text?: string) => {
|
renderLink: (url: string, text?: string) => {
|
||||||
if (url) return h(Button, { type: 'link', href: url, target: '_blank' }, () => text || '');
|
if (url)
|
||||||
|
return h(
|
||||||
|
Button,
|
||||||
|
{ type: 'link', href: url, target: '_blank' },
|
||||||
|
() => text || '',
|
||||||
|
);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
@ -37,8 +44,7 @@ export const useRender = {
|
||||||
* @returns 文本1 + 文本2
|
* @returns 文本1 + 文本2
|
||||||
*/
|
*/
|
||||||
renderText: (text: string, val: string) => {
|
renderText: (text: string, val: string) => {
|
||||||
if (text) return `${text} ${val}`;
|
return text ? `${text} ${val}` : '';
|
||||||
else return '';
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 渲染多行文本
|
* 渲染多行文本
|
||||||
|
@ -47,19 +53,19 @@ export const useRender = {
|
||||||
*/
|
*/
|
||||||
renderMultiLineText: (text: string, params?: any) => {
|
renderMultiLineText: (text: string, params?: any) => {
|
||||||
if (text) {
|
if (text) {
|
||||||
params = params || {}
|
params = params || {};
|
||||||
let classArr: string[] = params.class || [];
|
const classArr: string[] = params.class || [];
|
||||||
if (params?.maxLine && params?.maxLine > 0) {
|
if (params?.maxLine && params?.maxLine > 0) {
|
||||||
classArr.push('line-clamp-' + params?.maxLine)
|
classArr.push(`line-clamp-${params?.maxLine}`);
|
||||||
}
|
}
|
||||||
return h(
|
return h(
|
||||||
Tooltip,
|
Tooltip,
|
||||||
{ trigger: 'hover' },
|
{ trigger: 'hover' },
|
||||||
{
|
{
|
||||||
trigger: () => h('span', { class: classArr.join(' ') }, text),
|
trigger: () => h('span', { class: classArr.join(' ') }, text),
|
||||||
default: () => text
|
default: () => text,
|
||||||
}
|
},
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
@ -69,9 +75,8 @@ export const useRender = {
|
||||||
* @param color 标签颜色
|
* @param color 标签颜色
|
||||||
* @returns 标签
|
* @returns 标签
|
||||||
*/
|
*/
|
||||||
renderTag: (text: string | number, color?: string) => {
|
renderTag: (text: number | string, color?: string) => {
|
||||||
if (color) return h(Tag, { color }, () => text);
|
return color ? h(Tag, { color }, () => text) : h(Tag, {}, () => text);
|
||||||
else return h(Tag, {}, () => text);
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 渲染多标签
|
* 渲染多标签
|
||||||
|
@ -97,8 +102,9 @@ export const useRender = {
|
||||||
renderDate: (text: string, format?: string) => {
|
renderDate: (text: string, format?: string) => {
|
||||||
if (!text) return '';
|
if (!text) return '';
|
||||||
|
|
||||||
if (!format) return dayjs(text).format('YYYY-MM-DD HH:mm:ss');
|
return format
|
||||||
else return dayjs(text).format(format);
|
? dayjs(text).format(format)
|
||||||
|
: dayjs(text).format('YYYY-MM-DD HH:mm:ss');
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 渲染字典
|
* 渲染字典
|
||||||
|
@ -107,19 +113,20 @@ export const useRender = {
|
||||||
* @returns 字典标签
|
* @returns 字典标签
|
||||||
*/
|
*/
|
||||||
renderDict: (text: string, dictType: string, params?: any) => {
|
renderDict: (text: string, dictType: string, params?: any) => {
|
||||||
|
debugger;
|
||||||
if (!dictType && !params.options) {
|
if (!dictType && !params.options) {
|
||||||
console.warn('请传入字典类型')
|
console.warn('请传入字典类型');
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
let dict: any[] = [];
|
let dict: any[] = [];
|
||||||
if (dictType) {
|
if (dictType) {
|
||||||
dict = getDictOpts(dictType)
|
dict = getDictOpts(dictType);
|
||||||
}
|
}
|
||||||
if (params && params.options) {
|
if (params && params.options) {
|
||||||
dict = params.options;
|
dict = params.options;
|
||||||
}
|
}
|
||||||
return h(DictTag, { options: dict, value: text, ...params });
|
return h(DictTag, { options: dict, value: text, ...params });
|
||||||
}
|
},
|
||||||
// /**
|
// /**
|
||||||
// * 渲染图标icon
|
// * 渲染图标icon
|
||||||
// * @param text icon
|
// * @param text icon
|
||||||
|
|
|
@ -27,7 +27,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
hideInTab: true,
|
hideInTab: true,
|
||||||
icon: 'lucide:area-chart',
|
icon: 'lucide:area-chart',
|
||||||
title: '立项填报',
|
title: '立项填报',
|
||||||
activePath: '/contract/approval/edit/:id?',
|
activePath: '/supervise/edit/:id?',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +1,69 @@
|
||||||
/** 字典枚举 */
|
/** 字典枚举 */
|
||||||
export enum DICT_TYPE {
|
export enum DICT_TYPE {
|
||||||
|
|
||||||
/** 静态枚举-划分标段 */
|
|
||||||
sectionType = 'section_type',
|
|
||||||
sectionNum = 'section_num',
|
|
||||||
commonWhether = 'common_whether',
|
|
||||||
|
|
||||||
sysNormalDisable = 'sys_normal_disable',
|
|
||||||
// 会议类型
|
|
||||||
meeting_type = 'meeting_type',
|
|
||||||
meeting_facilities = 'meeting_facilities',
|
|
||||||
meeting_room = 'meeting_room',
|
|
||||||
|
|
||||||
// 订餐
|
|
||||||
// 主食
|
|
||||||
canteen_staplefood = 'canteen_staplefood',
|
|
||||||
/** 就餐方式 */
|
/** 就餐方式 */
|
||||||
canteen_dineway = 'canteen_dineway',
|
canteen_dineway = 'canteen_dineway',
|
||||||
|
// 主食
|
||||||
|
canteen_staplefood = 'canteen_staplefood',
|
||||||
canteenTimeRange = 'canteen_time_range',
|
canteenTimeRange = 'canteen_time_range',
|
||||||
officesupplies_status = 'officesupplies_status',
|
|
||||||
|
|
||||||
supervise_task_type = 'supervise_task_type',
|
commonWhether = 'common_whether',
|
||||||
supervise_emergency_level = 'supervise_emergency_level',
|
comprehensiveConfig = 'comprehensive_config',
|
||||||
|
/** 综合管理-项目管理 */
|
||||||
|
comprehensiveProject = 'comprehensive_project',
|
||||||
|
/** 综合管理-项目名称管理 */
|
||||||
|
comprehensiveProjectName = 'comprehensive_project_name',
|
||||||
|
|
||||||
|
// 订餐
|
||||||
|
/** 合同管理-合同审批 */
|
||||||
|
contractApproval = 'contract_approval',
|
||||||
|
/** 合同管理-授权类型 */
|
||||||
|
contractAuthorizationType = 'contract_authorization_type',
|
||||||
|
|
||||||
|
/** 合同管理-签约依据类型 */
|
||||||
|
contractBasisType = 'contract_basis_type',
|
||||||
|
/** 合同管理-币种单位 */
|
||||||
|
contractCurrencyUnit = 'contract_currency_unit',
|
||||||
|
|
||||||
/** 合同管理-资金流向 */
|
/** 合同管理-资金流向 */
|
||||||
contractFundFlow = 'contract_fund_flow',
|
contractFundFlow = 'contract_fund_flow',
|
||||||
|
|
||||||
/** 合同管理-资金渠道 */
|
/** 合同管理-资金渠道 */
|
||||||
contractFundingSource = 'contract_funding_source',
|
contractFundingSource = 'contract_funding_source',
|
||||||
|
|
||||||
/** 合同管理-组织形式 */
|
|
||||||
contractOrganizationForm = 'contract_organization_form',
|
|
||||||
|
|
||||||
/** 合同管理-币种单位 */
|
|
||||||
contractCurrencyUnit = 'contract_currency_unit',
|
|
||||||
|
|
||||||
/** 合同管理-合同模块 */
|
/** 合同管理-合同模块 */
|
||||||
contractModule = 'contract_module',
|
contractModule = 'contract_module',
|
||||||
|
|
||||||
/** 合同管理-选商方式 */
|
/** 合同管理-组织形式 */
|
||||||
contractSelectionMethod = 'contract_selection_method',
|
contractOrganizationForm = 'contract_organization_form',
|
||||||
|
|
||||||
/** 合同管理-合同审批 */
|
|
||||||
contractApproval = 'contract_approval',
|
|
||||||
|
|
||||||
/** 合同管理-履行状态 */
|
/** 合同管理-履行状态 */
|
||||||
contractPerformanceStatus = 'contract_performance_status',
|
contractPerformanceStatus = 'contract_performance_status',
|
||||||
|
|
||||||
/** 合同管理-授权类型 */
|
/** 合同管理-商务计价方式 */
|
||||||
contractAuthorizationType = 'contract_authorization_type',
|
contractPriceStyle = 'contract_price_style',
|
||||||
|
|
||||||
/** 合同管理-项目类型 */
|
/** 合同管理-项目类型 */
|
||||||
contractProjectType = 'contract_project_type',
|
contractProjectType = 'contract_project_type',
|
||||||
|
|
||||||
/** 合同管理-商务计价方式 */
|
/** 合同管理-选商方式 */
|
||||||
contractPriceStyle = 'contract_price_style',
|
contractSelectionMethod = 'contract_selection_method',
|
||||||
|
|
||||||
/** 综合管理-项目管理 */
|
meeting_facilities = 'meeting_facilities',
|
||||||
comprehensiveProject = 'comprehensive_project',
|
|
||||||
|
|
||||||
/** 综合管理-项目名称管理 */
|
meeting_room = 'meeting_room',
|
||||||
comprehensiveProjectName = 'comprehensive_project_name',
|
|
||||||
|
|
||||||
comprehensiveConfig = 'comprehensive_config',
|
// 会议类型
|
||||||
|
meeting_type = 'meeting_type',
|
||||||
|
|
||||||
/** 合同管理-签约依据类型 */
|
officesupplies_status = 'officesupplies_status',
|
||||||
contractBasisType = 'contract_basis_type',
|
|
||||||
|
sectionNum = 'section_num',
|
||||||
|
|
||||||
|
/** 静态枚举-划分标段 */
|
||||||
|
sectionType = 'section_type',
|
||||||
|
|
||||||
|
supervise_emergency_level = 'supervise_emergency_level',
|
||||||
|
|
||||||
|
supervise_task_type = 'supervise_task_type',
|
||||||
|
|
||||||
|
sysNormalDisable = 'sys_normal_disable',
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,33 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
/** 变更原因 */
|
/** 变更原因 */
|
||||||
cancel_reson: [
|
cancel_reson: [
|
||||||
{ label: "未填写原因", value: "0" },
|
{ label: '未填写原因', value: '0' },
|
||||||
{ label: "用户取消", value: "1" },
|
{ label: '用户取消', value: '1' },
|
||||||
{ label: "系统取消", value: "2" },
|
{ label: '系统取消', value: '2' },
|
||||||
{ label: "其他原因", value: "3" }
|
{ label: '其他原因', value: '3' },
|
||||||
],
|
],
|
||||||
|
|
||||||
/** 划分标段 */
|
/** 划分标段 */
|
||||||
section_type: [
|
section_type: [
|
||||||
{ label: "是", value: "1" },
|
{ label: '是', value: '1' },
|
||||||
{ label: "否", value: "0" }
|
{ label: '否', value: '0' },
|
||||||
],
|
],
|
||||||
|
|
||||||
/** 标段数 */
|
/** 标段数 */
|
||||||
section_num: [
|
section_num: [
|
||||||
{ label: "1", value: "1" },
|
{ label: '1', value: '1' },
|
||||||
{ label: "2", value: "2" }, ,
|
{ label: '2', value: '2' },
|
||||||
{ label: "3", value: "3" },
|
{ label: '3', value: '3' },
|
||||||
{ label: "4", value: "4" },
|
{ label: '4', value: '4' },
|
||||||
{ label: "5", value: "5" },
|
{ label: '5', value: '5' },
|
||||||
{ label: "6", value: "6" },
|
{ label: '6', value: '6' },
|
||||||
{ label: "7", value: "7" },
|
{ label: '7', value: '7' },
|
||||||
{ label: "8", value: "8" },
|
{ label: '8', value: '8' },
|
||||||
],
|
],
|
||||||
|
|
||||||
/** 常用是否 */
|
/** 常用是否 */
|
||||||
common_whether: [
|
common_whether: [
|
||||||
{ label: "是", value: "1" },
|
{ label: '是', value: '1' },
|
||||||
{ label: "否", value: "0" }
|
{ label: '否', value: '0' },
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const PrimaryKey = 'guid';
|
||||||
|
|
||||||
|
export function getFormSchema(_params: any = {}) {
|
||||||
|
return [];
|
||||||
|
}
|
|
@ -1,17 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="tsx">
|
||||||
import { nextTick, onMounted, ref } from 'vue';
|
import { computed, nextTick, onMounted, ref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
import { MdiUpload } from '@vben/icons';
|
import { MdiUpload } from '@vben/icons';
|
||||||
import { useUserStore } from '@vben/stores';
|
import { useUserStore } from '@vben/stores';
|
||||||
|
|
||||||
import {
|
import { message, Modal, type UploadChangeParam } from 'ant-design-vue';
|
||||||
message,
|
|
||||||
Modal,
|
|
||||||
type UploadChangeParam,
|
|
||||||
type UploadProps,
|
|
||||||
} from 'ant-design-vue';
|
|
||||||
import { logger } from 'common-utils';
|
import { logger } from 'common-utils';
|
||||||
import dayjs, { Dayjs } from 'dayjs';
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
@ -35,10 +30,13 @@ const form2Ref = ref();
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
|
||||||
|
const currData = ref<any>({});
|
||||||
|
const nodeInfo = ref<any>({});
|
||||||
|
|
||||||
function calculateDaysBetweenTimestamps(timestamp1, timestamp2) {
|
function calculateDaysBetweenTimestamps(timestamp1, timestamp2) {
|
||||||
const date1 = new Date(timestamp1);
|
const date1 = new Date(timestamp1);
|
||||||
const date2 = new Date(timestamp2);
|
const date2 = new Date(timestamp2);
|
||||||
const timeDifference = Math.abs(date2 - date1);
|
const timeDifference = Math.abs(date2.getTime() - date1.getTime());
|
||||||
const daysDifference = timeDifference / (24 * 60 * 60 * 1000);
|
const daysDifference = timeDifference / (24 * 60 * 60 * 1000);
|
||||||
const roundedDaysDifference = Math.round(daysDifference * 2) / 2;
|
const roundedDaysDifference = Math.round(daysDifference * 2) / 2;
|
||||||
return roundedDaysDifference;
|
return roundedDaysDifference;
|
||||||
|
@ -70,6 +68,10 @@ function handleUpdateFormattedValue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const readOnly = computed(() => {
|
||||||
|
return id.value && currData.value.status === 'edit';
|
||||||
|
});
|
||||||
|
|
||||||
const disabledDate = (current: Dayjs) => {
|
const disabledDate = (current: Dayjs) => {
|
||||||
// Can not select days before today and today
|
// Can not select days before today and today
|
||||||
const form = formRef.value.form;
|
const form = formRef.value.form;
|
||||||
|
@ -92,10 +94,18 @@ const formBinding = ref({
|
||||||
// disabledDate: (current) => current && current < dayjs().endOf("day"),
|
// disabledDate: (current) => current && current < dayjs().endOf("day"),
|
||||||
format: 'YYYY-MM-DD HH:mm',
|
format: 'YYYY-MM-DD HH:mm',
|
||||||
valueFormat: 'YYYY-MM-DD HH:mm',
|
valueFormat: 'YYYY-MM-DD HH:mm',
|
||||||
onChange: (e) => {
|
onChange: () => {
|
||||||
handleUpdateFormattedValue();
|
handleUpdateFormattedValue();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
conditionalRender: {
|
||||||
|
match(_context) {
|
||||||
|
return readOnly.value;
|
||||||
|
},
|
||||||
|
render({ form }) {
|
||||||
|
return <span>{form.starttime}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
rules: [{ required: true, message: '请选择出发时间' }],
|
rules: [{ required: true, message: '请选择出发时间' }],
|
||||||
},
|
},
|
||||||
endtime: {
|
endtime: {
|
||||||
|
@ -107,12 +117,20 @@ const formBinding = ref({
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
showTime: { format: 'HH:mm' },
|
showTime: { format: 'HH:mm' },
|
||||||
disabledDate,
|
disabledDate,
|
||||||
onChange: (e) => {
|
onChange: () => {
|
||||||
handleUpdateFormattedValue();
|
handleUpdateFormattedValue();
|
||||||
},
|
},
|
||||||
format: 'YYYY-MM-DD HH:mm',
|
format: 'YYYY-MM-DD HH:mm',
|
||||||
valueFormat: 'YYYY-MM-DD HH:mm',
|
valueFormat: 'YYYY-MM-DD HH:mm',
|
||||||
},
|
},
|
||||||
|
conditionalRender: {
|
||||||
|
match(_context) {
|
||||||
|
return readOnly.value;
|
||||||
|
},
|
||||||
|
render({ form }) {
|
||||||
|
return <span>{form.endtime}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
rules: [{ required: true, message: '请选择结束时间' }],
|
rules: [{ required: true, message: '请选择结束时间' }],
|
||||||
},
|
},
|
||||||
days: {
|
days: {
|
||||||
|
@ -123,6 +141,16 @@ const formBinding = ref({
|
||||||
name: 'a-input-number',
|
name: 'a-input-number',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
min: 0,
|
min: 0,
|
||||||
|
addonAfter: '天',
|
||||||
|
placeholder: '请输入出差天数',
|
||||||
|
},
|
||||||
|
conditionalRender: {
|
||||||
|
match(_context) {
|
||||||
|
return readOnly.value;
|
||||||
|
},
|
||||||
|
render({ form }) {
|
||||||
|
return <span>{form.days} 天</span>;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
place: {
|
place: {
|
||||||
|
@ -134,6 +162,14 @@ const formBinding = ref({
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
props: {},
|
props: {},
|
||||||
},
|
},
|
||||||
|
conditionalRender: {
|
||||||
|
match(_context) {
|
||||||
|
return readOnly.value;
|
||||||
|
},
|
||||||
|
render({ form }) {
|
||||||
|
return <span>{form.place}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
rules: [{ required: true, message: '请输入出差地点' }],
|
rules: [{ required: true, message: '请输入出差地点' }],
|
||||||
},
|
},
|
||||||
reasons: {
|
reasons: {
|
||||||
|
@ -145,6 +181,14 @@ const formBinding = ref({
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
props: {},
|
props: {},
|
||||||
},
|
},
|
||||||
|
conditionalRender: {
|
||||||
|
match(_context) {
|
||||||
|
return readOnly.value;
|
||||||
|
},
|
||||||
|
render({ form }) {
|
||||||
|
return <span>{form.reasons}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
phone: {
|
phone: {
|
||||||
title: '联系方式',
|
title: '联系方式',
|
||||||
|
@ -155,6 +199,14 @@ const formBinding = ref({
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
props: {},
|
props: {},
|
||||||
},
|
},
|
||||||
|
conditionalRender: {
|
||||||
|
match(_context) {
|
||||||
|
return readOnly.value;
|
||||||
|
},
|
||||||
|
render({ form }) {
|
||||||
|
return <span>{form.phone}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
remarks: {
|
remarks: {
|
||||||
title: '备注',
|
title: '备注',
|
||||||
|
@ -165,6 +217,14 @@ const formBinding = ref({
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
props: {},
|
props: {},
|
||||||
},
|
},
|
||||||
|
conditionalRender: {
|
||||||
|
match(_context) {
|
||||||
|
return readOnly.value;
|
||||||
|
},
|
||||||
|
render({ form }) {
|
||||||
|
return <span>{form.remarks}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -181,10 +241,6 @@ const form2Binding = ref({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleBack() {
|
function handleBack() {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
|
@ -208,6 +264,21 @@ const handleChange = (info: UploadChangeParam) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handleDelete() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '是否确认删除该条记录?',
|
||||||
|
okType: 'danger',
|
||||||
|
onOk: async () => {
|
||||||
|
await Apis.ccsq.post_deletes({
|
||||||
|
params: { ids: id.value },
|
||||||
|
});
|
||||||
|
message.success('删除成功');
|
||||||
|
back();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const chooseUserIds = ref([]);
|
const chooseUserIds = ref([]);
|
||||||
|
|
||||||
async function handleChooseUserConfirm(e) {
|
async function handleChooseUserConfirm(e) {
|
||||||
|
@ -215,19 +286,23 @@ async function handleChooseUserConfirm(e) {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
try {
|
try {
|
||||||
// 先查询相关节点信息
|
// 先查询相关节点信息
|
||||||
|
|
||||||
// const nodeInfo = await getNodeInfo(nodeId);
|
// const nodeInfo = await getNodeInfo(nodeId);
|
||||||
chooseUserIds.value = e.map((item) => item.ACCOUNT_ID);
|
chooseUserIds.value = e.map((item) => item.ACCOUNT_ID);
|
||||||
|
if (!nodeInfo.value.variableName) {
|
||||||
|
throw new Error('出差审批节点异常,请稍候再试');
|
||||||
|
}
|
||||||
await Apis.ccsq.post_startWorkFlow({
|
await Apis.ccsq.post_startWorkFlow({
|
||||||
data: {
|
data: {
|
||||||
guid: id.value,
|
guid: id.value,
|
||||||
assigneeList: chooseUserIds.value,
|
variables: {
|
||||||
|
[nodeInfo.value.variableName]: chooseUserIds.value,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
message.success('提交成功');
|
message.success('提交成功');
|
||||||
back();
|
back();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('合同立项提交失败', error);
|
logger.error('出差提交失败', error);
|
||||||
message.error('提交失败,请稍候再试');
|
message.error('提交失败,请稍候再试');
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
@ -238,27 +313,26 @@ async function handleSave() {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await formRef.value.submit();
|
||||||
|
|
||||||
const form = formRef.value.form;
|
const form = formRef.value.form;
|
||||||
// await formRef.value.submit()
|
|
||||||
console.log(formRef.value);
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
form.applyName = userStore.userInfo.gwmc;
|
form.applyName = (userStore.userInfo as any).gwmc;
|
||||||
form.applyId = userStore.userInfo.userId;
|
form.applyId = userStore.userInfo!.userId;
|
||||||
form.applyTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
form.applyTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
|
||||||
console.log(form2Ref.value.form);
|
|
||||||
const fileList = form2Ref.value.form.fileList;
|
const fileList = form2Ref.value.form.fileList;
|
||||||
let files: any = [];
|
let files: any = [];
|
||||||
if (fileList && fileList.length > 0) {
|
if (fileList && fileList.length > 0) {
|
||||||
files = await fileUploader.upload(fileList, { source: 'erp' });
|
files = await fileUploader.upload(fileList, { source: 'erp' });
|
||||||
}
|
}
|
||||||
console.log(files);
|
|
||||||
if (files) {
|
if (files) {
|
||||||
form.fileUuid = (files.map((item) => item.fileUuid) || []).join(',');
|
form.fileUuid = (files.map((item) => item.fileUuid) || []).join(',');
|
||||||
}
|
}
|
||||||
const data = await Apis.ccsq.post_save({ data: form });
|
const data = await Apis.ccsq.post_save({ data: form });
|
||||||
id.value = data.guid;
|
id.value = data.guid;
|
||||||
|
currData.value.status = '已创建';
|
||||||
message.success('保存成功');
|
message.success('保存成功');
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
|
@ -272,16 +346,25 @@ async function handleSave() {
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('提交失败,请稍候再试');
|
message.error('提交失败,请稍候再试');
|
||||||
console.log(error);
|
logger.error('出差申请提交失败', error);
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSubmit() {
|
async function handleSubmit() {
|
||||||
|
await formRef.value.submit();
|
||||||
|
|
||||||
// isLoading.value = true
|
// isLoading.value = true
|
||||||
|
// 先查询相关节点信息
|
||||||
|
let tempNodeInfo = await Apis.ccsq.get_getFlowNodeUserConfig({
|
||||||
|
params: { guid: id.value },
|
||||||
|
});
|
||||||
|
nodeInfo.value = tempNodeInfo = tempNodeInfo.rows[0];
|
||||||
|
|
||||||
chooseUserModalApi.setData({
|
chooseUserModalApi.setData({
|
||||||
title: '选择审批人',
|
title: `选择${tempNodeInfo.name}(${tempNodeInfo.selectMode})`,
|
||||||
|
limitMultipleNum: tempNodeInfo.selectMode === '多选' ? 10 : 1,
|
||||||
userIds: chooseUserIds.value || [],
|
userIds: chooseUserIds.value || [],
|
||||||
});
|
});
|
||||||
chooseUserModalApi.open();
|
chooseUserModalApi.open();
|
||||||
|
@ -289,27 +372,21 @@ function handleSubmit() {
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
console.log(id.value);
|
|
||||||
try {
|
try {
|
||||||
if (id.value) {
|
if (id.value) {
|
||||||
let data = await Apis.ccsq.get_page({ params: { guid: id.value } });
|
let data = await Apis.ccsq.get_page({ params: { guid: id.value } });
|
||||||
data = data.rows[0];
|
data = data.rows[0] || {};
|
||||||
|
currData.value = data;
|
||||||
|
|
||||||
formRef.value.setFormData(data);
|
formRef.value.setFormData(data);
|
||||||
|
|
||||||
if (data.fileUuid) {
|
if (data.fileUuid) {
|
||||||
const files = await fileUploader.select(data.fileUuid);
|
const files = await fileUploader.select(data.fileUuid);
|
||||||
console.log(files);
|
form2Ref.value.setFormData({ fileList: files });
|
||||||
form2Ref.value.setFormData(
|
|
||||||
{
|
|
||||||
fileList: files,
|
|
||||||
},
|
|
||||||
50,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
logger.error('当前出差申请不存在', error);
|
||||||
|
|
||||||
Modal.error({
|
Modal.error({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '当前出差申请不存在',
|
content: '当前出差申请不存在',
|
||||||
|
@ -337,10 +414,28 @@ onMounted(async () => {
|
||||||
|
|
||||||
<a-spin :spinning="isLoading">
|
<a-spin :spinning="isLoading">
|
||||||
<a-space>
|
<a-space>
|
||||||
<vben-button variant="primary" @click="handleSave()">保存</vben-button>
|
<vben-button
|
||||||
<vben-button variant="primary" @click="handleSubmit()">
|
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>
|
||||||
|
@ -356,13 +451,13 @@ onMounted(async () => {
|
||||||
<template #form_fileList="scope">
|
<template #form_fileList="scope">
|
||||||
<a-upload
|
<a-upload
|
||||||
v-model:file-list="scope.form.fileList"
|
v-model:file-list="scope.form.fileList"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="() => false"
|
||||||
:max-count="3"
|
:max-count="3"
|
||||||
accept=".pdf"
|
accept=".pdf"
|
||||||
name="file"
|
name="file"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
<vben-button variant="secondary">
|
<vben-button v-if="!readOnly" variant="secondary">
|
||||||
<MdiUpload />
|
<MdiUpload />
|
||||||
点击上传
|
点击上传
|
||||||
</vben-button>
|
</vben-button>
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
import type { VxeGridPropTypes } from 'vxe-table';
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
import { useRender } from '#/hooks/useRender';
|
|
||||||
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 {
|
||||||
return [
|
return [
|
||||||
{ type: 'radio', width: 40, slots: { radio: 'radio_cell' }, align: 'center', fixed: 'left' },
|
{
|
||||||
|
type: 'radio',
|
||||||
|
width: 40,
|
||||||
|
slots: { radio: 'radio_cell' },
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'left',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'applyTime',
|
field: 'applyTime',
|
||||||
title: '申请日期',
|
title: '申请日期',
|
||||||
|
@ -14,20 +22,32 @@ export function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'status', title: '记录状态', width: 120, slots: {
|
field: 'status',
|
||||||
|
title: '记录状态',
|
||||||
|
width: 120,
|
||||||
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
const statusMap: any = {
|
const statusMap: any = {
|
||||||
'已创建': 'default',
|
已创建: 'default',
|
||||||
'待审核': 'warning',
|
待审核: 'warning',
|
||||||
'已完成': 'success'
|
已完成: 'success',
|
||||||
|
退回: 'error',
|
||||||
};
|
};
|
||||||
return useRender.renderTag(row.status, statusMap[row.status] || 'default');
|
return useRender.renderTag(
|
||||||
}
|
row.status,
|
||||||
}
|
statusMap[row.status] || 'default',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'base',
|
||||||
|
title: '出差时间',
|
||||||
|
width: 200,
|
||||||
|
slots: { default: 'baseSlot' },
|
||||||
},
|
},
|
||||||
{ field: 'base', title: '出差时间', width: 200, slots: { default: 'baseSlot' } },
|
|
||||||
{ field: 'days', title: '出差天数', width: 80 },
|
{ field: 'days', title: '出差天数', width: 80 },
|
||||||
{ field: 'place', title: '出差地点', width: 200, },
|
{ field: 'place', title: '出差地点', width: 200 },
|
||||||
{ field: 'reasons', title: '出差事项', width: 200 },
|
{ field: 'reasons', title: '出差事项', width: 200 },
|
||||||
{ field: 'phone', title: '联系方式', width: 200 },
|
{ field: 'phone', title: '联系方式', width: 200 },
|
||||||
// { field: 'place', title: '出差地点', width: 200, slots: { default: 'ddy' } },
|
// { field: 'place', title: '出差地点', width: 200, slots: { default: 'ddy' } },
|
||||||
|
|
|
@ -1,46 +1,27 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, ref, computed, reactive, onMounted } from 'vue';
|
import { computed, onMounted, reactive, ref } from 'vue';
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { useRouter } from 'vue-router';
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
|
||||||
import {
|
import { Page } from '@vben/common-ui';
|
||||||
type CreateCrudOptionsProps,
|
|
||||||
useColumns,
|
|
||||||
useFormWrapper,
|
|
||||||
useFs,
|
|
||||||
utils,
|
|
||||||
} from '@fast-crud/fast-crud';
|
|
||||||
import {
|
import {
|
||||||
MdiAdd,
|
MdiAdd,
|
||||||
MdiUpdate,
|
|
||||||
MdiDelete,
|
MdiDelete,
|
||||||
MdiExport,
|
MdiExport,
|
||||||
MdiRadioUnchecked,
|
|
||||||
MdiRadioChecked,
|
MdiRadioChecked,
|
||||||
|
MdiRadioUnchecked,
|
||||||
|
MdiUpdate,
|
||||||
} from '@vben/icons';
|
} from '@vben/icons';
|
||||||
import { getColumns } from './crud.tsx';
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
|
||||||
import { getMonthStartAndEnd } from '#/utils/time';
|
|
||||||
import Apis from '#/api';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
import { Modal } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { useRouter } from 'vue-router';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
|
import { getColumns } from './crud.tsx';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const checkedValue = ref('all');
|
|
||||||
const exportSearchParams = ref<any>({
|
|
||||||
daterange: getMonthStartAndEnd(),
|
|
||||||
});
|
|
||||||
const radioStyle = reactive({
|
|
||||||
display: 'flex',
|
|
||||||
height: '30px',
|
|
||||||
lineHeight: '30px',
|
|
||||||
});
|
|
||||||
|
|
||||||
const searchRef = ref();
|
const searchRef = ref();
|
||||||
let isConfirmLoading = ref(false);
|
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
|
@ -77,22 +58,23 @@ function handleAdd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUpdate(row) {
|
function handleUpdate(row) {
|
||||||
router.push('/bussiness-trip/edit/' + row['guid']);
|
router.push(`/bussiness-trip/edit/${row.guid}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete(row) {
|
function handleDelete(row) {
|
||||||
|
if (['待审核'].includes(row.status)) {
|
||||||
|
message.warning('该记录已提交,不能删除');
|
||||||
|
return;
|
||||||
|
}
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '是否确认删除该条记录?',
|
content: '是否确认删除该条记录?',
|
||||||
okType: 'danger',
|
okType: 'danger',
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
await Apis.ccsq.post_deletes({ params: { ids: row['guid'] } });
|
await Apis.ccsq.post_deletes({ params: { ids: row.guid } });
|
||||||
message.success('删除成功');
|
message.success('删除成功');
|
||||||
triggerProxy('reload');
|
triggerProxy('reload');
|
||||||
},
|
},
|
||||||
onCancel() {
|
|
||||||
console.log('Cancel');
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,13 +89,13 @@ function handleExport() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 选中数据 */
|
/** 选中数据 */
|
||||||
const selectRow: ant = computed(() => {
|
const selectRow: any = computed(() => {
|
||||||
return xGridRef.value?.getRadioRecord() || null;
|
return xGridRef.value?.getRadioRecord() || null;
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 单选框选中事件 */
|
/** 单选框选中事件 */
|
||||||
const setSelectRow = (row: ant) => {
|
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 {
|
||||||
xGridRef.value?.setRadioRow(row);
|
xGridRef.value?.setRadioRow(row);
|
||||||
|
@ -139,29 +121,41 @@ const searchForm = ref({
|
||||||
name: 'a-date-picker',
|
name: 'a-date-picker',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
props: {
|
format: 'YYYY-MM-DD',
|
||||||
format: 'YYYY-MM-DD',
|
valueFormat: 'YYYY-MM-DD',
|
||||||
valueFormat: 'YYYY-MM-DD',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
autoSearchTrigger: 'enter',
|
autoSearchTrigger: 'enter',
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
endDate: {
|
endDate: {
|
||||||
title: '截止月份',
|
title: '截止日期',
|
||||||
key: 'endDate',
|
key: 'endDate',
|
||||||
component: {
|
component: {
|
||||||
name: 'a-date-picker',
|
name: 'a-date-picker',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
props: {
|
format: 'YYYY-MM-DD',
|
||||||
format: 'YYYY-MM-DD',
|
valueFormat: 'YYYY-MM-DD',
|
||||||
valueFormat: 'YYYY-MM-DD',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
autoSearchTrigger: 'enter',
|
autoSearchTrigger: 'enter',
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
|
status: {
|
||||||
|
title: '记录状态',
|
||||||
|
key: 'status',
|
||||||
|
component: {
|
||||||
|
name: 'a-select',
|
||||||
|
vModel: 'value',
|
||||||
|
allowClear: true,
|
||||||
|
class: 'min-w-[180px]',
|
||||||
|
options: [
|
||||||
|
{ label: '已创建', value: '已创建' },
|
||||||
|
{ label: '待审核', value: '待审核' },
|
||||||
|
{ label: '退回', value: '退回' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
onSearch(_context: any) {
|
onSearch(_context: any) {
|
||||||
triggerProxy('reload');
|
triggerProxy('reload');
|
||||||
|
@ -171,31 +165,14 @@ const searchForm = ref({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page contentClass="h-full flex flex-col">
|
<Page content-class="h-full flex flex-col">
|
||||||
<SubmitModal
|
<fs-search ref="searchRef" v-bind="searchForm" />
|
||||||
class="w-[600px]"
|
|
||||||
title="选择送审人"
|
|
||||||
:loading="isConfirmLoading"
|
|
||||||
:confirmLoading="isConfirmLoading"
|
|
||||||
>
|
|
||||||
<a-radio-group v-model:value="checkedValue">
|
|
||||||
<a-radio :style="radioStyle" value="all">导出全部</a-radio>
|
|
||||||
<a-radio :style="radioStyle" value="daterange">
|
|
||||||
导出时间范围
|
|
||||||
<div class="ml-2">
|
|
||||||
<a-range-picker
|
|
||||||
v-model:value="exportSearchParams.daterange"
|
|
||||||
format="YYYY-MM-DD"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
</SubmitModal>
|
|
||||||
|
|
||||||
<fs-search ref="searchRef" v-bind="searchForm"> </fs-search>
|
|
||||||
<div class="min-h-300px flex-1">
|
<div class="min-h-300px flex-1">
|
||||||
<vxe-grid ref="xGridRef" v-bind="gridOptions" @cell-click="handleCellClick">
|
<vxe-grid
|
||||||
|
ref="xGridRef"
|
||||||
|
v-bind="gridOptions"
|
||||||
|
@cell-click="handleCellClick"
|
||||||
|
>
|
||||||
<template #toolbar_buttons>
|
<template #toolbar_buttons>
|
||||||
<a-space>
|
<a-space>
|
||||||
<vben-button variant="primary" @click="handleAdd()">
|
<vben-button variant="primary" @click="handleAdd()">
|
||||||
|
@ -203,8 +180,8 @@ const searchForm = ref({
|
||||||
新增
|
新增
|
||||||
</vben-button>
|
</vben-button>
|
||||||
<vben-button
|
<vben-button
|
||||||
|
:disabled="!selectRow || !selectRow.guid"
|
||||||
variant="warning"
|
variant="warning"
|
||||||
:disabled="!selectRow || !selectRow['guid']"
|
|
||||||
@click="handleUpdate(selectRow)"
|
@click="handleUpdate(selectRow)"
|
||||||
>
|
>
|
||||||
<MdiUpdate class="mr-0.5 text-lg" />
|
<MdiUpdate class="mr-0.5 text-lg" />
|
||||||
|
@ -215,8 +192,8 @@ const searchForm = ref({
|
||||||
导出
|
导出
|
||||||
</vben-button>
|
</vben-button>
|
||||||
<vben-button
|
<vben-button
|
||||||
|
:disabled="!selectRow || !selectRow.guid"
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
:disabled="!selectRow || !selectRow['guid']"
|
|
||||||
@click="handleDelete(selectRow)"
|
@click="handleDelete(selectRow)"
|
||||||
>
|
>
|
||||||
<MdiDelete class="mr-0.5 text-lg" />
|
<MdiDelete class="mr-0.5 text-lg" />
|
||||||
|
|
|
@ -1,51 +1,132 @@
|
||||||
import type { VxeGridPropTypes } from 'vxe-table';
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
|
|
||||||
import { useRender } from '#/hooks/useRender';
|
import { useRender } from '#/hooks/useRender';
|
||||||
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 {
|
||||||
let columns: VxeGridPropTypes.Columns = [
|
const columns: VxeGridPropTypes.Columns = [
|
||||||
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
||||||
{
|
{
|
||||||
field: 'applyTime', title: '申请日期', width: 130,
|
field: 'auditTime',
|
||||||
|
title: '申请日期',
|
||||||
|
width: 130,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'status', title: '记录状态', width: 120, slots: {
|
field: 'status',
|
||||||
|
title: '记录状态',
|
||||||
|
width: 120,
|
||||||
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
const statusMap: any = {
|
const statusMap: any = {
|
||||||
'已创建': 'default',
|
已创建: 'default',
|
||||||
'待审核': 'warning',
|
待审核: 'warning',
|
||||||
'已完成': 'success'
|
已完成: 'success',
|
||||||
|
退回: 'error',
|
||||||
};
|
};
|
||||||
return useRender.renderTag(row.status, statusMap[row.status] || 'default');
|
return useRender.renderTag(
|
||||||
}
|
row.status,
|
||||||
}
|
statusMap[row.status] || 'default',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'applyName', title: '出差人员', minWidth: 200,
|
field: 'taskName',
|
||||||
|
title: '任务名称',
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyName',
|
||||||
|
title: '出差人员',
|
||||||
|
minWidth: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'base',
|
||||||
|
title: '出差时间',
|
||||||
|
width: 200,
|
||||||
|
slots: { default: 'baseSlot' },
|
||||||
},
|
},
|
||||||
{ field: 'base', title: '出差时间', width: 200, slots: { default: 'baseSlot' } },
|
|
||||||
{ field: 'days', title: '出差天数', width: 80 },
|
{ field: 'days', title: '出差天数', width: 80 },
|
||||||
{ field: 'place', title: '出差地点', width: 200, },
|
{ field: 'place', title: '出差地点', width: 200 },
|
||||||
{ field: 'reasons', title: '出差事项', width: 200 },
|
{ field: 'reasons', title: '出差事项', width: 200 },
|
||||||
{ field: 'phone', title: '联系方式', width: 200 },
|
{ field: 'phone', title: '联系方式', width: 200 },
|
||||||
{ field: 'remarks', title: '备注', minWidth: 200 },
|
{ field: 'remarks', title: '备注', minWidth: 200 },
|
||||||
]
|
];
|
||||||
|
|
||||||
if (params.todoType === 'todo') {
|
if (params.todoType === 'todo') {
|
||||||
columns.push({
|
columns.push({
|
||||||
field: "operate",
|
field: 'operate',
|
||||||
title: "操作",
|
title: '操作',
|
||||||
width: 110,
|
width: 110,
|
||||||
fixed: "right",
|
fixed: 'right',
|
||||||
slots: { default: "operate" },
|
slots: { default: 'operate' },
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return columns
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDoneColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
|
const columns: VxeGridPropTypes.Columns = [
|
||||||
|
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
||||||
|
{
|
||||||
|
field: 'applyTime',
|
||||||
|
title: '申请日期',
|
||||||
|
width: 130,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
title: '记录状态',
|
||||||
|
width: 120,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
const statusMap: any = {
|
||||||
|
已创建: 'default',
|
||||||
|
待审核: 'warning',
|
||||||
|
已完成: 'success',
|
||||||
|
退回: 'error',
|
||||||
|
};
|
||||||
|
return useRender.renderTag(
|
||||||
|
row.status,
|
||||||
|
statusMap[row.status] || 'default',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'taskName',
|
||||||
|
title: '任务名称',
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyName',
|
||||||
|
title: '出差人员',
|
||||||
|
minWidth: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'base',
|
||||||
|
title: '出差时间',
|
||||||
|
width: 200,
|
||||||
|
slots: { default: 'baseSlot' },
|
||||||
|
},
|
||||||
|
{ field: 'days', title: '出差天数', width: 80 },
|
||||||
|
{ field: 'place', title: '出差地点', width: 200 },
|
||||||
|
{ field: 'reasons', title: '出差事项', width: 200 },
|
||||||
|
{ field: 'phone', title: '联系方式', width: 200 },
|
||||||
|
{ field: 'remarks', title: '备注', minWidth: 200 },
|
||||||
|
{
|
||||||
|
field: 'operate',
|
||||||
|
title: '操作',
|
||||||
|
width: 80,
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'operate' },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFormSchema(_params: any = {}) {
|
export function getFormSchema(_params: any = {}) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, ref, reactive, onMounted, nextTick } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { FsCrud } from '@fast-crud/fast-crud';
|
import { useRouter } from 'vue-router';
|
||||||
import { type VxeGridProps } from 'vxe-table';
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import { logger } from 'common-utils';
|
||||||
|
|
||||||
import { MdiAdd, MdiUpdate, MdiDelete } from '@vben/icons';
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
|
||||||
import { getColumns } from './crud';
|
|
||||||
import Apis from '#/api';
|
import Apis from '#/api';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
import chooseUserModal from '#/views/system/user/choose-user-modal.vue';
|
import chooseUserModal from '#/views/system/user/choose-user-modal.vue';
|
||||||
|
|
||||||
|
import { getColumns, getDoneColumns } from './crud';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const [ChooseUserModal, chooseUserModalApi] = useVbenModal({
|
const [ChooseUserModal, chooseUserModalApi] = useVbenModal({
|
||||||
connectedComponent: chooseUserModal,
|
connectedComponent: chooseUserModal,
|
||||||
});
|
});
|
||||||
|
@ -22,9 +25,21 @@ const { xGridRef: xGrid2Ref, triggerProxy: triggerProxy2 } = useVxeTable({
|
||||||
ref: 'xGrid2Ref',
|
ref: 'xGrid2Ref',
|
||||||
});
|
});
|
||||||
|
|
||||||
let selectRow = ref({});
|
const selectRow = ref<any>({});
|
||||||
|
|
||||||
const treeData = ref([]);
|
const nodeInfo = ref<any>({});
|
||||||
|
const chooseUserIds = ref([]);
|
||||||
|
|
||||||
|
const isLoading = ref(false);
|
||||||
|
|
||||||
|
const title = ref('1');
|
||||||
|
|
||||||
|
const form2Ref = ref();
|
||||||
|
|
||||||
|
const form2Binding = ref({
|
||||||
|
col: { span: 24 },
|
||||||
|
columns: {},
|
||||||
|
});
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
const gridOptions = reactive(
|
const gridOptions = reactive(
|
||||||
|
@ -40,7 +55,6 @@ const gridOptions = reactive(
|
||||||
params: {
|
params: {
|
||||||
pageNum: page.currentPage,
|
pageNum: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
...searchParams,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -60,7 +74,7 @@ const grid2Options = reactive(
|
||||||
gridProps({
|
gridProps({
|
||||||
height: '100%',
|
height: '100%',
|
||||||
size: 'mini',
|
size: 'mini',
|
||||||
columns: getColumns({ todoType: 'done' }),
|
columns: getDoneColumns({ todoType: 'done' }),
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
autoLoad: true,
|
autoLoad: true,
|
||||||
ajax: {
|
ajax: {
|
||||||
|
@ -69,7 +83,6 @@ const grid2Options = reactive(
|
||||||
params: {
|
params: {
|
||||||
pageNum: page.currentPage,
|
pageNum: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
...searchParams,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -84,50 +97,13 @@ const grid2Options = reactive(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const assigneeList = ref([]);
|
||||||
|
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
|
|
||||||
let searchParams = reactive({});
|
const isConfirmLoading = ref(false);
|
||||||
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;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let isConfirmLoading = ref(false);
|
const [TemporaryModal, temporaryModalApi] = useVbenModal({
|
||||||
|
|
||||||
const [TemporaryModalApi, temporaryModalApi] = useVbenModal({
|
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
isConfirmLoading.value = false;
|
isConfirmLoading.value = false;
|
||||||
|
@ -135,24 +111,58 @@ const [TemporaryModalApi, temporaryModalApi] = useVbenModal({
|
||||||
},
|
},
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
// await
|
// await
|
||||||
|
handleAudit(selectRow.value, 'rejectConfirm');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleAudit(row, type) {
|
async function handleAudit(row, type) {
|
||||||
selectRow.value = row;
|
selectRow.value = row;
|
||||||
|
|
||||||
|
// 先查询相关节点信息
|
||||||
|
let tempNodeInfo = await Apis.ccsq.post_getNextNodeUserConfig({
|
||||||
|
params: { taskId: row.taskId },
|
||||||
|
});
|
||||||
|
nodeInfo.value = tempNodeInfo = tempNodeInfo.rows[0];
|
||||||
|
|
||||||
|
chooseUserModalApi.setData({
|
||||||
|
title: `选择${tempNodeInfo.name}(${tempNodeInfo.selectMode})`,
|
||||||
|
limitMultipleNum: tempNodeInfo.selectMode === '多选' ? 10 : 1,
|
||||||
|
userIds: chooseUserIds.value || [],
|
||||||
|
});
|
||||||
|
|
||||||
if (type === 'access') {
|
if (type === 'access') {
|
||||||
chooseUserModalApi.setData({
|
|
||||||
title: '选择审批人',
|
|
||||||
});
|
|
||||||
chooseUserModalApi.open();
|
chooseUserModalApi.open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'accessConfirm') {
|
||||||
|
try {
|
||||||
|
await Apis.ccsq.post_submit({
|
||||||
|
data: {
|
||||||
|
guid: selectRow.value.guid,
|
||||||
|
variables: {
|
||||||
|
[nodeInfo.value.variableName]: assigneeList.value,
|
||||||
|
},
|
||||||
|
comment: '通过',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
message.success('提交成功');
|
||||||
|
triggerProxy('reload');
|
||||||
|
triggerProxy2('reload');
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('出差审批提交失败', error);
|
||||||
|
message.error('提交失败,请稍候再试');
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 'reject') {
|
if (type === 'reject') {
|
||||||
await Apis.ccsq.get_getBackNode({
|
// let tempBackNodeInfo = await Apis.ccsq.get_getBackNode({
|
||||||
params: { taskId: row.taskId },
|
// params: { taskId: row.taskId },
|
||||||
});
|
// });
|
||||||
|
// tempBackNodeInfo = tempBackNodeInfo.rows[0]
|
||||||
|
|
||||||
form2Binding.value.columns = {};
|
form2Binding.value.columns = {};
|
||||||
|
|
||||||
|
@ -161,63 +171,57 @@ async function handleAudit(row, type) {
|
||||||
comment: {
|
comment: {
|
||||||
title: '',
|
title: '',
|
||||||
key: 'comment',
|
key: 'comment',
|
||||||
col: { span: 10 },
|
col: { span: 24 },
|
||||||
colon: false,
|
colon: false,
|
||||||
component: {
|
component: {
|
||||||
name: 'a-time-picker',
|
name: 'a-textarea',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
format: 'HH:mm',
|
autoSize: { minRows: 4, maxRows: 6 },
|
||||||
valueFormat: 'HH:mm',
|
placeholder: '请输入',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
temporaryModalApi.open();
|
temporaryModalApi.open();
|
||||||
nextTick(() => {
|
isConfirmLoading.value = true;
|
||||||
form2Ref.value.setFormData(submitForm.value);
|
}
|
||||||
|
|
||||||
|
if (type === 'rejectConfirm') {
|
||||||
|
await Apis.ccsq.post_rollback({
|
||||||
|
params: {
|
||||||
|
...form2Ref.value.form,
|
||||||
|
guid: selectRow.value.guid,
|
||||||
|
backNodeId: 'userTask_first_node',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
temporaryModalApi.close();
|
||||||
|
isConfirmLoading.value = false;
|
||||||
|
triggerProxy('reload');
|
||||||
|
triggerProxy2('reload');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleChooseUserConfirm(e) {
|
async function handleChooseUserConfirm(e) {
|
||||||
console.log(e);
|
|
||||||
chooseUserModalApi.close();
|
chooseUserModalApi.close();
|
||||||
try {
|
assigneeList.value = e.map((item) => item.ACCOUNT_ID);
|
||||||
await Apis.ccsq.post_submit({
|
handleAudit(selectRow.value, 'accessConfirm');
|
||||||
data: {
|
|
||||||
guid: selectRow.value.guid,
|
|
||||||
assigneeList: e.map((item) => item.ACCOUNT_ID),
|
|
||||||
comment: '通过',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
message.success('提交成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
message.error('提交失败,请稍候再试');
|
|
||||||
} finally {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = ref('1');
|
function toPage(row) {
|
||||||
|
router.push(`/bussiness-trip/edit/${row.guid || row.businessKey}`);
|
||||||
const form2Ref = ref();
|
}
|
||||||
|
|
||||||
const form2Binding = ref({
|
|
||||||
col: { span: 24 },
|
|
||||||
columns: {},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page contentClass="h-full flex flex-col">
|
<Page content-class="h-full flex flex-col">
|
||||||
<TemporaryModal
|
<TemporaryModal
|
||||||
class="w-[400px]"
|
:confirm-loading="isConfirmLoading"
|
||||||
:title="title"
|
|
||||||
contentClass="min-h-0"
|
|
||||||
:loading="isConfirmLoading"
|
:loading="isConfirmLoading"
|
||||||
:confirmLoading="isConfirmLoading"
|
:title="title"
|
||||||
|
class="w-[600px]"
|
||||||
|
content-class="min-h-0"
|
||||||
>
|
>
|
||||||
<fs-form ref="form2Ref" v-bind="form2Binding"> </fs-form>
|
<fs-form ref="form2Ref" v-bind="form2Binding" />
|
||||||
</TemporaryModal>
|
</TemporaryModal>
|
||||||
|
|
||||||
<ChooseUserModal
|
<ChooseUserModal
|
||||||
|
@ -226,12 +230,12 @@ const form2Binding = ref({
|
||||||
@confirm="handleChooseUserConfirm"
|
@confirm="handleChooseUserConfirm"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<a-space direction="vertical" size="small" class="flex h-full flex-col">
|
<a-space class="flex h-full flex-col" direction="vertical" size="small">
|
||||||
<a-card
|
<a-card
|
||||||
title="待办"
|
:body-style="{ flex: '1' }"
|
||||||
size="small"
|
|
||||||
class="flex h-full flex-col"
|
class="flex h-full flex-col"
|
||||||
:bodyStyle="{ flex: '1' }"
|
size="small"
|
||||||
|
title="待办"
|
||||||
>
|
>
|
||||||
<vxe-grid ref="xGridRef" v-bind="gridOptions" class="h-full">
|
<vxe-grid ref="xGridRef" v-bind="gridOptions" class="h-full">
|
||||||
<template #toolbar_buttons> </template>
|
<template #toolbar_buttons> </template>
|
||||||
|
@ -244,16 +248,16 @@ const form2Binding = ref({
|
||||||
<template #operate="{ row }">
|
<template #operate="{ row }">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button
|
<a-button
|
||||||
type="text"
|
|
||||||
size="small"
|
size="small"
|
||||||
|
type="text"
|
||||||
@click="handleAudit(row, 'access')"
|
@click="handleAudit(row, 'access')"
|
||||||
>
|
>
|
||||||
通过
|
通过
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
type="text"
|
|
||||||
danger
|
danger
|
||||||
size="small"
|
size="small"
|
||||||
|
type="text"
|
||||||
@click="handleAudit(row, 'reject')"
|
@click="handleAudit(row, 'reject')"
|
||||||
>
|
>
|
||||||
拒绝
|
拒绝
|
||||||
|
@ -263,10 +267,10 @@ const form2Binding = ref({
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card
|
<a-card
|
||||||
title="已办"
|
:body-style="{ flex: '1' }"
|
||||||
size="small"
|
|
||||||
class="flex h-full flex-col"
|
class="flex h-full flex-col"
|
||||||
:bodyStyle="{ flex: '1' }"
|
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>
|
||||||
|
@ -274,6 +278,14 @@ const form2Binding = ref({
|
||||||
<p>开始时间:{{ row.starttime }}</p>
|
<p>开始时间:{{ row.starttime }}</p>
|
||||||
<p>结束时间:{{ row.endtime }}</p>
|
<p>结束时间:{{ row.endtime }}</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #operate="{ row }">
|
||||||
|
<a-space>
|
||||||
|
<a-button size="small" type="text" @click="toPage(row)">
|
||||||
|
查看
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
|
|
@ -1,78 +1,80 @@
|
||||||
import type { VxeGridPropTypes } from 'vxe-table';
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
import { useRender } from '#/hooks/useRender';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { DICT_TYPE, getDictObj, getDictOptions } from '#/utils/dict';
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
import { unitComponentProps } from '#/common/unit';
|
|
||||||
|
import { useRender } from '#/hooks/useRender';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
||||||
|
|
||||||
export const PrimaryKey = 'guid';
|
export const PrimaryKey = 'guid';
|
||||||
|
|
||||||
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
type: "radio",
|
type: 'radio',
|
||||||
width: 40,
|
width: 40,
|
||||||
slots: { radio: "radio_cell" },
|
slots: { radio: 'radio_cell' },
|
||||||
align: "center",
|
align: 'center',
|
||||||
fixed: "left",
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
{ field: "applyName", title: "申请人", width: 120 },
|
{ field: 'applyName', title: '申请人', width: 120 },
|
||||||
{ field: "officeName", title: "申请物品", minWidth: 150 },
|
{ field: 'officeName', title: '申请物品', minWidth: 150 },
|
||||||
{
|
{
|
||||||
field: "model",
|
field: 'model',
|
||||||
title: "物品型号",
|
title: '物品型号',
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "count",
|
field: 'count',
|
||||||
title: "申请数量",
|
title: '申请数量',
|
||||||
minWidth: 80,
|
minWidth: 80,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return row.count + "个";
|
return `${row.count}个`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: "remarks", title: "申请原因", width: 200 },
|
{ field: 'remarks', title: '申请原因', width: 200 },
|
||||||
{
|
{
|
||||||
field: "status",
|
field: 'status',
|
||||||
title: "申请状态",
|
title: '申请状态',
|
||||||
width: 120,
|
width: 120,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderDict(row.status, DICT_TYPE.officesupplies_status, {
|
return useRender.renderDict(
|
||||||
labelField: "extend1",
|
row.status,
|
||||||
});
|
DICT_TYPE.officesupplies_status,
|
||||||
|
{
|
||||||
|
labelField: 'extend1',
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "companyRealCount",
|
field: 'companyRealCount',
|
||||||
title: "实际发放量",
|
title: '实际发放量',
|
||||||
width: 100,
|
width: 100,
|
||||||
showOverflow: true,
|
showOverflow: true,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.companyRealCount, "个");
|
return useRender.renderText(row.companyRealCount, '个');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: "time", title: "申请时间", width: 150 },
|
{ field: 'time', title: '申请时间', width: 150 },
|
||||||
]
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFormSchema(params: any = {}) {
|
export function getFormSchema(params: any = {}) {
|
||||||
|
const { chooseUserModalApi } = params;
|
||||||
|
|
||||||
const { chooseUserModalApi } = params
|
const data = getDictOptions(DICT_TYPE.officesupplies_status);
|
||||||
|
|
||||||
let data = getDictOptions(DICT_TYPE.officesupplies_status);
|
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
item.label = item.extend1;
|
item.label = item.extend1;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
initialForm: {
|
initialForm: {},
|
||||||
},
|
|
||||||
columns: {
|
columns: {
|
||||||
status: {
|
status: {
|
||||||
title: '申请状态',
|
title: '申请状态',
|
||||||
|
@ -83,8 +85,8 @@ export function getFormSchema(params: any = {}) {
|
||||||
class: 'min-w-[180px]',
|
class: 'min-w-[180px]',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: data
|
data,
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
autoSearchTrigger: 'enter',
|
autoSearchTrigger: 'enter',
|
||||||
show: true,
|
show: true,
|
||||||
|
@ -126,6 +128,5 @@ export function getFormSchema(params: any = {}) {
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,78 +1,173 @@
|
||||||
import type { VxeGridPropTypes } from 'vxe-table';
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
import { useRender } from '#/hooks/useRender';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { DICT_TYPE, getDictObj, getDictOptions } from '#/utils/dict';
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
import { unitComponentProps } from '#/common/unit';
|
|
||||||
|
import { useRender } from '#/hooks/useRender';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
||||||
|
|
||||||
export const PrimaryKey = 'guid';
|
export const PrimaryKey = 'guid';
|
||||||
|
|
||||||
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
return [
|
return [
|
||||||
|
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
||||||
{
|
{
|
||||||
type: "radio",
|
field: 'status',
|
||||||
width: 40,
|
title: '申请状态',
|
||||||
slots: { radio: "radio_cell" },
|
|
||||||
align: "center",
|
|
||||||
fixed: "left",
|
|
||||||
},
|
|
||||||
{ field: "applyName", title: "申请人", width: 120 },
|
|
||||||
{ field: "officeName", title: "申请物品", minWidth: 150 },
|
|
||||||
{
|
|
||||||
field: "model",
|
|
||||||
title: "物品型号",
|
|
||||||
minWidth: 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "count",
|
|
||||||
title: "申请数量",
|
|
||||||
minWidth: 80,
|
|
||||||
slots: {
|
|
||||||
default: ({ row }) => {
|
|
||||||
return row.count + "个";
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ field: "remarks", title: "申请原因", width: 200 },
|
|
||||||
{
|
|
||||||
field: "status",
|
|
||||||
title: "申请状态",
|
|
||||||
width: 120,
|
width: 120,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderDict(row.status, DICT_TYPE.officesupplies_status, {
|
return useRender.renderDict(
|
||||||
labelField: "extend1",
|
row.status,
|
||||||
});
|
DICT_TYPE.officesupplies_status,
|
||||||
|
{
|
||||||
|
labelField: 'extend1',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'applyName', title: '申请人', width: 120 },
|
||||||
|
{ field: 'officeName', title: '申请物品', minWidth: 150 },
|
||||||
|
{
|
||||||
|
field: 'model',
|
||||||
|
title: '物品型号',
|
||||||
|
minWidth: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'count',
|
||||||
|
title: '申请数量',
|
||||||
|
minWidth: 80,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return `${row.count}个`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'remarks', title: '申请原因', width: 200 },
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
title: '申请状态',
|
||||||
|
width: 120,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return useRender.renderDict(
|
||||||
|
row.status,
|
||||||
|
DICT_TYPE.officesupplies_status,
|
||||||
|
{
|
||||||
|
labelField: 'extend1',
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "companyRealCount",
|
field: 'companyRealCount',
|
||||||
title: "实际发放量",
|
title: '实际发放量',
|
||||||
width: 100,
|
width: 100,
|
||||||
showOverflow: true,
|
showOverflow: true,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.companyRealCount, "个");
|
return useRender.renderText(row.companyRealCount, '个');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: "time", title: "申请时间", width: 150 },
|
{ field: 'remarks', title: '申请原因', minWidth: 150 },
|
||||||
]
|
{ field: 'time', title: '申请时间', width: 150 },
|
||||||
|
{
|
||||||
|
field: 'num',
|
||||||
|
title: '审核数量',
|
||||||
|
width: 200,
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'edit_num' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'operate',
|
||||||
|
title: '操作',
|
||||||
|
width: 110,
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'operate' },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDoneColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
|
return [
|
||||||
|
{ type: 'seq', width: 50, align: 'center', fixed: 'left' },
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
title: '申请状态',
|
||||||
|
width: 120,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return useRender.renderDict(
|
||||||
|
row.status,
|
||||||
|
DICT_TYPE.officesupplies_status,
|
||||||
|
{
|
||||||
|
labelField: 'extend1',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'applyName', title: '申请人', width: 120 },
|
||||||
|
{ field: 'officeName', title: '申请物品', minWidth: 150 },
|
||||||
|
{
|
||||||
|
field: 'model',
|
||||||
|
title: '物品型号',
|
||||||
|
minWidth: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'count',
|
||||||
|
title: '申请数量',
|
||||||
|
minWidth: 80,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return `${row.count}个`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'remarks', title: '申请原因', width: 200 },
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
title: '申请状态',
|
||||||
|
width: 120,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return useRender.renderDict(
|
||||||
|
row.status,
|
||||||
|
DICT_TYPE.officesupplies_status,
|
||||||
|
{
|
||||||
|
labelField: 'extend1',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'companyRealCount',
|
||||||
|
title: '实际发放量',
|
||||||
|
width: 100,
|
||||||
|
showOverflow: true,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return useRender.renderText(row.companyRealCount, '个');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'time', title: '申请时间', width: 150 },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFormSchema(params: any = {}) {
|
export function getFormSchema(params: any = {}) {
|
||||||
|
const { chooseUserModalApi } = params;
|
||||||
|
|
||||||
const { chooseUserModalApi } = params
|
const data = getDictOptions(DICT_TYPE.officesupplies_status);
|
||||||
|
|
||||||
let data = getDictOptions(DICT_TYPE.officesupplies_status);
|
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
item.label = item.extend1;
|
item.label = item.extend1;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
initialForm: {
|
initialForm: {},
|
||||||
},
|
|
||||||
columns: {
|
columns: {
|
||||||
status: {
|
status: {
|
||||||
title: '申请状态',
|
title: '申请状态',
|
||||||
|
@ -83,8 +178,8 @@ export function getFormSchema(params: any = {}) {
|
||||||
class: 'min-w-[180px]',
|
class: 'min-w-[180px]',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: data
|
data,
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
autoSearchTrigger: 'enter',
|
autoSearchTrigger: 'enter',
|
||||||
show: true,
|
show: true,
|
||||||
|
@ -126,6 +221,5 @@ export function getFormSchema(params: any = {}) {
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,251 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
|
import { getColumns, getDoneColumns } from './crud.tsx';
|
||||||
|
|
||||||
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
|
const { xGridRef: xGrid2Ref, triggerProxy: triggerProxy2 } = useVxeTable({
|
||||||
|
ref: 'xGrid2Ref',
|
||||||
|
});
|
||||||
|
|
||||||
|
const title = ref('1');
|
||||||
|
const form2Ref = ref();
|
||||||
|
|
||||||
|
const form2Binding = ref({
|
||||||
|
col: { span: 24 },
|
||||||
|
columns: {},
|
||||||
|
});
|
||||||
|
const isConfirmLoading = ref(false);
|
||||||
|
const selectRow = ref<any>({});
|
||||||
|
|
||||||
|
const [TemporaryModal, temporaryModalApi] = useVbenModal({
|
||||||
|
onOpenChange(isOpen: boolean) {
|
||||||
|
if (isOpen) {
|
||||||
|
isConfirmLoading.value = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onConfirm() {
|
||||||
|
// await
|
||||||
|
handleAudit(selectRow.value, 'rejectConfirm');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/** Hooks - 表格 */
|
||||||
|
const gridOptions = reactive(
|
||||||
|
gridProps({
|
||||||
|
height: '100%',
|
||||||
|
columns: getColumns(),
|
||||||
|
proxyConfig: {
|
||||||
|
autoLoad: true,
|
||||||
|
ajax: {
|
||||||
|
query: ({ page }) => {
|
||||||
|
return Apis.officeSuppliesApply.get_page({
|
||||||
|
params: { pageNum: page.currentPage, pageSize: page.pageSize },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Hooks - 表格 */
|
||||||
|
const grid2Options = reactive(
|
||||||
|
gridProps({
|
||||||
|
height: '100%',
|
||||||
|
columns: getDoneColumns(),
|
||||||
|
proxyConfig: {
|
||||||
|
autoLoad: true,
|
||||||
|
ajax: {
|
||||||
|
query: ({ page }) => {
|
||||||
|
return Apis.officeSuppliesApply.get_page({
|
||||||
|
params: {
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
status: 'officeSuppliesAudit',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
async function handleAudit(
|
||||||
|
row: any,
|
||||||
|
type: 'access' | 'reject' | 'rejectConfirm',
|
||||||
|
) {
|
||||||
|
selectRow.value = row;
|
||||||
|
|
||||||
|
let form = {
|
||||||
|
guid: row.guid,
|
||||||
|
status: '', // departmentAudit
|
||||||
|
unitCount: null,
|
||||||
|
companyApprovalCount: null,
|
||||||
|
companyRealCount: null,
|
||||||
|
flag: '',
|
||||||
|
};
|
||||||
|
// console.log(row);
|
||||||
|
// if (row.status === 'start') {
|
||||||
|
// form.status = 'departmentAudit';
|
||||||
|
// form.unitCount = row.num;
|
||||||
|
// }
|
||||||
|
// if (row.status === 'departmentAudit') {
|
||||||
|
// form.status = 'officeAudit';
|
||||||
|
// form.companyApprovalCount = row.num;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (row.status === 'officeAudit') {
|
||||||
|
// form.status = 'officeSuppliesAudit';
|
||||||
|
// form.companyRealCount = row.num;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (row.status === 'officeSuppliesAudit') {
|
||||||
|
// form.status = 'end';
|
||||||
|
// }
|
||||||
|
|
||||||
|
form.status = row.status;
|
||||||
|
form.unitCount = row.num;
|
||||||
|
form.companyApprovalCount = row.num;
|
||||||
|
form.companyRealCount = row.num;
|
||||||
|
|
||||||
|
console.log('审批表单', form);
|
||||||
|
if (
|
||||||
|
type === 'access' &&
|
||||||
|
!form.unitCount &&
|
||||||
|
!form.companyApprovalCount &&
|
||||||
|
!form.companyRealCount
|
||||||
|
) {
|
||||||
|
message.error('请输入审核或发放数量');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
form = { ...row, ...form };
|
||||||
|
|
||||||
|
if (type === 'reject') {
|
||||||
|
form.status = 'start';
|
||||||
|
form2Binding.value.columns = {};
|
||||||
|
title.value = '审核拒绝';
|
||||||
|
form2Binding.value.columns = {
|
||||||
|
comment: {
|
||||||
|
title: '',
|
||||||
|
key: 'comment',
|
||||||
|
col: { span: 24 },
|
||||||
|
colon: false,
|
||||||
|
component: {
|
||||||
|
name: 'a-textarea',
|
||||||
|
vModel: 'value',
|
||||||
|
autoSize: { minRows: 4, maxRows: 6 },
|
||||||
|
placeholder: '请输入',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
temporaryModalApi.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'rejectConfirm') {
|
||||||
|
form.flag = 'rollback';
|
||||||
|
await Apis.officeSuppliesApply.post_audit({
|
||||||
|
data: [form, ...form2Ref.value.form],
|
||||||
|
});
|
||||||
|
message.success('操作成功');
|
||||||
|
triggerProxy('reload');
|
||||||
|
triggerProxy2('reload');
|
||||||
|
row.num = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'access') {
|
||||||
|
form.flag = 'submit';
|
||||||
|
await Apis.officeSuppliesApply.post_audit({ data: [form] });
|
||||||
|
message.success('操作成功');
|
||||||
|
triggerProxy('reload');
|
||||||
|
triggerProxy2('reload');
|
||||||
|
row.num = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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">
|
<TemporaryModal
|
||||||
<a-card title="待办" size="small">
|
:confirm-loading="isConfirmLoading"
|
||||||
|
:loading="isConfirmLoading"
|
||||||
|
:title="title"
|
||||||
|
class="w-[600px]"
|
||||||
|
content-class="min-h-0"
|
||||||
|
>
|
||||||
|
<fs-form ref="form2Ref" v-bind="form2Binding" />
|
||||||
|
</TemporaryModal>
|
||||||
|
|
||||||
|
<a-space class="flex h-full flex-col" direction="vertical" 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>
|
||||||
|
|
||||||
|
<template #edit_num="{ row }">
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="row.num"
|
||||||
|
:addon-after="row.units || '个'"
|
||||||
|
:min="1"
|
||||||
|
placeholder="审核数量"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #operate="{ row }">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="handleAudit(row, 'access')"
|
||||||
|
>
|
||||||
|
通过
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
danger
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="handleAudit(row, 'reject')"
|
||||||
|
>
|
||||||
|
拒绝
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</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,60 +254,8 @@
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<style scoped>
|
||||||
import { defineComponent, ref, reactive, onMounted } from 'vue';
|
:deep(.ant-space-item) {
|
||||||
import { type VxeGridProps } from 'vxe-table'
|
flex: 1;
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
}
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
</style>
|
||||||
|
|
||||||
import Apis from '#/api'
|
|
||||||
import { getColumns } from './crud.tsx';
|
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
|
||||||
|
|
||||||
const { xGridRef:xGrid2Ref, triggerProxy:triggerProxy2 } = useVxeTable({ ref: 'xGrid2Ref' });
|
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
|
||||||
const gridOptions = reactive(gridProps({
|
|
||||||
columns: getColumns(),
|
|
||||||
proxyConfig: {
|
|
||||||
autoLoad: true,
|
|
||||||
ajax: {
|
|
||||||
query: ({ page }) => {
|
|
||||||
return Apis.officeSuppliesApply.get_page({ params: { pageNum: page.currentPage, pageSize: page.pageSize, } })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pagerConfig: {
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
toolbarConfig: {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
|
||||||
const grid2Options = reactive(gridProps({
|
|
||||||
columns: getColumns(),
|
|
||||||
proxyConfig: {
|
|
||||||
autoLoad: true,
|
|
||||||
ajax: {
|
|
||||||
query: ({ page }) => {
|
|
||||||
return Apis.ccsq.get_donePage({ params: { pageNum: page.currentPage, pageSize: page.pageSize, } })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pagerConfig: {
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
toolbarConfig: {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
|
@ -1,82 +1,79 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from "vue";
|
import type { VxeGridPropTypes, VxeTablePropTypes } from 'vxe-table';
|
||||||
import { useVbenModal } from "@vben/common-ui";
|
|
||||||
import { message } from "ant-design-vue";
|
import { reactive, ref } from 'vue';
|
||||||
import { useVxeTable } from "#/hooks/vxeTable";
|
|
||||||
import type { VxeGridPropTypes, VxeTablePropTypes } from "vxe-table";
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import Apis from "#/api";
|
import { MdiExport } from '@vben/icons';
|
||||||
import { useRender } from "#/hooks/useRender";
|
|
||||||
import { MdiExport } from "@vben/icons";
|
import { message, Modal } from 'ant-design-vue';
|
||||||
import { Modal } from "ant-design-vue";
|
import Big from 'big.js';
|
||||||
import { getUnitData } from "#/common/unit";
|
|
||||||
import Big from "big.js";
|
import Apis from '#/api';
|
||||||
|
import { getUnitData } from '#/common/unit';
|
||||||
|
import { useRender } from '#/hooks/useRender';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "success"): void;
|
(e: 'confirm', row: any[]): any[];
|
||||||
(e: "rowClick", row: any): any;
|
(e: 'rowClick', row: any): any;
|
||||||
(e: "confirm", row: any[]): any[];
|
(e: 'success'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: "xGridRef" });
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
let isConfirmLoading = ref(false);
|
const isConfirmLoading = ref(false);
|
||||||
|
|
||||||
let unitId = ref();
|
const unitId = ref();
|
||||||
|
|
||||||
let treeData = ref<any>([])
|
const treeData = ref<any>([]);
|
||||||
|
|
||||||
const data = ref({
|
const data = ref({
|
||||||
userIds: [],
|
userIds: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const activeKey = ref('1');
|
|
||||||
const searchRef = ref()
|
|
||||||
|
|
||||||
const idToNameMap = ref<any>({});
|
|
||||||
|
|
||||||
function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||||
return [
|
return [
|
||||||
{ type: "seq", width: 50, fixed: "left" },
|
{ type: 'seq', width: 50, fixed: 'left' },
|
||||||
{
|
{
|
||||||
field: "officeName",
|
field: 'officeName',
|
||||||
title: "办公用名称",
|
title: '办公用名称',
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
if (row.model) {
|
if (row.model) {
|
||||||
return useRender.renderText(row.officeName, "(" + row.model + ")");
|
return useRender.renderText(row.officeName, `(${row.model})`);
|
||||||
}
|
}
|
||||||
return useRender.renderText(row.officeName, "");
|
return useRender.renderText(row.officeName, '');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "count",
|
field: 'count',
|
||||||
title: "采购数量",
|
title: '采购数量',
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.count, row.units || "个");
|
return useRender.renderText(row.count, row.units || '个');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "price",
|
field: 'price',
|
||||||
title: "单价",
|
title: '单价',
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.price, "元");
|
return useRender.renderText(row.price, '元');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "priceSum",
|
field: 'priceSum',
|
||||||
title: "预计花费",
|
title: '预计花费',
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.priceSum, "元");
|
return useRender.renderText(row.priceSum, '元');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -86,52 +83,57 @@ function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
const gridOptions = reactive(
|
const gridOptions = reactive(
|
||||||
gridProps({
|
gridProps({
|
||||||
height: "500px",
|
height: '500px',
|
||||||
columns: getColumns(),
|
columns: getColumns(),
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
autoLoad: true,
|
autoLoad: true,
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }) => {
|
query: async ({ page }) => {
|
||||||
|
const data = await Apis.officeSuppliesApplySum.get_list({
|
||||||
let data = await Apis.officeSuppliesApplySum.get_list({
|
|
||||||
params: {
|
params: {
|
||||||
pageNum: page.currentPage, pageSize: page.pageSize,
|
pageNum: page.currentPage,
|
||||||
unitId: unitId.value
|
pageSize: page.pageSize,
|
||||||
}
|
unitId: unitId.value,
|
||||||
})
|
},
|
||||||
data.rows.forEach((item) => {
|
|
||||||
item.priceSum = Big(item.price||0).times(item.count||0).toNumber();
|
|
||||||
});
|
});
|
||||||
return data
|
data.rows.forEach((item) => {
|
||||||
}
|
item.priceSum = Big(item.price || 0)
|
||||||
}
|
.times(item.count || 0)
|
||||||
|
.toNumber();
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
showFooter: true,
|
showFooter: true,
|
||||||
pagerConfig: {
|
pagerConfig: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
footerMethod: (e) => footerMethod(e),
|
footerMethod: (e) => footerMethod(e),
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格计算规则
|
* 表格计算规则
|
||||||
* @param param0
|
* @param param0
|
||||||
*/
|
*/
|
||||||
const footerMethod: VxeTablePropTypes.FooterMethod<any> = ({ columns, data }) => {
|
const footerMethod: VxeTablePropTypes.FooterMethod<any> = ({
|
||||||
|
columns,
|
||||||
|
data,
|
||||||
|
}) => {
|
||||||
const footerData = [
|
const footerData = [
|
||||||
columns.map((column, _columnIndex) => {
|
columns.map((column, _columnIndex) => {
|
||||||
if (_columnIndex === 0) {
|
if (_columnIndex === 0) {
|
||||||
return "总价";
|
return '总价';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (["priceSum"].includes(column.field)) {
|
if (['priceSum'].includes(column.field)) {
|
||||||
return sumNum(data, column.field) + " 元";
|
return `${sumNum(data, column.field)} 元`;
|
||||||
}
|
}
|
||||||
// if (['tradeType', 'companyName'].includes(column.field)) {
|
// if (['tradeType', 'companyName'].includes(column.field)) {
|
||||||
// return '';
|
// return '';
|
||||||
// }
|
// }
|
||||||
return "";
|
return '';
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
return footerData;
|
return footerData;
|
||||||
|
@ -145,7 +147,7 @@ const footerMethod: VxeTablePropTypes.FooterMethod<any> = ({ columns, data }) =>
|
||||||
const sumNum = (list: any[], field: string) => {
|
const sumNum = (list: any[], field: string) => {
|
||||||
let count = null;
|
let count = null;
|
||||||
list.forEach((item) => {
|
list.forEach((item) => {
|
||||||
if (typeof item[field] == "number") {
|
if (typeof item[field] === 'number') {
|
||||||
if (count == null) {
|
if (count == null) {
|
||||||
count = new Big(0);
|
count = new Big(0);
|
||||||
}
|
}
|
||||||
|
@ -155,7 +157,6 @@ const sumNum = (list: any[], field: string) => {
|
||||||
return count;
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 办公用品批量选择确认事件
|
* 办公用品批量选择确认事件
|
||||||
* @param rows
|
* @param rows
|
||||||
|
@ -163,13 +164,13 @@ const sumNum = (list: any[], field: string) => {
|
||||||
function handleChooseOfficeConfirm(rows) {
|
function handleChooseOfficeConfirm(rows) {
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
row.count = 1;
|
row.count = 1;
|
||||||
row.remarks = "";
|
row.remarks = '';
|
||||||
}
|
}
|
||||||
const $grid = xGridRef.value;
|
const $grid = xGridRef.value;
|
||||||
// 判断上一个新增项有无完成,未完成则不允许新增
|
// 判断上一个新增项有无完成,未完成则不允许新增
|
||||||
if ($grid) {
|
if ($grid) {
|
||||||
$grid.remove();
|
$grid.remove();
|
||||||
$grid.insert(rows).then(({ row }) => { });
|
$grid.insert(rows).then(({ row }) => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,42 +178,41 @@ function handleExport() {
|
||||||
const $grid = xGridRef.value;
|
const $grid = xGridRef.value;
|
||||||
if ($grid) {
|
if ($grid) {
|
||||||
$grid.exportData({
|
$grid.exportData({
|
||||||
type: "xlsx",
|
type: 'xlsx',
|
||||||
});
|
});
|
||||||
message.success("导出成功");
|
message.success('导出成功');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const [BaseModal, baseModalApi] = useVbenModal({
|
const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
async onOpenChange(isOpen: boolean) {
|
async onOpenChange(isOpen: boolean) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
isConfirmLoading.value = false
|
isConfirmLoading.value = false;
|
||||||
|
|
||||||
treeData.value = await getUnitData()
|
treeData.value = await getUnitData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onConfirm() {
|
onConfirm() {
|
||||||
try {
|
try {
|
||||||
isConfirmLoading.value = true
|
isConfirmLoading.value = true;
|
||||||
const res = xGridRef.value?.getTableData();
|
const res = xGridRef.value?.getTableData();
|
||||||
const data = res?.fullData || [];
|
const data = res?.fullData || [];
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
item.officeName = item.name || "";
|
item.officeName = item.name || '';
|
||||||
});
|
});
|
||||||
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: "提示",
|
title: '提示',
|
||||||
content: `是否确认入库以上办公用品?`,
|
content: `是否确认入库以上办公用品?`,
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
try {
|
try {
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
item.status = "in";
|
item.status = 'in';
|
||||||
});
|
});
|
||||||
await Apis.inOrOut.post_saveBatch({ data: data });
|
await Apis.inOrOut.post_saveBatch({ data });
|
||||||
emit("success");
|
emit('success');
|
||||||
baseModalApi.close();
|
baseModalApi.close();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -220,7 +220,7 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
isConfirmLoading.value = false
|
isConfirmLoading.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -230,12 +230,16 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BaseModal :title="'办公用品审批通过的采购汇总单'" :showConfirmButton="false" cancelText="关闭">
|
<BaseModal
|
||||||
<div class="h-full flex flex-col">
|
:show-confirm-button="false"
|
||||||
|
cancel-text="关闭"
|
||||||
|
title="办公用品审批通过的采购汇总单"
|
||||||
|
>
|
||||||
|
<div class="flex h-full flex-col">
|
||||||
<VxeGrid ref="xGridRef" v-bind="gridOptions">
|
<VxeGrid ref="xGridRef" v-bind="gridOptions">
|
||||||
<template #toolbar_buttons>
|
<template #toolbar_buttons>
|
||||||
<vben-button variant="primary" @click="handleExport()">
|
<vben-button variant="primary" @click="handleExport()">
|
||||||
<MdiExport class="text-lg mr-0.5" />
|
<MdiExport class="mr-0.5 text-lg" />
|
||||||
导出
|
导出
|
||||||
</vben-button>
|
</vben-button>
|
||||||
<!-- <a-tree-select v-model:value="unitId" show-search style="width: 200px"
|
<!-- <a-tree-select v-model:value="unitId" show-search style="width: 200px"
|
||||||
|
@ -255,7 +259,9 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
|
|
||||||
<template #supplies_default_slot="scope">
|
<template #supplies_default_slot="scope">
|
||||||
<div>
|
<div>
|
||||||
{{ scope.row.name ? scope.row.name + "(" + scope.row.model + ")" : "" }}
|
{{
|
||||||
|
scope.row.name ? `${scope.row.name}(${scope.row.model})` : ''
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</VxeGrid>
|
</VxeGrid>
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, ref } from "vue";
|
import { nextTick, ref } from 'vue';
|
||||||
import { useVbenModal } from "@vben/common-ui";
|
|
||||||
import Apis from "#/api";
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import { message } from "ant-design-vue";
|
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "success"): void;
|
(e: 'success'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
let isConfirmLoading = ref(false);
|
const isConfirmLoading = ref(false);
|
||||||
|
|
||||||
const data = ref({
|
const data = ref({
|
||||||
isUpdate: false,
|
isUpdate: false,
|
||||||
|
@ -18,63 +21,60 @@ const formRef = ref();
|
||||||
|
|
||||||
const formBinding = ref({
|
const formBinding = ref({
|
||||||
col: { span: 24 },
|
col: { span: 24 },
|
||||||
labelCol: { style: { width: "120px" } },
|
labelCol: { style: { width: '120px' } },
|
||||||
initialForm: {},
|
initialForm: {},
|
||||||
columns: {
|
columns: {
|
||||||
name: {
|
name: {
|
||||||
title: "用品名称",
|
title: '用品名称',
|
||||||
key: "name",
|
key: 'name',
|
||||||
component: {
|
component: {
|
||||||
name: "a-input",
|
name: 'a-input',
|
||||||
vModel: "value",
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: "请输入办公用品名称" }],
|
rules: [{ required: true, message: '请输入办公用品名称' }],
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
title: "型号",
|
title: '型号',
|
||||||
key: "model",
|
key: 'model',
|
||||||
component: {
|
component: {
|
||||||
name: "a-input",
|
name: 'a-input',
|
||||||
vModel: "value",
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
qualityStandard: {
|
qualityStandard: {
|
||||||
title: "质量标准",
|
title: '质量标准',
|
||||||
key: "qualityStandard",
|
key: 'qualityStandard',
|
||||||
component: {
|
component: {
|
||||||
name: "a-input",
|
name: 'a-input',
|
||||||
vModel: "value",
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
price: {
|
price: {
|
||||||
title: "单价",
|
title: '单价',
|
||||||
key: "price",
|
key: 'price',
|
||||||
component: {
|
component: {
|
||||||
name: "a-input-number",
|
name: 'a-input-number',
|
||||||
vModel: "value",
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
min: 0,
|
min: 0,
|
||||||
addonAfter: "元",
|
addonAfter: '元',
|
||||||
placeholder: "请输入办公用品单价",
|
placeholder: '请输入办公用品单价',
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: "请输入办公用品单价" }],
|
rules: [{ required: true, message: '请输入办公用品单价' }],
|
||||||
},
|
},
|
||||||
remarks: {
|
remarks: {
|
||||||
title: "备注",
|
title: '备注',
|
||||||
key: "remarks",
|
key: 'remarks',
|
||||||
component: {
|
component: {
|
||||||
name: "a-textarea",
|
name: 'a-textarea',
|
||||||
vModel: "value",
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
doSubmit(context: any) {
|
|
||||||
console.log(context);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
@ -90,19 +90,19 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
console.info("onConfirm");
|
console.info('onConfirm');
|
||||||
try {
|
try {
|
||||||
await formRef.value!.submit();
|
await formRef.value!.submit();
|
||||||
isConfirmLoading.value = true;
|
isConfirmLoading.value = true;
|
||||||
|
|
||||||
let form = formRef.value!.form;
|
const form = formRef.value!.form;
|
||||||
await Apis.officeSuppliesList.post_saveBatch({ data: [form] });
|
await Apis.officeSuppliesList.post_saveBatch({ data: [form] });
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
message.success("保存成功");
|
message.success('保存成功');
|
||||||
emit("success");
|
emit('success');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
message.error("保存失败");
|
message.error('保存失败');
|
||||||
} finally {
|
} finally {
|
||||||
isConfirmLoading.value = false;
|
isConfirmLoading.value = false;
|
||||||
}
|
}
|
||||||
|
@ -114,10 +114,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
:title="data.isUpdate ? '编辑办公用品' : '新增办公用品'"
|
|
||||||
:loading="isConfirmLoading"
|
|
||||||
:confirm-loading="isConfirmLoading"
|
:confirm-loading="isConfirmLoading"
|
||||||
|
:loading="isConfirmLoading"
|
||||||
|
:title="data.isUpdate ? '编辑办公用品' : '新增办公用品'"
|
||||||
>
|
>
|
||||||
<fs-form ref="formRef" v-bind="formBinding"> </fs-form>
|
<fs-form ref="formRef" v-bind="formBinding" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,101 +1,107 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from "vue";
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
import { useVbenModal } from "@vben/common-ui";
|
|
||||||
import { message } from "ant-design-vue";
|
import { reactive, ref } from 'vue';
|
||||||
import { useVxeTable } from "#/hooks/vxeTable";
|
|
||||||
import type { VxeGridPropTypes } from "vxe-table";
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import Apis from "#/api";
|
|
||||||
import { useRender } from "#/hooks/useRender";
|
import { Modal } from 'ant-design-vue';
|
||||||
import { MdiAdd } from "@vben/icons";
|
|
||||||
import { Modal } from "ant-design-vue";
|
import Apis from '#/api';
|
||||||
import { getUnitData } from "#/common/unit";
|
import { getUnitData } from '#/common/unit';
|
||||||
import chooseOfficeModal from "../inventory/choose-office-modal.vue";
|
import { useRender } from '#/hooks/useRender';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
|
import chooseOfficeModal from '../inventory/choose-office-modal.vue';
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'confirm', row: any[]): any[];
|
||||||
|
(e: 'rowClick', row: any): any;
|
||||||
|
(e: 'success'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
const [ChooseOfficeModal, chooseOfficeModalApi] = useVbenModal({
|
const [ChooseOfficeModal, chooseOfficeModalApi] = useVbenModal({
|
||||||
connectedComponent: chooseOfficeModal,
|
connectedComponent: chooseOfficeModal,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
(e: "success"): void;
|
|
||||||
(e: "rowClick", row: any): any;
|
|
||||||
(e: "confirm", row: any[]): any[];
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: "xGridRef" });
|
const isConfirmLoading = ref(false);
|
||||||
|
|
||||||
let isConfirmLoading = ref(false);
|
const unitId = ref();
|
||||||
|
|
||||||
let unitId = ref();
|
const treeData = ref<any>([]);
|
||||||
|
|
||||||
let treeData = ref<any>([])
|
|
||||||
|
|
||||||
const data = ref({
|
const data = ref({
|
||||||
userIds: [],
|
userIds: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const activeKey = ref('1');
|
const activeKey = ref('1');
|
||||||
const searchRef = ref()
|
const searchRef = ref();
|
||||||
|
|
||||||
const idToNameMap = ref<any>({});
|
const idToNameMap = ref<any>({});
|
||||||
|
|
||||||
function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||||
return [
|
return [
|
||||||
{ type: "seq", width: 50, fixed: "left" },
|
{ type: 'seq', width: 50, fixed: 'left' },
|
||||||
{ field: "applyName", title: "申请人", width: 120 },
|
{ field: 'applyName', title: '申请人', width: 120 },
|
||||||
{
|
{
|
||||||
field: "applyInfo",
|
field: 'applyInfo',
|
||||||
title: "申请信息",
|
title: '申请信息',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
slots: { default: "applyInfoSlot" },
|
slots: { default: 'applyInfoSlot' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "count",
|
field: 'count',
|
||||||
title: "申请数量",
|
title: '申请数量',
|
||||||
width: 100,
|
width: 100,
|
||||||
showOverflow: true,
|
showOverflow: true,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.count, row.units || "个");
|
return useRender.renderText(row.count, row.units || '个');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "unitCount",
|
field: 'unitCount',
|
||||||
title: "部门审核量",
|
title: '部门审核量',
|
||||||
width: 100,
|
width: 100,
|
||||||
showOverflow: true,
|
showOverflow: true,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.unitCount, row.units || "个");
|
return useRender.renderText(row.unitCount, row.units || '个');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "companyApprovalCount",
|
field: 'companyApprovalCount',
|
||||||
title: "办公室审核量",
|
title: '办公室审核量',
|
||||||
width: 100,
|
width: 100,
|
||||||
showOverflow: true,
|
showOverflow: true,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderText(row.companyApprovalCount, row.units || "个");
|
return useRender.renderText(
|
||||||
|
row.companyApprovalCount,
|
||||||
|
row.units || '个',
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: "remarks", title: "申请原因", minWidth: 150 },
|
{ field: 'remarks', title: '申请原因', minWidth: 150 },
|
||||||
{ field: "time", title: "申请时间", width: 150 },
|
{ field: 'time', title: '申请时间', width: 150 },
|
||||||
{
|
{
|
||||||
field: "num",
|
field: 'num',
|
||||||
title: "发放数量",
|
title: '发放数量',
|
||||||
width: 150,
|
width: 100,
|
||||||
fixed: "right",
|
fixed: 'right',
|
||||||
slots: { default: "edit_num" },
|
slots: { default: 'edit_num' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "operate",
|
field: 'operate',
|
||||||
title: "操作",
|
title: '操作',
|
||||||
width: 120,
|
width: 120,
|
||||||
fixed: "right",
|
fixed: 'right',
|
||||||
slots: { default: "operate" },
|
slots: { default: 'operate' },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -103,7 +109,7 @@ function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
const gridOptions = reactive(
|
const gridOptions = reactive(
|
||||||
gridProps({
|
gridProps({
|
||||||
height: "500px",
|
height: '500px',
|
||||||
columns: getColumns(),
|
columns: getColumns(),
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
autoLoad: true,
|
autoLoad: true,
|
||||||
|
@ -111,21 +117,22 @@ const gridOptions = reactive(
|
||||||
query: ({ page }) => {
|
query: ({ page }) => {
|
||||||
return Apis.officeSuppliesApply.get_page({
|
return Apis.officeSuppliesApply.get_page({
|
||||||
params: {
|
params: {
|
||||||
pageNum: page.currentPage, pageSize: page.pageSize,
|
pageNum: page.currentPage,
|
||||||
unitId: unitId.value
|
pageSize: page.pageSize,
|
||||||
}
|
unitId: unitId.value,
|
||||||
})
|
},
|
||||||
}
|
});
|
||||||
}
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
isCurrent: false,
|
isCurrent: false,
|
||||||
},
|
},
|
||||||
editConfig: {
|
editConfig: {
|
||||||
trigger: "click",
|
trigger: 'click',
|
||||||
mode: "row",
|
mode: 'row',
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,14 +140,7 @@ const gridOptions = reactive(
|
||||||
*/
|
*/
|
||||||
function handleCellClick({ row }) {
|
function handleCellClick({ row }) {
|
||||||
console.log(row);
|
console.log(row);
|
||||||
emit("rowClick", row);
|
emit('rowClick', row);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开选择办公用品弹窗
|
|
||||||
*/
|
|
||||||
function handleOpenOfficeModal() {
|
|
||||||
chooseOfficeModalApi.open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,13 +150,13 @@ function handleOpenOfficeModal() {
|
||||||
function handleChooseOfficeConfirm(rows) {
|
function handleChooseOfficeConfirm(rows) {
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
row.count = 1;
|
row.count = 1;
|
||||||
row.remarks = "";
|
row.remarks = '';
|
||||||
}
|
}
|
||||||
const $grid = xGridRef.value;
|
const $grid = xGridRef.value;
|
||||||
// 判断上一个新增项有无完成,未完成则不允许新增
|
// 判断上一个新增项有无完成,未完成则不允许新增
|
||||||
if ($grid) {
|
if ($grid) {
|
||||||
$grid.remove();
|
$grid.remove();
|
||||||
$grid.insert(rows).then(({ row }) => { });
|
$grid.insert(rows).then(({ row }) => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,37 +169,35 @@ function handleAudit(row, type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = ref("选择要入库的办公用品");
|
const title = ref('选择要入库的办公用品');
|
||||||
|
|
||||||
const [BaseModal, baseModalApi] = useVbenModal({
|
const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
async onOpenChange(isOpen: boolean) {
|
async onOpenChange(isOpen: boolean) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
isConfirmLoading.value = false
|
isConfirmLoading.value = false;
|
||||||
|
|
||||||
treeData.value = await getUnitData()
|
treeData.value = await getUnitData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onConfirm() {
|
onConfirm() {
|
||||||
try {
|
try {
|
||||||
isConfirmLoading.value = true
|
isConfirmLoading.value = true;
|
||||||
const res = xGridRef.value?.getTableData();
|
const res = xGridRef.value?.getTableData();
|
||||||
const data = res?.fullData || [];
|
const data = res?.fullData || [];
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
item.officeName = item.name || "";
|
item.officeName = item.name || '';
|
||||||
});
|
});
|
||||||
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: "提示",
|
title: '提示',
|
||||||
content: `是否确认入库以上办公用品?`,
|
content: `是否确认入库以上办公用品?`,
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
try {
|
try {
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
item.status = "in";
|
item.status = 'in';
|
||||||
});
|
});
|
||||||
await Apis.inOrOut.post_saveBatch({ data: data });
|
await Apis.inOrOut.post_saveBatch({ data });
|
||||||
emit("success");
|
emit('success');
|
||||||
baseModalApi.close();
|
baseModalApi.close();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -207,7 +205,7 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
isConfirmLoading.value = false
|
isConfirmLoading.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -218,19 +216,32 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BaseModal :title="title">
|
<BaseModal :title="title">
|
||||||
|
<ChooseOfficeModal
|
||||||
|
class="w-[900px] max-w-[75vw]"
|
||||||
|
@confirm="handleChooseOfficeConfirm"
|
||||||
|
/>
|
||||||
|
|
||||||
<ChooseOfficeModal class="w-[900px] max-w-[75vw]" @confirm="handleChooseOfficeConfirm" />
|
<a-tabs v-model:active-key="activeKey" size="small">
|
||||||
|
|
||||||
|
|
||||||
<a-tabs v-model:activeKey="activeKey" size="small">
|
|
||||||
<a-tab-pane key="1" tab="针对审批分发">
|
<a-tab-pane key="1" tab="针对审批分发">
|
||||||
<div class="h-full flex flex-col">
|
<div class="flex h-full flex-col">
|
||||||
<VxeGrid ref="xGridRef" v-bind="gridOptions" @cell-click="handleCellClick">
|
<VxeGrid
|
||||||
|
ref="xGridRef"
|
||||||
|
v-bind="gridOptions"
|
||||||
|
@cell-click="handleCellClick"
|
||||||
|
>
|
||||||
<template #toolbar_buttons>
|
<template #toolbar_buttons>
|
||||||
<a-tree-select v-model:value="unitId" show-search style="width: 200px"
|
<a-tree-select
|
||||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" placeholder="可筛选单位" allow-clear
|
v-model:value="unitId"
|
||||||
tree-default-expand-all :tree-data="treeData" tree-node-filter-prop="label"
|
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||||
@change="triggerProxy('reload')">
|
:tree-data="treeData"
|
||||||
|
allow-clear
|
||||||
|
placeholder="可筛选单位"
|
||||||
|
show-search
|
||||||
|
style="width: 200px"
|
||||||
|
tree-default-expand-all
|
||||||
|
tree-node-filter-prop="label"
|
||||||
|
@change="triggerProxy('reload')"
|
||||||
|
>
|
||||||
<template #title="{ value: val, label }">
|
<template #title="{ value: val, label }">
|
||||||
<b v-if="val === 'parent 1-1'" style="color: #08c">sss</b>
|
<b v-if="val === 'parent 1-1'" style="color: #08c">sss</b>
|
||||||
<template v-else>{{ label }}</template>
|
<template v-else>{{ label }}</template>
|
||||||
|
@ -244,21 +255,39 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
|
|
||||||
<template #supplies_default_slot="scope">
|
<template #supplies_default_slot="scope">
|
||||||
<div>
|
<div>
|
||||||
{{ scope.row.name ? scope.row.name + "(" + scope.row.model + ")" : "" }}
|
{{
|
||||||
|
scope.row.name
|
||||||
|
? `${scope.row.name}(${scope.row.model})`
|
||||||
|
: ''
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #edit_num="{ row }">
|
<template #edit_num="{ row }">
|
||||||
<a-input-number v-model:value="row.count" :min="1" :addon-after="row.units || '个'"
|
<a-input-number
|
||||||
placeholder="请选择发放数量" />
|
v-model:value="row.count"
|
||||||
|
:addon-after="row.units || '个'"
|
||||||
|
:min="1"
|
||||||
|
placeholder="请选择发放数量"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #operate="{ row }">
|
<template #operate="{ row }">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="text" size="small" class="text-primary-500" @click="handleAudit(row, 'access')">
|
<a-button
|
||||||
|
class="text-primary-500"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="handleAudit(row, 'access')"
|
||||||
|
>
|
||||||
发放
|
发放
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="text" size="small" class="text-red-500" @click="handleAudit(row, 'reject')">
|
<a-button
|
||||||
|
class="text-red-500"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="handleAudit(row, 'reject')"
|
||||||
|
>
|
||||||
驳回
|
驳回
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
@ -267,8 +296,5 @@ const [BaseModal, baseModalApi] = useVbenModal({
|
||||||
</div>
|
</div>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</BaseModal>
|
</BaseModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,28 +1,20 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="tsx">
|
||||||
import { nextTick, onMounted, ref } from 'vue';
|
import { nextTick, onMounted, ref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
import { MdiUpload } from '@vben/icons';
|
import { MdiUpload } from '@vben/icons';
|
||||||
import { useUserStore } from '@vben/stores';
|
|
||||||
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
import {
|
import { message, Modal, type UploadChangeParam } from 'ant-design-vue';
|
||||||
message,
|
import { logger } from 'common-utils';
|
||||||
Modal,
|
|
||||||
type UploadChangeParam,
|
|
||||||
type UploadProps,
|
|
||||||
} from 'ant-design-vue';
|
|
||||||
import dayjs, { Dayjs } from 'dayjs';
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
import Apis from '#/api';
|
import Apis from '#/api';
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
|
||||||
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
||||||
import { FileUploader } from '#/utils/file';
|
import { FileUploader } from '#/utils/file';
|
||||||
import chooseUserModal from '#/views/system/user/choose-user-modal.vue';
|
import chooseUserModal from '#/views/system/user/choose-user-modal.vue';
|
||||||
|
|
||||||
const { xGridRef, gridProps, triggerProxy } = useVxeTable({ ref: 'xGridRef' });
|
|
||||||
|
|
||||||
const fileUploader = new FileUploader({});
|
const fileUploader = new FileUploader({});
|
||||||
|
|
||||||
const [ChooseUserModal, chooseUserModalApi] = useVbenModal({
|
const [ChooseUserModal, chooseUserModalApi] = useVbenModal({
|
||||||
|
@ -31,16 +23,12 @@ const [ChooseUserModal, chooseUserModalApi] = useVbenModal({
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const id = route.params.id;
|
const id = ref(route.params.id);
|
||||||
|
|
||||||
const showHelpTip = ref(false);
|
|
||||||
|
|
||||||
const containerRef = ref();
|
const containerRef = ref();
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const form2Ref = ref();
|
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
|
||||||
function handleUpdateFormattedValue() {
|
function handleUpdateFormattedValue() {
|
||||||
const { starttime, endtime } = formRef.value.form;
|
const { starttime, endtime } = formRef.value.form;
|
||||||
|
|
||||||
|
@ -54,6 +42,7 @@ function handleUpdateFormattedValue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectUsers = ref<any>([]);
|
||||||
const disabledDate = (current: Dayjs) => {
|
const disabledDate = (current: Dayjs) => {
|
||||||
// Can not select days before today and today
|
// Can not select days before today and today
|
||||||
const form = formRef.value.form;
|
const form = formRef.value.form;
|
||||||
|
@ -80,7 +69,7 @@ const formBinding = ref({
|
||||||
key: 'taskType',
|
key: 'taskType',
|
||||||
col: { span: 12 },
|
col: { span: 12 },
|
||||||
component: {
|
component: {
|
||||||
name: 'fs-dict-select',
|
name: 'fs-dict-radio',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: getDictOptions(DICT_TYPE.supervise_task_type),
|
data: getDictOptions(DICT_TYPE.supervise_task_type),
|
||||||
|
@ -93,14 +82,13 @@ const formBinding = ref({
|
||||||
key: 'urgentDegree',
|
key: 'urgentDegree',
|
||||||
col: { span: 12 },
|
col: { span: 12 },
|
||||||
component: {
|
component: {
|
||||||
name: 'fs-dict-select',
|
name: 'fs-dict-radio',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: getDictOptions(DICT_TYPE.supervise_emergency_level),
|
data: getDictOptions(DICT_TYPE.supervise_emergency_level),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
starttime: {
|
starttime: {
|
||||||
title: '开始时间',
|
title: '开始时间',
|
||||||
key: 'starttime',
|
key: 'starttime',
|
||||||
|
@ -113,7 +101,7 @@ const formBinding = ref({
|
||||||
// disabledDate: (current) => current && current < dayjs().endOf("day"),
|
// disabledDate: (current) => current && current < dayjs().endOf("day"),
|
||||||
format: 'YYYY-MM-DD HH:mm',
|
format: 'YYYY-MM-DD HH:mm',
|
||||||
valueFormat: 'YYYY-MM-DD HH:mm',
|
valueFormat: 'YYYY-MM-DD HH:mm',
|
||||||
onChange: (e) => {
|
onChange: () => {
|
||||||
handleUpdateFormattedValue();
|
handleUpdateFormattedValue();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -129,7 +117,7 @@ const formBinding = ref({
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
showTime: { format: 'HH:mm' },
|
showTime: { format: 'HH:mm' },
|
||||||
disabledDate,
|
disabledDate,
|
||||||
onChange: (e) => {
|
onChange: () => {
|
||||||
handleUpdateFormattedValue();
|
handleUpdateFormattedValue();
|
||||||
},
|
},
|
||||||
format: 'YYYY-MM-DD HH:mm',
|
format: 'YYYY-MM-DD HH:mm',
|
||||||
|
@ -146,7 +134,7 @@ const formBinding = ref({
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
showTime: { format: 'HH:mm' },
|
showTime: { format: 'HH:mm' },
|
||||||
disabledDate,
|
disabledDate,
|
||||||
onChange: (e) => {
|
onChange: () => {
|
||||||
handleUpdateFormattedValue();
|
handleUpdateFormattedValue();
|
||||||
},
|
},
|
||||||
format: 'YYYY-MM-DD HH:mm',
|
format: 'YYYY-MM-DD HH:mm',
|
||||||
|
@ -161,6 +149,7 @@ const formBinding = ref({
|
||||||
component: {
|
component: {
|
||||||
name: 'a-textarea',
|
name: 'a-textarea',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
|
autoSize: { minRows: 4, maxRows: 6 },
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '请输入任务内容' }],
|
rules: [{ required: true, message: '请输入任务内容' }],
|
||||||
},
|
},
|
||||||
|
@ -171,6 +160,7 @@ const formBinding = ref({
|
||||||
component: {
|
component: {
|
||||||
name: 'a-textarea',
|
name: 'a-textarea',
|
||||||
vModel: 'value',
|
vModel: 'value',
|
||||||
|
autoSize: { minRows: 4, maxRows: 6 },
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '请输入任务进度' }],
|
rules: [{ required: true, message: '请输入任务进度' }],
|
||||||
},
|
},
|
||||||
|
@ -178,13 +168,35 @@ const formBinding = ref({
|
||||||
title: '相关附件',
|
title: '相关附件',
|
||||||
key: 'fileList',
|
key: 'fileList',
|
||||||
},
|
},
|
||||||
|
people: {
|
||||||
|
title: '相关执行人',
|
||||||
|
key: 'people',
|
||||||
|
component: {
|
||||||
|
name: 'a-select',
|
||||||
|
vModel: 'value',
|
||||||
|
open: false,
|
||||||
|
mode: 'multiple',
|
||||||
|
onClick: () => {
|
||||||
|
chooseUserModalApi.setData({
|
||||||
|
title: '选择执行人',
|
||||||
|
limitMultipleNum: 10,
|
||||||
|
userIds: selectUsers.value.map((row) => row.value) || [],
|
||||||
|
});
|
||||||
|
chooseUserModalApi.open();
|
||||||
|
},
|
||||||
|
onChange: () => {
|
||||||
|
// 同步 selectUsers 变量的值
|
||||||
|
selectUsers.value = formRef.value.form.people.map((item1) => {
|
||||||
|
const value = item1.split('-')[1];
|
||||||
|
return selectUsers.value.find((item2) => item2.value === value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// rules: [{ required: true, message: '请选择相关执行人' }],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleBack() {
|
function handleBack() {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
|
@ -215,7 +227,7 @@ function handleDelete() {
|
||||||
okType: 'danger',
|
okType: 'danger',
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
await Apis.meeting.post_deletes({
|
await Apis.meeting.post_deletes({
|
||||||
params: { ids: currData.value.guid },
|
params: { ids: id.value },
|
||||||
});
|
});
|
||||||
message.success('删除成功');
|
message.success('删除成功');
|
||||||
back();
|
back();
|
||||||
|
@ -228,53 +240,97 @@ function handleDelete() {
|
||||||
* @param rows
|
* @param rows
|
||||||
*/
|
*/
|
||||||
function handleChooseUserConfirm(rows) {
|
function handleChooseUserConfirm(rows) {
|
||||||
console.log('[ rows ] >', rows);
|
rows.forEach((row) => {
|
||||||
rows.forEach((element) => {});
|
row.label = row.EMPLOYEE_NAME;
|
||||||
const $grid = xGridRef.value;
|
row.value = row.ACCOUNT_ID;
|
||||||
// 判断上一个新增项有无完成,未完成则不允许新增
|
});
|
||||||
if ($grid) {
|
formRef.value.setFormData({
|
||||||
$grid.remove();
|
people: rows.map((row) => `${row.label}-${row.value}`),
|
||||||
$grid.insert(rows).then(({ row }) => {});
|
});
|
||||||
} else {
|
selectUsers.value = rows;
|
||||||
console.error('xGridRef不存在');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSave() {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const form = formRef.value.form;
|
await formRef.value.submit();
|
||||||
// await formRef.value.submit()
|
|
||||||
console.log(formRef.value);
|
|
||||||
const userStore = useUserStore();
|
|
||||||
|
|
||||||
let newForm = {};
|
const newForm = formRef.value.form;
|
||||||
|
|
||||||
// 会议附件
|
// 附件
|
||||||
const fileList = formRef.value.form.fileList;
|
const fileList = formRef.value.form.fileList;
|
||||||
let files: any = [];
|
let files: any = [];
|
||||||
if (fileList && fileList.length > 0) {
|
if (fileList && fileList.length > 0) {
|
||||||
files = await fileUploader.upload(fileList, { source: 'erp' });
|
files = await fileUploader.upload(fileList, { source: 'erp' });
|
||||||
}
|
}
|
||||||
console.log(files);
|
|
||||||
if (files) {
|
if (files) {
|
||||||
newForm.fileUuid = (files.map((item) => item.fileUuid) || []).join(',');
|
newForm.fileUuid = (files.map((item) => item.fileUuid) || []).join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
newForm = Object.assign({}, formRef.value.form, newForm);
|
|
||||||
|
|
||||||
delete newForm.fileList;
|
delete newForm.fileList;
|
||||||
|
|
||||||
console.log(newForm);
|
const data = await Apis.supervise.post_save({
|
||||||
|
data: newForm,
|
||||||
|
});
|
||||||
|
id.value = data.guid;
|
||||||
|
|
||||||
await Apis.supervise.post_save({ data: newForm }).then((data) => {
|
message.success('保存成功');
|
||||||
message.success('提交成功');
|
Modal.confirm({
|
||||||
back();
|
title: '提示',
|
||||||
|
content: '保存成功!是否立即提交?',
|
||||||
|
onOk: () => {
|
||||||
|
handleSubmit();
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
back();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
logger.error('立项保存失败', error);
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function handleSubmit() {
|
||||||
|
isLoading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await formRef.value.submit();
|
||||||
|
|
||||||
|
const newForm: any = formRef.value.form;
|
||||||
|
|
||||||
|
if (!newForm.people || newForm.people.length === 0) {
|
||||||
|
message.error('请先选择相关执行人');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Apis.supervise.post_audit({
|
||||||
|
params: {
|
||||||
|
guid: id.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (newForm.people && newForm.people.length > 0) {
|
||||||
|
const people = selectUsers.value.map((item) => {
|
||||||
|
return {
|
||||||
|
dwbm: item.ORG_ID,
|
||||||
|
dwmc: item.ORG_NAME,
|
||||||
|
principalId: item.ACCOUNT_ID,
|
||||||
|
principal: item.EMPLOYEE_NAME,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await Apis.feedback.post_save({
|
||||||
|
params: { guid: newForm.guid },
|
||||||
|
data: people,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
message.success('提交成功');
|
||||||
|
back();
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('立项提交失败', error);
|
||||||
message.error('提交失败,请稍候再试');
|
message.error('提交失败,请稍候再试');
|
||||||
console.log(error);
|
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
@ -284,14 +340,11 @@ const currData = ref({});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
console.log(id);
|
|
||||||
try {
|
try {
|
||||||
if (id) {
|
if (id.value) {
|
||||||
let data = await Apis.supervise.get_page({ params: { guid: id } });
|
let data = await Apis.supervise.get_page({ params: { guid: id.value } });
|
||||||
data = data.rows[0];
|
data = data.rows[0];
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
currData.value = data;
|
currData.value = data;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value.setFormData(data);
|
formRef.value.setFormData(data);
|
||||||
|
@ -299,7 +352,6 @@ onMounted(async () => {
|
||||||
|
|
||||||
if (data.fileUuid) {
|
if (data.fileUuid) {
|
||||||
const files = await fileUploader.select(data.fileUuid);
|
const files = await fileUploader.select(data.fileUuid);
|
||||||
console.log(files);
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value.setFormData({
|
formRef.value.setFormData({
|
||||||
fileList: files,
|
fileList: files,
|
||||||
|
@ -308,7 +360,7 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
logger.error('当前立项信息不存在', error);
|
||||||
|
|
||||||
Modal.error({
|
Modal.error({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
|
@ -336,6 +388,9 @@ onMounted(async () => {
|
||||||
/>
|
/>
|
||||||
<a-spin :spinning="isLoading">
|
<a-spin :spinning="isLoading">
|
||||||
<a-space>
|
<a-space>
|
||||||
|
<vben-button variant="primary" @click="handleSave()">
|
||||||
|
保存
|
||||||
|
</vben-button>
|
||||||
<vben-button variant="primary" @click="handleSubmit()">
|
<vben-button variant="primary" @click="handleSubmit()">
|
||||||
提交
|
提交
|
||||||
</vben-button>
|
</vben-button>
|
||||||
|
@ -353,7 +408,7 @@ onMounted(async () => {
|
||||||
<template #form_fileList="scope">
|
<template #form_fileList="scope">
|
||||||
<a-upload
|
<a-upload
|
||||||
v-model:file-list="scope.form.fileList"
|
v-model:file-list="scope.form.fileList"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="() => false"
|
||||||
:max-count="3"
|
:max-count="3"
|
||||||
accept=".pdf,.ppt,.pptx"
|
accept=".pdf,.ppt,.pptx"
|
||||||
name="file"
|
name="file"
|
||||||
|
@ -373,15 +428,4 @@ onMounted(async () => {
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
.sortable-tree-demo .drag-btn {
|
|
||||||
cursor: move;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sortable-tree-demo .vxe-body--row.sortable-ghost,
|
|
||||||
.sortable-tree-demo .vxe-body--row.sortable-chosen {
|
|
||||||
background-color: #dfecfb;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: 'remarks', title: '备注', minWidth: 200 },
|
{ field: 'remarks', title: '备注', minWidth: 200 },
|
||||||
// { title: '操作', width: 120, fixed: 'right', slots: { default: 'operate' } }
|
{ title: '操作', width: 80, fixed: 'right', slots: { default: 'operate' } },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
|
import { getColumns } from '../../feedback/crud';
|
||||||
|
|
||||||
|
const { xGridRef, gridProps, triggerProxy } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
|
const open = ref<boolean>(false);
|
||||||
|
|
||||||
|
const title = ref('');
|
||||||
|
const currData = ref<any>({});
|
||||||
|
|
||||||
|
/** Hooks - 表格 */
|
||||||
|
const gridOptions = reactive(
|
||||||
|
gridProps({
|
||||||
|
height: '100%',
|
||||||
|
columns: getColumns(),
|
||||||
|
proxyConfig: {
|
||||||
|
autoLoad: false,
|
||||||
|
ajax: {
|
||||||
|
query: async () => {
|
||||||
|
const data = await Apis.feedback.get_page({
|
||||||
|
params: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 500,
|
||||||
|
guid: currData.value.guid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// function handleExport() {
|
||||||
|
// const $grid = xGridRef.value;
|
||||||
|
// if ($grid) {
|
||||||
|
// $grid.exportData({
|
||||||
|
// type: 'xlsx',
|
||||||
|
// });
|
||||||
|
// message.success('导出成功');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
const openDrawer = async (data) => {
|
||||||
|
open.value = true;
|
||||||
|
title.value = data.title;
|
||||||
|
currData.value = data.record;
|
||||||
|
triggerProxy('reload');
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDrawer = () => {
|
||||||
|
open.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ open: openDrawer, close: closeDrawer });
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<a-drawer
|
||||||
|
:open="open"
|
||||||
|
:title="title"
|
||||||
|
height="60vh"
|
||||||
|
placement="bottom"
|
||||||
|
@close="closeDrawer"
|
||||||
|
>
|
||||||
|
<template #extra>
|
||||||
|
<a-button @click="closeDrawer">关闭</a-button>
|
||||||
|
</template>
|
||||||
|
<vxe-grid ref="xGridRef" v-bind="gridOptions">
|
||||||
|
<template #toolbar_buttons> </template>
|
||||||
|
</vxe-grid>
|
||||||
|
</a-drawer>
|
||||||
|
</template>
|
|
@ -18,12 +18,14 @@ import Apis from '#/api';
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
import { getColumns, getFormSchema } from './crud.tsx';
|
import { getColumns, getFormSchema } from './crud.tsx';
|
||||||
|
import DetailDrawer from './detail-drawer/detail-drawer.vue';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const isOneDay = ref('');
|
const isOneDay = ref('');
|
||||||
|
|
||||||
const searchRef = ref();
|
const searchRef = ref();
|
||||||
|
const detailDrawerRef = ref();
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
|
@ -87,6 +89,13 @@ function handleCellClick({ row }) {
|
||||||
setSelectRow(row);
|
setSelectRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectDetail(row) {
|
||||||
|
detailDrawerRef.value.open({
|
||||||
|
title: row.taskName,
|
||||||
|
record: row,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
triggerProxy('reload');
|
triggerProxy('reload');
|
||||||
});
|
});
|
||||||
|
@ -122,6 +131,8 @@ function handleDelete(row) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page content-class="h-full flex flex-col">
|
<Page content-class="h-full flex flex-col">
|
||||||
|
<DetailDrawer ref="detailDrawerRef" />
|
||||||
|
|
||||||
<fs-search ref="searchRef" v-bind="searchForm" />
|
<fs-search ref="searchRef" v-bind="searchForm" />
|
||||||
<div class="min-h-300px flex-1">
|
<div class="min-h-300px flex-1">
|
||||||
<vxe-grid
|
<vxe-grid
|
||||||
|
@ -172,6 +183,18 @@ function handleDelete(row) {
|
||||||
<template #statusSlot="{ row }">
|
<template #statusSlot="{ row }">
|
||||||
<a-tag>{{ row.status || '待提交' }}</a-tag>
|
<a-tag>{{ row.status || '待提交' }}</a-tag>
|
||||||
</template>
|
</template>
|
||||||
|
<template #operate="{ row }">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
class="text-primary"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
@click="selectDetail(row)"
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
@ -1,24 +1,36 @@
|
||||||
import type { VxeGridPropTypes } from 'vxe-table';
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
import { useRender } from '#/hooks/useRender';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { DICT_TYPE, getDictObj, getDictOptions } from '#/utils/dict';
|
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from '@fast-crud/fast-crud';
|
||||||
import { unitComponentProps } from '#/common/unit';
|
|
||||||
|
import { useRender } from '#/hooks/useRender';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
||||||
|
|
||||||
export const PrimaryKey = 'guid';
|
export const PrimaryKey = 'guid';
|
||||||
|
|
||||||
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
return [
|
return [
|
||||||
{ type: 'radio', width: 40, slots: { radio: 'radio_cell' }, align: 'center', fixed: 'left' },
|
{
|
||||||
|
type: 'radio',
|
||||||
|
width: 40,
|
||||||
|
slots: { radio: 'radio_cell' },
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'left',
|
||||||
|
},
|
||||||
// { type: 'expand', width: 60, slots: { content: 'expand_content' } },
|
// { type: 'expand', width: 60, slots: { content: 'expand_content' } },
|
||||||
{
|
{
|
||||||
field: 'TASK_NAME', title: '任务标题', width: 200, slots: {
|
field: 'TASK_NAME',
|
||||||
default: "task-name-slot"
|
title: '任务标题',
|
||||||
|
width: 200,
|
||||||
|
slots: {
|
||||||
|
default: 'task-name-slot',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'status', title: '任务状态', width: 120, slots: {
|
field: 'status',
|
||||||
default: "statusSlot"
|
title: '任务状态',
|
||||||
|
width: 120,
|
||||||
|
slots: {
|
||||||
|
default: 'statusSlot',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -27,22 +39,31 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
width: 100,
|
width: 100,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderDict(row.taskType, DICT_TYPE.supervise_task_type);
|
return useRender.renderDict(
|
||||||
}
|
row.taskType,
|
||||||
}
|
DICT_TYPE.supervise_task_type,
|
||||||
},
|
);
|
||||||
{
|
},
|
||||||
field: 'TASK_CONTENT', title: '任务内容', width: 300, slots: {
|
|
||||||
default: ({ row }) => {
|
|
||||||
return useRender.renderMultiLineText(row.TASK_CONTENT, {});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'taskProgress', title: '任务进度', minWidth: 200, slots: {
|
field: 'TASK_CONTENT',
|
||||||
|
title: '任务内容',
|
||||||
|
width: 300,
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return useRender.renderMultiLineText(row.TASK_CONTENT, {});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'taskProgress',
|
||||||
|
title: '任务进度',
|
||||||
|
minWidth: 200,
|
||||||
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderMultiLineText(row.taskProgress, {});
|
return useRender.renderMultiLineText(row.taskProgress, {});
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -51,33 +72,42 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
width: 100,
|
width: 100,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderDict(row.urgentDegree, DICT_TYPE.supervise_emergency_level);
|
return useRender.renderDict(
|
||||||
}
|
row.urgentDegree,
|
||||||
}
|
DICT_TYPE.supervise_emergency_level,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'starttime', title: '开始日期', width: 120,
|
field: 'starttime',
|
||||||
|
title: '开始日期',
|
||||||
|
width: 120,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderDate(row.starttime, 'YYYY-MM-DD');
|
return useRender.renderDate(row.starttime, 'YYYY-MM-DD');
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'endtime', title: '截止日期', width: 120,
|
field: 'endtime',
|
||||||
|
title: '截止日期',
|
||||||
|
width: 120,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderDate(row.endtime, 'YYYY-MM-DD');
|
return useRender.renderDate(row.endtime, 'YYYY-MM-DD');
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'planFinishTime', title: '预计完成日期', width: 120,
|
field: 'planFinishTime',
|
||||||
|
title: '预计完成日期',
|
||||||
|
width: 120,
|
||||||
slots: {
|
slots: {
|
||||||
default: ({ row }) => {
|
default: ({ row }) => {
|
||||||
return useRender.renderDate(row.planFinishTime, 'YYYY-MM-DD');
|
return useRender.renderDate(row.planFinishTime, 'YYYY-MM-DD');
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{ field: 'remarks', title: '备注', minWidth: 200 },
|
{ field: 'remarks', title: '备注', minWidth: 200 },
|
||||||
// { title: '操作', width: 120, fixed: 'right', slots: { default: 'operate' } }
|
// { title: '操作', width: 120, fixed: 'right', slots: { default: 'operate' } }
|
||||||
|
@ -86,8 +116,7 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
|
||||||
|
|
||||||
export function getFormSchema(_params: any = {}) {
|
export function getFormSchema(_params: any = {}) {
|
||||||
return {
|
return {
|
||||||
initialForm: {
|
initialForm: {},
|
||||||
},
|
|
||||||
columns: {
|
columns: {
|
||||||
taskName: {
|
taskName: {
|
||||||
title: '任务名称',
|
title: '任务名称',
|
||||||
|
@ -112,21 +141,21 @@ export function getFormSchema(_params: any = {}) {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
value: '1',
|
value: '1',
|
||||||
label: '未开始'
|
label: '未开始',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '2',
|
value: '2',
|
||||||
label: '进行中'
|
label: '进行中',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '3',
|
value: '3',
|
||||||
label: '已完成'
|
label: '已完成',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '4',
|
value: '4',
|
||||||
label: '已超时'
|
label: '已超时',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
autoSearchTrigger: 'enter',
|
autoSearchTrigger: 'enter',
|
||||||
|
@ -141,7 +170,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.supervise_task_type)
|
data: getDictOptions(DICT_TYPE.supervise_task_type),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
autoSearchTrigger: 'enter',
|
autoSearchTrigger: 'enter',
|
||||||
|
@ -155,6 +184,5 @@ export function getFormSchema(_params: any = {}) {
|
||||||
// show: true,
|
// show: true,
|
||||||
// },
|
// },
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,55 +1,55 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, ref, computed, reactive, onMounted } from 'vue';
|
import { computed, onMounted, reactive, ref } from 'vue';
|
||||||
import { FsCrud } from '@fast-crud/fast-crud';
|
|
||||||
import { type VxeGridProps } from 'vxe-table'
|
import { Page } from '@vben/common-ui';
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { MdiExport, MdiRadioChecked, MdiRadioUnchecked } from '@vben/icons';
|
||||||
|
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
import { useVxeTable } from '#/hooks/vxeTable';
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
import { MdiAdd, MdiUpdate, MdiDelete, MdiImport, MdiExport, MdiRadioUnchecked, MdiRadioChecked } from '@vben/icons';
|
|
||||||
import { getFormSchema, getColumns } from './crud.tsx';
|
|
||||||
import { dict } from "@fast-crud/fast-crud";
|
|
||||||
import { getMonthStartAndEnd } from '#/utils/time'
|
|
||||||
import Apis from '#/api'
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { message } from "ant-design-vue";
|
|
||||||
import { Modal } from 'ant-design-vue';
|
|
||||||
import { unitComponentProps } from '#/common/unit'
|
|
||||||
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
|
|
||||||
|
|
||||||
import { useRouter } from 'vue-router'
|
import { getColumns, getFormSchema } from './crud.tsx';
|
||||||
|
|
||||||
const router = useRouter();
|
const searchRef = ref();
|
||||||
|
|
||||||
const searchRef = ref()
|
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
const gridOptions = reactive(gridProps({
|
const gridOptions = reactive(
|
||||||
columns: getColumns(),
|
gridProps({
|
||||||
proxyConfig: {
|
columns: getColumns(),
|
||||||
autoLoad: false,
|
proxyConfig: {
|
||||||
ajax: {
|
autoLoad: false,
|
||||||
query: ({ page }) => {
|
ajax: {
|
||||||
let form = searchRef.value?.formData
|
query: ({ page }) => {
|
||||||
return Apis.supervise.get_huizong({ params: { pageNum: page.currentPage, pageSize: page.pageSize, ...form } })
|
const form = searchRef.value?.formData;
|
||||||
}
|
return Apis.supervise.get_huizong({
|
||||||
|
params: {
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
...form,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
pagerConfig: {
|
||||||
pagerConfig: {
|
enabled: true,
|
||||||
enabled: true
|
},
|
||||||
},
|
toolbarConfig: {
|
||||||
toolbarConfig: {
|
enabled: true,
|
||||||
enabled: true
|
},
|
||||||
},
|
}),
|
||||||
}));
|
);
|
||||||
|
|
||||||
function handleExport() {
|
function handleExport() {
|
||||||
const $grid = xGridRef.value;
|
const $grid = xGridRef.value;
|
||||||
if ($grid) {
|
if ($grid) {
|
||||||
$grid.exportData({
|
$grid.exportData({
|
||||||
type: "xlsx",
|
type: 'xlsx',
|
||||||
});
|
});
|
||||||
message.success("导出成功");
|
message.success('导出成功');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ const selectRow: any = computed(() => {
|
||||||
|
|
||||||
/** 单选框选中事件 */
|
/** 单选框选中事件 */
|
||||||
const setSelectRow = (row: any) => {
|
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 {
|
||||||
xGridRef.value?.setRadioRow(row);
|
xGridRef.value?.setRadioRow(row);
|
||||||
|
@ -73,31 +73,30 @@ function handleCellClick({ row }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
triggerProxy('reload')
|
triggerProxy('reload');
|
||||||
})
|
});
|
||||||
|
|
||||||
let searchParams = reactive({})
|
|
||||||
const searchForm = ref({
|
const searchForm = ref({
|
||||||
...getFormSchema(),
|
...getFormSchema(),
|
||||||
onSearch(context: any) {
|
onSearch(_context: any) {
|
||||||
console.log(searchRef.value)
|
triggerProxy('reload');
|
||||||
triggerProxy('reload')
|
|
||||||
},
|
|
||||||
onReset(context: any) {
|
|
||||||
searchParams = context.form
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page contentClass="h-full flex flex-col">
|
<Page content-class="h-full flex flex-col">
|
||||||
<fs-search ref="searchRef" v-bind="searchForm"> </fs-search>
|
<fs-search ref="searchRef" v-bind="searchForm" />
|
||||||
<div class="flex-1 min-h-300px">
|
<div class="min-h-300px flex-1">
|
||||||
<vxe-grid ref="xGridRef" v-bind="gridOptions" @cell-click="handleCellClick">
|
<vxe-grid
|
||||||
|
ref="xGridRef"
|
||||||
|
v-bind="gridOptions"
|
||||||
|
@cell-click="handleCellClick"
|
||||||
|
>
|
||||||
<template #toolbar_buttons>
|
<template #toolbar_buttons>
|
||||||
<a-space>
|
<a-space>
|
||||||
<vben-button variant="primary" @click="handleExport()">
|
<vben-button variant="primary" @click="handleExport()">
|
||||||
<MdiExport class="text-lg mr-0.5" />
|
<MdiExport class="mr-0.5 text-lg" />
|
||||||
导出
|
导出
|
||||||
</vben-button>
|
</vben-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
@ -115,7 +114,7 @@ const searchForm = ref({
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #statusSlot="{ row }">
|
<template #statusSlot="{ row }">
|
||||||
<a-tag>{{ row.status || "待提交" }}</a-tag>
|
<a-tag>{{ row.status || '待提交' }}</a-tag>
|
||||||
</template>
|
</template>
|
||||||
</vxe-grid>
|
</vxe-grid>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from "vue";
|
import type { VxeGridPropTypes } from 'vxe-table';
|
||||||
import { useVbenModal } from "@vben/common-ui";
|
|
||||||
import { message } from "ant-design-vue";
|
|
||||||
import { useVxeTable } from "#/hooks/vxeTable";
|
|
||||||
import type { VxeGridPropTypes } from "vxe-table";
|
|
||||||
import Apis from "#/api";
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
import { reactive, ref } from 'vue';
|
||||||
(e: "rowClick", row: any): any;
|
|
||||||
(e: "confirm", row: any[]): any[];
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
}>();
|
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import { logger } from 'common-utils';
|
||||||
|
|
||||||
|
import Apis from '#/api';
|
||||||
|
import { useVxeTable } from '#/hooks/vxeTable';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
@ -19,68 +19,75 @@ const props = withDefaults(
|
||||||
{
|
{
|
||||||
multiple: false,
|
multiple: false,
|
||||||
showDepartment: true,
|
showDepartment: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'confirm', row: any[]): any[];
|
||||||
|
(e: 'rowClick', row: any): any;
|
||||||
|
}>();
|
||||||
|
|
||||||
const [messageApi] = message.useMessage();
|
const [messageApi] = message.useMessage();
|
||||||
|
|
||||||
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: "xGridRef" });
|
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||||
|
|
||||||
const searchRef = ref();
|
const searchRef = ref();
|
||||||
|
|
||||||
const data = ref({
|
const data = ref({
|
||||||
userIds: []
|
title: '',
|
||||||
|
limitMultipleNum: 10,
|
||||||
|
userIds: [],
|
||||||
});
|
});
|
||||||
const formRef = ref();
|
|
||||||
const treeData = ref([]);
|
const treeData = ref([]);
|
||||||
|
|
||||||
const treeItemKey = ref([]);
|
const treeItemKey = ref([]);
|
||||||
const isEditMenu = ref(false);
|
const isEditMenu = ref(false);
|
||||||
const checkedId = ref(0);
|
const checkedId = ref(0);
|
||||||
|
const canMultiple = ref(false);
|
||||||
const checkRecords = ref([]);
|
const limitMultipleNum = ref(10);
|
||||||
|
const checkRecords = ref<any>([]);
|
||||||
|
|
||||||
const searchBinding = ref({
|
const searchBinding = ref({
|
||||||
initialForm: {},
|
initialForm: {},
|
||||||
columns: {
|
columns: {
|
||||||
name: {
|
name: {
|
||||||
title: "用户姓名",
|
title: '用户姓名',
|
||||||
key: "name",
|
key: 'name',
|
||||||
component: {
|
component: {
|
||||||
name: "a-input",
|
name: 'a-input',
|
||||||
vModel: "value",
|
vModel: 'value',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
},
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onSearch(context: any) {
|
onSearch(_context: any) {
|
||||||
triggerProxy("reload");
|
triggerProxy('reload');
|
||||||
},
|
},
|
||||||
onReset(context: any) { },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||||
let columns: any[] = [{ type: "seq", width: 50 }];
|
let columns: any[] = [{ type: 'seq', width: 50 }];
|
||||||
if (props.multiple) {
|
if (props.multiple) {
|
||||||
columns.push({ type: "checkbox", title: "用户ID", width: 150 });
|
columns.push({ type: 'checkbox', title: '用户ID', width: 150 });
|
||||||
}
|
}
|
||||||
columns = columns.concat([
|
columns = [
|
||||||
{ field: "EMPLOYEE_NAME", title: "用户姓名", width: 120 },
|
...columns,
|
||||||
{ field: "EMPLOYEE_GENDER", title: "性别", width: 80 },
|
{ field: 'EMPLOYEE_NAME', title: '用户姓名', width: 120 },
|
||||||
{ field: "MAIL_ADDRESS", title: "邮箱", width: 150 },
|
{ field: 'EMPLOYEE_GENDER', title: '性别', width: 80 },
|
||||||
{ field: "PHONE_NUM", title: "联系方式", width: 120 },
|
{ field: 'MAIL_ADDRESS', title: '邮箱', width: 150 },
|
||||||
{ field: "ORG_NAME", title: "所属组织", minWidth: 120 },
|
{ field: 'PHONE_NUM', title: '联系方式', width: 120 },
|
||||||
]);
|
{ field: 'ORG_NAME', title: '所属组织', minWidth: 120 },
|
||||||
|
];
|
||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Hooks - 表格 */
|
/** Hooks - 表格 */
|
||||||
const gridOptions = reactive(
|
const gridOptions = reactive(
|
||||||
gridProps({
|
gridProps({
|
||||||
height: "400px",
|
height: '400px',
|
||||||
columns: getColumns(),
|
columns: getColumns(),
|
||||||
pagerConfig: { size: "mini" },
|
pagerConfig: { size: 'mini' },
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
autoLoad: true,
|
autoLoad: true,
|
||||||
ajax: {
|
ajax: {
|
||||||
|
@ -101,10 +108,10 @@ const gridOptions = reactive(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
keyField: "ACCOUNT_ID",
|
keyField: 'ACCOUNT_ID',
|
||||||
},
|
},
|
||||||
checkboxConfig: {
|
checkboxConfig: {
|
||||||
labelField: "ACCOUNT_ID",
|
labelField: 'ACCOUNT_ID',
|
||||||
// 取消显示全选头部按钮
|
// 取消显示全选头部按钮
|
||||||
showHeader: false,
|
showHeader: false,
|
||||||
highlight: true,
|
highlight: true,
|
||||||
|
@ -112,14 +119,19 @@ const gridOptions = reactive(
|
||||||
// 保留勾选状态
|
// 保留勾选状态
|
||||||
reserve: true,
|
reserve: true,
|
||||||
checkMethod: ({ row }) => {
|
checkMethod: ({ row }) => {
|
||||||
let checkRecordIds = checkRecords.value.map((item) => item.ACCOUNT_ID);
|
const checkRecordIds = checkRecords.value.map(
|
||||||
if (checkRecords.value.length < 10 || checkRecordIds.includes(row.ACCOUNT_ID)) {
|
(item) => item.ACCOUNT_ID,
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
checkRecords.value.length < limitMultipleNum.value ||
|
||||||
|
checkRecordIds.includes(row.ACCOUNT_ID)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 转换树行数据的方法
|
// 转换树行数据的方法
|
||||||
|
@ -143,7 +155,7 @@ function transTree(list) {
|
||||||
const children = list.filter((data) => data.PARENT_ID === item.ORG_ID);
|
const children = list.filter((data) => data.PARENT_ID === item.ORG_ID);
|
||||||
|
|
||||||
// 如果没有子节点,直接 return 不做任何处理
|
// 如果没有子节点,直接 return 不做任何处理
|
||||||
if (!children.length) return;
|
if (children.length === 0) return;
|
||||||
|
|
||||||
// 将返回的子级进行赋值给父级(item)的 children 属性
|
// 将返回的子级进行赋值给父级(item)的 children 属性
|
||||||
item.children = children;
|
item.children = children;
|
||||||
|
@ -159,37 +171,37 @@ function transferFormData() {
|
||||||
subFilter: [] as any[],
|
subFilter: [] as any[],
|
||||||
};
|
};
|
||||||
|
|
||||||
let values = searchRef.value?.formData;
|
const values = searchRef.value?.formData;
|
||||||
|
|
||||||
if (values.name) {
|
if (values.name) {
|
||||||
form.subFilter.push({
|
form.subFilter.push({
|
||||||
symbol: "like",
|
symbol: 'like',
|
||||||
singleValue: `%${values.name || ""}%`,
|
singleValue: `%${values.name || ''}%`,
|
||||||
key: "EMPLOYEE_NAME",
|
key: 'EMPLOYEE_NAME',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.id) {
|
if (values.id) {
|
||||||
form.subFilter.push({
|
form.subFilter.push({
|
||||||
symbol: "like",
|
symbol: 'like',
|
||||||
singleValue: `%${values.id || ""}%`,
|
singleValue: `%${values.id || ''}%`,
|
||||||
key: "ACCOUNT_ID",
|
key: 'ACCOUNT_ID',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (form.subFilter.length == 2) {
|
if (form.subFilter.length === 2) {
|
||||||
form.subFilter[1].logic = "AND";
|
form.subFilter[1].logic = 'AND';
|
||||||
}
|
}
|
||||||
|
|
||||||
let newForm: any = {};
|
const newForm: any = {};
|
||||||
|
|
||||||
if (treeItemKey.value && treeItemKey.value.length) {
|
if (treeItemKey.value && treeItemKey.value.length > 0) {
|
||||||
newForm.subFilter = [
|
newForm.subFilter = [
|
||||||
{
|
{
|
||||||
symbol: "like",
|
symbol: 'like',
|
||||||
singleValue: treeItemKey.value[0],
|
singleValue: treeItemKey.value[0],
|
||||||
key: "ORG_ID",
|
key: 'ORG_ID',
|
||||||
logic: "AND",
|
logic: 'AND',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -204,22 +216,22 @@ function transferFormData() {
|
||||||
|
|
||||||
async function loadDataByDept() {
|
async function loadDataByDept() {
|
||||||
try {
|
try {
|
||||||
let data = await Apis.api.core.orgemplbc.organization.post_paging({
|
const data = await Apis.api.core.orgemplbc.organization.post_paging({
|
||||||
params: { page: 1, size: 1000 },
|
params: { page: 1, size: 1000 },
|
||||||
data: {
|
data: {
|
||||||
subFilter: [
|
subFilter: [
|
||||||
{
|
{
|
||||||
symbol: "like",
|
symbol: 'like',
|
||||||
singleValue: "0001%",
|
singleValue: '0001%',
|
||||||
key: "ORG_ID",
|
key: 'ORG_ID',
|
||||||
logic: "AND",
|
logic: 'AND',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
treeData.value = transTree(data.rows);
|
treeData.value = transTree(data.rows);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(err);
|
logger.error('loadDataByDept error', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +239,7 @@ async function loadDataByDept() {
|
||||||
* 单元行点击事件
|
* 单元行点击事件
|
||||||
*/
|
*/
|
||||||
function handleCellClick({ row }) {
|
function handleCellClick({ row }) {
|
||||||
console.log(row);
|
emit('rowClick', {
|
||||||
emit("rowClick", {
|
|
||||||
...row,
|
...row,
|
||||||
label: row.EMPLOYEE_NAME,
|
label: row.EMPLOYEE_NAME,
|
||||||
value: row.ACCOUNT_ID,
|
value: row.ACCOUNT_ID,
|
||||||
|
@ -238,11 +249,10 @@ function handleCellClick({ row }) {
|
||||||
|
|
||||||
const currTypeData = ref<any>({});
|
const currTypeData = ref<any>({});
|
||||||
|
|
||||||
const treeItemTitle = ref("");
|
const treeItemTitle = ref('');
|
||||||
|
|
||||||
function handleTreeSelectChange(keys, opts) {
|
function handleTreeSelectChange(keys) {
|
||||||
console.log("keys", keys, opts);
|
if (keys.length > 0) {
|
||||||
if (keys.length) {
|
|
||||||
const treeItem = keys[0];
|
const treeItem = keys[0];
|
||||||
treeItemKey.value = keys;
|
treeItemKey.value = keys;
|
||||||
treeItemTitle.value = treeItem.label;
|
treeItemTitle.value = treeItem.label;
|
||||||
|
@ -250,15 +260,15 @@ function handleTreeSelectChange(keys, opts) {
|
||||||
Object.assign(currTypeData.value, treeItem);
|
Object.assign(currTypeData.value, treeItem);
|
||||||
isEditMenu.value = true;
|
isEditMenu.value = true;
|
||||||
checkedId.value = treeItem.id;
|
checkedId.value = treeItem.id;
|
||||||
triggerProxy("reload");
|
triggerProxy('reload');
|
||||||
} else {
|
} else {
|
||||||
currTypeData.value = {};
|
currTypeData.value = {};
|
||||||
checkedId.value = 0;
|
checkedId.value = 0;
|
||||||
isEditMenu.value = false;
|
isEditMenu.value = false;
|
||||||
treeItemKey.value = [];
|
treeItemKey.value = [];
|
||||||
treeItemTitle.value = "";
|
treeItemTitle.value = '';
|
||||||
// searchParams.type = undefined;
|
// searchParams.type = undefined;
|
||||||
triggerProxy("reload");
|
triggerProxy('reload');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -266,14 +276,14 @@ function handleTreeSelectChange(keys, opts) {
|
||||||
* @param e
|
* @param e
|
||||||
*/
|
*/
|
||||||
function handleCheckboxChange(e) {
|
function handleCheckboxChange(e) {
|
||||||
let currRows = xGridRef.value?.getCheckboxRecords() || [];
|
const currRows = xGridRef.value?.getCheckboxRecords() || [];
|
||||||
let otherRows = xGridRef.value?.getCheckboxReserveRecords() || [];
|
const otherRows = xGridRef.value?.getCheckboxReserveRecords() || [];
|
||||||
let allRows = [...currRows, ...otherRows];
|
const allRows = [...currRows, ...otherRows];
|
||||||
console.log("e>", e);
|
|
||||||
console.log("allRows", allRows);
|
|
||||||
|
|
||||||
if (e.checked) {
|
if (e.checked) {
|
||||||
const existingIds = new Set(checkRecords.value.map((item) => item.ACCOUNT_ID));
|
const existingIds = new Set(
|
||||||
|
checkRecords.value.map((item) => item.ACCOUNT_ID),
|
||||||
|
);
|
||||||
|
|
||||||
if (!existingIds.has(e.row.ACCOUNT_ID)) {
|
if (!existingIds.has(e.row.ACCOUNT_ID)) {
|
||||||
checkRecords.value = [...checkRecords.value, e.row];
|
checkRecords.value = [...checkRecords.value, e.row];
|
||||||
|
@ -282,43 +292,46 @@ function handleCheckboxChange(e) {
|
||||||
handleCloseTag(e.row);
|
handleCloseTag(e.row);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("[ checkRecords.value ] >", checkRecords.value);
|
console.log('[ checkRecords.value ] >', checkRecords.value);
|
||||||
if (allRows.length >= 10) {
|
if (allRows.length >= limitMultipleNum.value) {
|
||||||
messageApi.warning("最多只能选择10条数据");
|
messageApi.warning(`最多只能选择${limitMultipleNum.value}条数据`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCloseTag(row) {
|
function handleCloseTag(row) {
|
||||||
checkRecords.value = checkRecords.value.filter(
|
checkRecords.value = checkRecords.value.filter(
|
||||||
(item) => item.ACCOUNT_ID != row.ACCOUNT_ID
|
(item) => item.ACCOUNT_ID != row.ACCOUNT_ID,
|
||||||
);
|
);
|
||||||
xGridRef.value?.setCheckboxRow(row, false);
|
xGridRef.value?.setCheckboxRow(row, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = ref("选择人员");
|
const title = ref('选择人员');
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
data.value = modalApi.getData<Record<string, any>>() || {};
|
data.value = modalApi.getData<Record<string, any>>() || {};
|
||||||
if (data.value.title) {
|
if (data.value.title) {
|
||||||
title.value = data.value.title
|
title.value = data.value.title;
|
||||||
}
|
}
|
||||||
console.log(data.value.userIds)
|
// canMultiple.value = data.value.multiple || false;
|
||||||
let rows: any = []
|
if (data.value.limitMultipleNum) {
|
||||||
|
limitMultipleNum.value = data.value.limitMultipleNum;
|
||||||
|
}
|
||||||
|
console.log(data.value.userIds);
|
||||||
|
const rows: any = [];
|
||||||
for (const element of checkRecords.value) {
|
for (const element of checkRecords.value) {
|
||||||
if (data.value.userIds.includes(element.ACCOUNT_ID)) {
|
if (data.value.userIds.includes(element.ACCOUNT_ID)) {
|
||||||
rows.push(element)
|
rows.push(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkRecords.value = rows
|
checkRecords.value = rows;
|
||||||
//
|
//
|
||||||
loadDataByDept();
|
loadDataByDept();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onConfirm() {
|
onConfirm() {
|
||||||
console.info("onConfirm");
|
emit('confirm', checkRecords.value);
|
||||||
emit("confirm", checkRecords.value);
|
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
},
|
},
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
@ -328,11 +341,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal :title="title">
|
<Modal :title="title">
|
||||||
<div v-if="props.multiple" class="flex flex-row py-12px">
|
<div v-if="props.multiple || canMultiple" class="py-12px flex flex-row">
|
||||||
<span class="block mr-12px">已选择:</span>
|
<span class="mr-12px block">已选择:</span>
|
||||||
<div class="flex flex-row flex-1">
|
<div class="flex flex-1 flex-row">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-tag v-for="(item, index) in checkRecords" :key="index" closable @close="handleCloseTag(item)">
|
<a-tag
|
||||||
|
v-for="(item, index) in checkRecords"
|
||||||
|
:key="index"
|
||||||
|
closable
|
||||||
|
@close="handleCloseTag(item)"
|
||||||
|
>
|
||||||
{{ item.EMPLOYEE_NAME }}-{{ item.ACCOUNT_ID }}
|
{{ item.EMPLOYEE_NAME }}-{{ item.ACCOUNT_ID }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
@ -340,14 +358,24 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
</div>
|
</div>
|
||||||
<a-row class="h-full">
|
<a-row class="h-full">
|
||||||
<a-col :span="5" class="">
|
<a-col :span="5" class="">
|
||||||
<a-tree class="draggable-tree" block-node autoExpandParent :tree-data="treeData" @select="handleTreeSelectChange" />
|
<a-tree
|
||||||
|
:tree-data="treeData"
|
||||||
|
auto-expand-parent
|
||||||
|
block-node
|
||||||
|
class="draggable-tree"
|
||||||
|
@select="handleTreeSelectChange"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="19" class="flex flex-col">
|
<a-col :span="19" class="flex flex-col">
|
||||||
<fs-search ref="searchRef" v-bind="searchBinding"> </fs-search>
|
<fs-search ref="searchRef" v-bind="searchBinding" />
|
||||||
<div class="flex-1 min-h-300px">
|
<div class="min-h-300px flex-1">
|
||||||
<VxeGrid ref="xGridRef" class="h-420px" v-bind="gridOptions" @cell-click="handleCellClick"
|
<VxeGrid
|
||||||
@checkbox-change="handleCheckboxChange">
|
ref="xGridRef"
|
||||||
</VxeGrid>
|
class="h-420px"
|
||||||
|
v-bind="gridOptions"
|
||||||
|
@cell-click="handleCellClick"
|
||||||
|
@checkbox-change="handleCheckboxChange"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
|
@ -164,6 +164,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),
|
||||||
|
@ -384,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: {
|
||||||
/** 合同系统/立项 合同立项保存 */
|
/** 合同系统/立项 合同立项保存 */
|
||||||
|
@ -780,4 +789,12 @@ export default {
|
||||||
/** 合同系统/首页待办/已办 待办 */
|
/** 合同系统/首页待办/已办 待办 */
|
||||||
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
get_todo: (data?: QueryOptions) => http.get('/app/home/todo', data),
|
||||||
},
|
},
|
||||||
|
sqConsignPt: {
|
||||||
|
/** 合同系统/签约授权 签约授权保存 */
|
||||||
|
post_saveSignMultiEntity: (data?: BodyOptions) =>
|
||||||
|
http.post('/app/sqConsignPt/saveSignMultiEntity', data),
|
||||||
|
/** 合同系统/签约授权 签约依据查询 */
|
||||||
|
get_SigningaAuthorizationSerch: (data?: QueryOptions) =>
|
||||||
|
http.get('/app/sqConsignPt/SigningaAuthorizationSerch', data),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue