签约依据功能完善

This commit is contained in:
z9130 2024-09-12 16:40:37 +08:00
parent b1707302e9
commit 9decfcb729
17 changed files with 602 additions and 438 deletions

View File

@ -505,5 +505,12 @@ export default {
/** 协同办公/督查督办/反馈记录 删除反馈记录 */
post_deletes: (data?: BodyOptions) => http.post("/app/superviseFeedbackRecord/deletes", data),
},
lxBasisSale: {
/** 合同系统/签约依据 分页保存/修改 */
post_save: (data?: BodyOptions) => http.post("/app/lxBasisSale/save", data),
/** 合同系统/签约依据 查询 */
get_page: (data?: QueryOptions) => http.get("/app/lxBasisSale/page", data),
/** 合同系统/签约依据 删除测试 */
post_deletes: (data?: BodyOptions) => http.post("/app/lxBasisSale/deletes", data),
},
}

View File

@ -7,6 +7,8 @@ export const unitComponentProps = {
allowClear: true,
class: 'min-w-[180px]',
showCheckedStrategy: "SHOW_CHILD",
showSearch: true,
"tree-node-filter-prop": "label",
dict: dict({
isTree: true,
async getData(dict, context) {

View File

@ -134,6 +134,7 @@ function handleMenuClick(e) {
<a-menu-item key="czg"> czg </a-menu-item>
<a-menu-item key="zp"> zp </a-menu-item>
<a-menu-item key="zzz"> zzz </a-menu-item>
<a-menu-item key="xmh"> xmh </a-menu-item>
</a-menu>
</template>
<a-button> {{ value ? "代理" + value : "代理切换" }} </a-button>

View File

@ -1,17 +1,9 @@
<template>
<Page contentClass="h-full flex flex-col">
<a-alert
v-if="isOneDay"
:message="`${isOneDay},共订餐 ${collectData.count} 人,其中食堂就餐 ${collectData.eatInCount} 人,保温派送
<a-alert v-if="isOneDay" :message="`${isOneDay}共订餐 ${collectData.count} 其中食堂就餐 ${collectData.eatInCount} 保温派送
${collectData.deliveryCount}
`"
type="info"
/>
<a-alert
v-else
message="当开始日期和截止日期为同一天时会显示该天总的订餐情况"
type="info"
/>
`" type="info" />
<a-alert v-else message="当开始日期和截止日期为同一天时会显示该天总的订餐情况" type="info" />
<fs-search ref="searchRef" v-bind="searchForm"> </fs-search>
@ -219,7 +211,7 @@ const searchForm = ref({
class: 'min-w-[180px]',
allowClear: true,
dict: dict({
async getData(dict, context) {
async getData(form) {
return getDictOptions(DICT_TYPE.canteen_dineway);
},
}),

View File

@ -12,37 +12,60 @@
<a-card class="mt-4 flex-1" title="订餐" size="small" :loading="isLoading">
<!-- {{ isOpening }}\ {{ ip }}\ {{ location }} -->
<a-alert v-if="isEated" message="今日已订餐" type="info" >
<template #description>
就餐方式{{
getDictObj(DICT_TYPE.canteen_dineway, todayOrderInfo.diningMode)
?.label
}}
<br />
<p v-if="todayOrderInfo.diningMode==='delivery'">主食{{
getDictObj(
DICT_TYPE.canteen_staplefood,
todayOrderInfo.stapleFood
)?.label
}}</p>
<p v-if="todayOrderInfo.diningMode==='delivery'">派送地址{{ todayOrderInfo.address }}</p>
</template>
</a-alert>
<div v-if="
isOpening &&
(todayRecipeInfo.deliveryOpen == '1' ||
todayRecipeInfo.eatinOpen == '1') &&
(location == 'basic' || location == 'government')
" class="bg-white rounded-xl p-10 max-w-lg w-full space-y-10 mx-auto mt-8">
<h2 class="text-3xl font-bold text-center">选择就餐方式</h2>
<div class="flex justify-center space-x-4">
<button v-if="location == 'government'" :disabled="todayRecipeInfo.eatinOpen != '1'"
@click="selectOption('eat-in')" :class="dineInClass"
class="px-6 py-3 rounded-md shadow focus:outline-none transition duration-300">食堂就餐</button>
<button @click="selectOption('delivery')" :disabled="todayRecipeInfo.deliveryOpen != '1'"
:class="deliveryClass"
class="px-6 py-3 rounded-md shadow focus:outline-none transition duration-300">保温派送</button>
</div>
<div v-if="showAddress" class="text-center text-base">
<p class="mt-4 mb-2">派送地址</p>
<button v-if="addressInfo.addressId" class="text-blue-500 underline" @click="handleOpenAddress">{{
getDictObj(
DICT_TYPE.canteen_staplefood,
addressInfo.stapleFood
)!.label }}{{ addressInfo.address }} [更改]</button>
<button v-else class="text-blue-500 underline" @click="handleOpenAddress">[点击选择地址]</button>
<template v-if="!isEated">
<h2 class="text-3xl font-bold text-center">选择就餐方式</h2>
<div class="flex justify-center space-x-4">
<button v-if="location == 'government'" :disabled="todayRecipeInfo.eatinOpen != '1'"
@click="selectOption('eat-in')" :class="dineInClass"
class="px-6 py-3 rounded-md shadow focus:outline-none transition duration-300">食堂就餐</button>
<button @click="selectOption('delivery')" :disabled="todayRecipeInfo.deliveryOpen != '1'"
:class="deliveryClass"
class="px-6 py-3 rounded-md shadow focus:outline-none transition duration-300">保温派送</button>
</div>
<div v-if="showAddress" class="text-center text-base">
<p class="mt-4 mb-2">派送地址</p>
<button v-if="addressInfo.addressId" class="text-blue-500 underline" @click="handleOpenAddress">{{
getDictObj(
DICT_TYPE.canteen_staplefood,
addressInfo.stapleFood
)!.label }}{{ addressInfo.address }} [更改]</button>
<button v-else class="text-blue-500 underline" @click="handleOpenAddress">[点击选择地址]</button>
</div>
</div>
</template>
<div class="text-center mt-8">
<button v-if="!isEated"
class="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-4 px-14 rounded-full shadow-lg transition duration-300"
@click="handleOrder('confirm')">订餐</button>
<button v-else
class="bg-orange-600 hover:bg-blue-700 text-white font-semibold py-4 px-14 rounded-full shadow-lg transition duration-300"
class="bg-orange-600 hover:bg-orange-700 text-white font-semibold py-4 px-14 rounded-full shadow-lg transition duration-300"
@click="handleOrder('cancel')">取消订餐</button>
</div>
</div>
@ -70,7 +93,7 @@
<p v-if="showHelpMessageCount >= 3" class="gray-600" style="margin: 8px 0 0 0">
<span class="text-sm text-gray-600 block mt-8px">当前环境IP: {{ ip }} , 所属单位类型{{
getUserTypeName(location)
}}</span>
}}</span>
</p>
</div>
</template>
@ -172,7 +195,7 @@ const orderTimeArr = ref<any[]>([]);
const showHelpMessageCount = ref(0);
const debuggerLocation = ref("basic"); // basic government
const debuggerLocation = ref("government"); // basic government
let location = ref("");
const isOpening = computed<boolean>(() => {
@ -218,7 +241,7 @@ const todayOrderInfo = ref({})
const autoPeopleInfo = ref({});
let isLoading = ref(false)
function loadTodayOrderInfo() {
async function loadTodayOrderInfo() {
isLoading.value = true;
const userStore = useUserStore();
Apis.orderfood.get_getOne({
@ -352,12 +375,7 @@ function handleOrder(type: "confirm" | "cancel") {
message.error("请选择就餐方式");
return;
}
if (!form.stapleFood) {
message.error("请选择派送地址");
return;
}
//
if (
location.value &&
form.diningMode == "delivery" &&
@ -367,32 +385,27 @@ function handleOrder(type: "confirm" | "cancel") {
return;
}
if (form.diningMode != "delivery") {
if (form.diningMode === "eat-in") {
delete form.addressId;
delete form.address;
} else {
// for (const item of addressData) {
// if (item.id == submitForm.value.address) {
// submitForm.value.address = item.label
// }
// }
delete form.stapleFood
}
console.log(submitForm.value)
console.log("提交表单", form);
isLoading.value = true
form.guid = todayOrderInfo.value.guid
Apis.orderfood.post_save({
data: { guid: todayOrderInfo.value.guid }
data: form
}).then(() => {
message.success("订餐成功")
loadTodayOrderInfo();
}).finally(() => {
isLoading.value = false
// isLoading.value = false
})
}
@ -404,7 +417,7 @@ function handleOrder(type: "confirm" | "cancel") {
message.success("订餐取消成功")
loadTodayOrderInfo();
}).finally(() => {
isLoading.value = false
// isLoading.value = false
})
}
}

View File

@ -141,7 +141,6 @@ export function getFormSchema(params: any = {}) {
min: 0,
max: 9999,
},
},
priceType: {
title: '',

View File

@ -3,9 +3,30 @@ import { useRender } from '#/hooks/useRender';
import dayjs from 'dayjs';
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
import { dict } from '@fast-crud/fast-crud';
import Apis from '#/api'
export const PrimaryKey = 'guid';
/**
*
*
*/
async function filterContractTypes(parentId: string) {
try {
let contractReferTypeData = await Apis.contractReferType.get_list({ params: {} })
return contractReferTypeData.rows.map((item) => {
item.label = item.contrLevelName;
item.value = item.contrLevelId;
return item;
}).filter((item) => item.parentId === parentId);
} catch (error) {
console.log(error)
return []
}
}
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
return [
{ type: 'radio', width: 40, slots: { radio: 'radio_cell' }, align: 'center', fixed: 'left' },
@ -42,6 +63,7 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
}
}
},
{ field: 'createTime', title: '申报时间', width: 130 },
{ field: 'inputPerson', title: '承办人', width: 100 },
{ field: 'inputDepartName', title: '承办部门', width: 100 },
{ field: 'inputDate', title: '承办时间', width: 130 },
@ -56,6 +78,7 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
}
export function getFormSchema(_params: any = {}) {
return {
initialForm: {
},
@ -116,16 +139,31 @@ export function getFormSchema(_params: any = {}) {
return (
<div class="flex">
<a-form-item class="inline-block !mb-0">
<a-date-picker v-model:value={form.startTime} placeholder="" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
<a-date-picker v-model:value={form.startDate} placeholder="" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
</a-form-item>
<span class="mx-1"></span>
<a-form-item class="inline-block !mb-0">
<a-date-picker v-model:value={form.endTime} placeholder="" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
<a-date-picker v-model:value={form.endDate} placeholder="" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
</a-form-item>
</div>
);
}
}
},
ctrType: {
title: "合同类别",
key: "ctrType",
show: true,
component: {
name: "fs-dict-select",
vModel: "value",
class: 'min-w-[200px]',
dict: dict({
async getData({ form = {} }) {
return await filterContractTypes("-1");
},
}),
}
},
},
};
}

View File

@ -55,6 +55,13 @@ const [_Modal, modalApi] = useVbenModal({
},
});
const searchFormBinding = ref({
...getFormSchema(),
onSearch(context: any) {
triggerProxy('reload')
}
});
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
@ -132,16 +139,11 @@ function handleCellClick({ row }) {
setSelectRow(row);
}
onMounted(() => {
onMounted(async () => {
triggerProxy('reload')
})
const searchForm = ref({
...getFormSchema(),
onSearch(context: any) {
triggerProxy('reload')
}
});
function toPage() {
window.open("/iframe/meeting/standing-book", "_blank");
@ -156,7 +158,7 @@ function toDetail(row) {
<template>
<Page contentClass="h-full flex flex-col">
<fs-search ref="searchRef" v-bind="searchForm">
<fs-search ref="searchRef" v-bind="searchFormBinding">
<template #form_price="{ row }">
<a-input-number v-model:value="row.budgetSum1" placeholder="">
</a-input-number>

View File

@ -1,28 +1,32 @@
import type { VxeGridPropTypes } from 'vxe-table';
import { useRender } from '#/hooks/useRender';
import dayjs from 'dayjs';
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
import { dict } from '@fast-crud/fast-crud';
export const PrimaryKey = 'guid';
export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
export function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
let columns: VxeGridPropTypes.Columns = [
{ field: 'basisId', title: '依据号', width: 130 },
{
field: 'meetingTheme',
title: '依据号',
minWidth: 300,
},
{
field: 'meetingDate',
field: 'basisName',
title: '依据名称',
width: 200,
},
{ field: 'meetingType', title: '依据编号', width: 120 },
{ field: 'compere', title: '有效期', width: 80 },
{ field: 'compere2', title: '创建人', width: 80 },
{ field: 'compere1', title: '创建时间', width: 80 },
{ field: 'remarks', title: '备注', width: 80 },
{ field: 'basisNum', title: '依据编号', width: 180 },
{
field: 'endDate', title: '有效期', width: 150, slots: {
default: ({ row }) => {
return useRender.renderDate(row.endDate, 'YYYY-MM-DD');
}
}
},
{ field: 'inputPerson', title: '创建人', width: 150 },
{
field: 'inputDate', title: '创建时间', width: 150, slots: {
default: ({ row }) => {
return useRender.renderDate(row.inputDate, 'YYYY-MM-DD');
}
}
},
{ field: 'remark', title: '备注', minWidth: 200 },
]
return columns;
@ -31,42 +35,11 @@ export function getColumns(params: any = {}): VxeGridPropTypes.Columns {
export function getFormSchema(_params: any = {}) {
return {
initialForm: {
startDate: dayjs().startOf('month').format("YYYY-MM-DD"),
},
columns: {
startDate: {
title: '开始日期',
key: 'startDate',
component: {
name: 'a-date-picker',
vModel: 'value',
allowClear: true,
props: {
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
},
},
autoSearchTrigger: 'enter',
show: true,
},
endDate: {
title: '截止日期',
key: 'endDate',
component: {
name: 'a-date-picker',
vModel: 'value',
allowClear: true,
props: {
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
},
},
autoSearchTrigger: 'enter',
show: true,
},
meetingTheme: {
title: '会议主题',
key: 'meetingTheme',
basisName: {
title: '依据名称',
key: 'basisName',
component: {
name: 'a-input',
vModel: 'value',
@ -75,36 +48,38 @@ export function getFormSchema(_params: any = {}) {
autoSearchTrigger: 'enter',
show: true,
},
meetingId: {
title: '会议室',
key: 'meetingId',
basisNum: {
title: '依据编号',
key: 'basisNum',
component: {
name: 'fs-dict-select',
name: 'a-input',
vModel: 'value',
class: 'min-w-[180px]',
allowClear: true,
dict: dict({
async getData(dict, context) {
return getDictOptions(DICT_TYPE.meeting_room);
},
}),
},
autoSearchTrigger: 'enter',
show: true,
},
meetingType: {
title: '会议类型',
key: 'meetingType',
inputPerson: {
title: '创建人',
key: 'inputPerson',
component: {
name: 'fs-dict-select',
name: 'a-input',
vModel: 'value',
class: 'min-w-[180px]',
allowClear: true,
dict: dict({
async getData(dict, context) {
return getDictOptions(DICT_TYPE.meeting_type);
},
}),
},
autoSearchTrigger: 'enter',
show: true,
},
inputDate: {
title: '创建年份',
key: 'inputDate',
component: {
name: 'a-date-picker',
vModel: 'value',
allowClear: true,
picker: 'year',
format: 'YYYY年',
valueFormat: 'YYYY',
},
autoSearchTrigger: 'enter',
show: true,

View File

@ -1,63 +1,3 @@
<template>
<Page contentClass="h-full flex flex-col">
<fs-search ref="searchRef" v-bind="searchForm"> </fs-search>
<div class="flex-1 min-h-300px">
<vxe-grid ref="xGridRef" v-bind="gridOptions" @cell-click="handleCellClick">
<template #toolbar_buttons>
<a-space>
<vben-button variant="primary" @click="handleAdd()">
<MdiAdd class="text-lg mr-0.5" />
新增
</vben-button>
<vben-button variant="warning" :disabled="!selectRow || !selectRow['guid']"
@click="handleUpdate(selectRow)">
<MdiUpdate class="text-lg mr-0.5" />
修改
</vben-button>
<vben-button variant="primary" @click="handleExport()">
<MdiExport class="text-lg mr-0.5" />
导出
</vben-button>
<vben-button variant="destructive" :disabled="!selectRow || !selectRow['guid']"
@click="handleDelete(selectRow)">
<MdiDelete class="text-lg mr-0.5" />
删除
</vben-button>
<vben-button variant="primary" @click="toPage()">
<span class="icon-[mdi--run] text-lg mr-0.5"></span>
前往会议台账
</vben-button>
</a-space>
</template>
<template #radio_cell="{ row, checked }">
<span class="text-base" @click.stop="setSelectRow(row)">
<MdiRadioChecked v-if="checked" />
<MdiRadioUnchecked v-else />
</span>
</template>
<template #meetingInfoSlot="{ row }">
<p>会议室{{ row.meeting }}</p>
<p>参会时间{{ row.meetingDate }}</p>
</template>
<template #meetingThemeSlot="{ row }">
<p class="cursor-pointer hover:color-blue hover:underline" @click="toDetail(row)">
{{ row.meetingTheme }}
</p>
</template>
<template #operation_cell="{ row }">
<a-button v-if="row.isConfirm == 1" type="text" class="text-orange-500"
@click="handleConfirm(row.guid, 0)">取消落实</a-button>
<a-button v-else type="text" class="text-blue-500" @click="handleConfirm(row.guid, 1)">落实会议</a-button>
</template>
</vxe-grid>
</div>
</Page>
</template>
<script setup lang="ts">
import { defineComponent, ref, computed, reactive, onMounted } from 'vue';
import { FsCrud } from '@fast-crud/fast-crud';
@ -72,7 +12,7 @@ import {
utils,
} from '@fast-crud/fast-crud';
import { MdiAdd, MdiUpdate, MdiDelete, MdiImport, MdiExport, MdiRadioUnchecked, MdiRadioChecked } from '@vben/icons';
import { getFormSchema, getColumns } from './crud.tsx';
import { getFormSchema, getColumns, PrimaryKey } from './crud.tsx';
import { dict } from "@fast-crud/fast-crud";
import { getMonthStartAndEnd } from '#/utils/time'
import Apis from '#/api'
@ -81,54 +21,13 @@ import { message } from "ant-design-vue";
import { Modal } from 'ant-design-vue';
import { useRouter } from 'vue-router'
import signingBasisEditModal from './signing-basis-edit-modal.vue';
const router = useRouter();
const checkedValue = ref('all')
const exportSearchParams = ref<any>({
daterange: getMonthStartAndEnd(),
});
const radioStyle = reactive({
display: 'flex',
height: '30px',
lineHeight: '30px',
const [EditModal, editModalApi] = useVbenModal({
connectedComponent: signingBasisEditModal,
});
const searchRef = ref()
let isConfirmLoading = ref(false)
const [_Modal, modalApi] = useVbenModal({
async onConfirm() {
isConfirmLoading.value = true
try {
let params = {};
if (checkedValue.value == "daterange") {
params = {
startDate: exportSearchParams.value.daterange[0],
endDate: exportSearchParams.value.daterange[1],
};
}
let res = await Apis.zbgl.post_export({
params: params, config: {
meta: {
responseType: 'blob'
}
}
}).send();
message.success("导出成功");
modalApi.close()
showExportModal.value = false;
} catch (error) {
console.error(error);
} finally {
isConfirmLoading.value = false
}
console.info("onConfirm");
},
});
const { xGridRef, triggerProxy, gridProps } = useVxeTable({ ref: 'xGridRef' });
@ -142,7 +41,7 @@ const gridOptions = reactive(gridProps({
autoLoad: false,
ajax: {
query: ({ page }) => {
return Apis.meeting.get_page({ params: { pageNum: page.currentPage, pageSize: page.pageSize, ...searchRef.value?.formData } })
return Apis.lxBasisSale.get_page({ params: { pageNum: page.currentPage, pageSize: page.pageSize, ...searchRef.value?.formData } })
}
},
},
@ -154,26 +53,15 @@ const gridOptions = reactive(gridProps({
},
}));
function handleAdd() {
router.push('/meeting/edit')
function handleEdit(record?: any) {
editModalApi.setData({
isUpdate: Boolean(record && record[PrimaryKey]),
record: JSON.parse(JSON.stringify(record || {})),
})
editModalApi.open()
}
function handleUpdate(row) {
router.push('/meeting/edit/' + row['guid'])
}
async function handleConfirm(id, isConfirm) {
let hideLoading = message.loading("正在保存中...");
try {
await Apis.meeting.post_save({ data: { guid: id, isConfirm: isConfirm } }).send();
message.success("保存成功");
triggerProxy("reload");
} catch (error) {
console.log("[ error ] >", error);
} finally {
hideLoading();
}
}
function handleDelete(row) {
Modal.confirm({
@ -181,7 +69,7 @@ function handleDelete(row) {
content: "是否确认删除该条记录?",
okType: 'danger',
onOk: async () => {
await Apis.meeting.post_deletes({ params: { ids: row['guid'] } })
await Apis.lxBasisSale.post_deletes({ params: { ids: row['guid'] } })
message.success("删除成功");
triggerProxy("reload");
},
@ -202,12 +90,12 @@ function handleExport() {
}
/** 选中数据 */
const selectRow: Recordable = computed(() => {
const selectRow: any = computed(() => {
return xGridRef.value?.getRadioRecord() || null;
});
/** 单选框选中事件 */
const setSelectRow = (row: Recordable) => {
const setSelectRow = (row: any) => {
if (selectRow.value && selectRow.value['guid'] === row['guid']) {
xGridRef.value?.clearRadioRow();
} else {
@ -224,27 +112,55 @@ onMounted(() => {
triggerProxy('reload')
})
let searchParams = reactive({})
const searchForm = ref({
...getFormSchema(),
onSearch(context: any) {
console.log(searchRef.value)
triggerProxy('reload')
},
onReset(context: any) {
searchParams = context.form
},
}
});
function toPage() {
window.open("/iframe/meeting/standing-book", "_blank");
}
function toDetail(row) {
window.open("/iframe/meeting/start/" + row.guid, "_blank");
}
//
</script>
<template>
<Page contentClass="h-full flex flex-col">
<EditModal class="w-[600px] max-w-[80vw]" @success="triggerProxy('reload')" />
<fs-search ref="searchRef" v-bind="searchForm"> </fs-search>
<div class="flex-1 min-h-300px">
<vxe-grid ref="xGridRef" v-bind="gridOptions" @cell-click="handleCellClick">
<template #toolbar_buttons>
<a-space>
<vben-button variant="primary" @click="handleEdit()">
<MdiAdd class="text-lg mr-0.5" />
新增
</vben-button>
<vben-button variant="warning" :disabled="!selectRow || !selectRow['guid']" @click="handleEdit(selectRow)">
<MdiUpdate class="text-lg mr-0.5" />
修改
</vben-button>
<vben-button variant="primary" @click="handleExport()">
<MdiExport class="text-lg mr-0.5" />
导出
</vben-button>
<vben-button variant="destructive" :disabled="!selectRow || !selectRow['guid']"
@click="handleDelete(selectRow)">
<MdiDelete class="text-lg mr-0.5" />
删除
</vben-button>
</a-space>
</template>
<template #radio_cell="{ row, checked }">
<span class="text-base" @click.stop="setSelectRow(row)">
<MdiRadioChecked v-if="checked" />
<MdiRadioUnchecked v-else />
</span>
</template>
</vxe-grid>
</div>
</Page>
</template>
<style></style>

View File

@ -1,13 +1,164 @@
<template>
<div>
<script lang="tsx" setup>
import { ref, nextTick } from "vue";
import { useVbenModal } from "@vben/common-ui";
import dayjs, { Dayjs } from "dayjs";
import Apis from "#/api";
import { message, type UploadChangeParam } from "ant-design-vue";
import { FileUploader } from "#/utils/file";
</div>
const emit = defineEmits<{
(e: "success"): void;
}>();
const fileUploader = new FileUploader({})
const data = ref({
isUpdate: false,
record: {} as any
});
const formRef = ref();
let isConfirmLoading = ref(false)
const formBinding = ref({
col: { span: 24 },
initialForm: {},
labelCol: { style: { width: '120px' } },
columns: {
basisNum: {
title: "依据编号",
key: "basisNum",
component: {
name: "a-input",
vModel: "value",
},
rules: [{ required: true, message: "请输入依据编号" }],
},
basisName: {
title: "依据名称",
key: "basisName",
component: {
name: "a-input",
vModel: "value",
},
rules: [{ required: true, message: "请输入依据名称" }],
},
endDate: {
title: "有效期",
key: "endDate",
component: {
name: "a-date-picker",
vModel: "value",
allowClear: false,
disabledDate: (current: Dayjs) => {
return current <= dayjs()
},
format: "YYYY-MM-DD",
valueFormat: "YYYY-MM-DD",
},
rules: [{ required: true, message: "请选择有效期" }],
},
remark: {
title: "备注",
key: "remark",
component: {
name: "a-textarea",
vModel: "value",
props: {},
},
},
fileList: {
title: "附件上传",
key: "fileList",
},
}
});
const handleChange = (info: UploadChangeParam) => {
formRef.value.setFormData({
fileList: info.fileList.length ? info.fileList : [],
});
};
const [BaseModal, baseModalApi] = useVbenModal({
async onOpenChange(isOpen: boolean) {
if (isOpen) {
isConfirmLoading.value = false
data.value = baseModalApi.getData<Record<string, any>>() || {};
if (data.value.isUpdate) {
if (data.value.record.fileUuid) {
let files = await fileUploader.select(data.value.record.fileUuid)
console.log(files)
data.value.record.fileList = files
}
nextTick(() => {
formRef.value.setFormData(data.value.record || {});
});
}
}
},
async onConfirm() {
try {
isConfirmLoading.value = true
console.info("onConfirm");
console.log(formRef.value?.form);
await formRef.value?.submit();
let form = formRef.value.form;
{
let tempFileList = form.fileList
let tempFiles: any = []
if (tempFileList && tempFileList.length) {
tempFiles = await fileUploader.upload(tempFileList, { source: 'ht' })
}
console.log(tempFiles)
if (tempFiles) {
form.fileUuid = (tempFiles.map((item) => item.fileUuid) || []).join(',')
}
}
delete form.fileList
await Apis.lxBasisSale.post_save({ data: form })
baseModalApi.close();
message.success("操作成功");
} catch (error) {
console.log(error)
} finally {
isConfirmLoading.value = false
emit("success");
}
},
onCancel() {
baseModalApi.close();
},
});
</script>
<template>
<BaseModal :title="data.isUpdate ? '修改签约依据信息' : '新增签约依据信息'" :loading="isConfirmLoading"
:confirmLoading="isConfirmLoading">
<fs-form ref="formRef" v-bind="formBinding">
<template #form_fileList="{ form }">
<a-upload-dragger v-model:fileList="form.fileList" accept=".pdf" :max-count="1" name="file"
:before-upload="() => false" @change="handleChange">
<div class="flex flex-col items-center">
<MdiCloudUpload class="text-[50px] text-center text-gray-600" />
<p class="ant-upload-text">点击或拖动文件到该区域来上传</p>
<p class="ant-upload-hint">仅支持 pdf 类型的文件</p>
</div>
</a-upload-dragger>
</template>
</fs-form>
</BaseModal>
</template>
<script lang="ts" setup>
</script>
<style>
<style scoped>
:deep(.ant-divider-horizontal.ant-divider-with-text) {
margin: 0 !important;
}
</style>

View File

@ -1,5 +1,6 @@
import { DICT_TYPE, getDictOptions } from "#/utils/dict";
import { dict } from "@fast-crud/fast-crud";
import { render } from "vue";
/**
@ -97,6 +98,65 @@ export function getFormSchema(params: any = {}) {
return <span></span>;
}
},
budgetSum: {
title: '预算金额',
key: 'budgetSum',
col: { span: 5 },
colon: false,
component: {
name: 'a-input-number',
vModel: 'value',
class: 'w-full',
min: 0,
max: 9999,
},
},
priceType: {
title: '',
key: 'priceType',
col: { span: 3 },
labelCol: { style: { width: "12px" } },
colon: false,
component: {
name: 'fs-dict-select',
vModel: 'value',
dict: dict({
data: getDictOptions(DICT_TYPE.contractCurrencyUnit)
}),
},
},
fundAllocation: {
title: "资金流向",
key: "fundAllocation",
col: { span: 8 },
component: {
name: "fs-dict-select",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
dict: dict({
data: getDictOptions(DICT_TYPE.contractFundFlow)
}),
},
rules: [{ required: true, message: "请选择资金流向" }],
},
fundDitch: {
title: "资金渠道",
key: "fundDitch",
col: { span: 8 },
component: {
name: "fs-dict-select",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
dict: dict({
data: getDictOptions(DICT_TYPE.contractFundingSource)
}),
},
rules: [{ required: true, message: "请选择资金渠道" }],
},
frameProtocol: {
title: "框架协议",
key: "frameProtocol",
@ -115,8 +175,8 @@ export function getFormSchema(params: any = {}) {
frameProtocolCtr: {
title: "框架协议下的合同",
key: "frameProtocolCtr",
col: { span: 12 },
labelCol: { style: { width: "200px" } },
col: { span: 8 },
labelCol: { style: { width: "150px" } },
component: {
name: "fs-dict-radio",
vModel: "value",
@ -128,70 +188,12 @@ export function getFormSchema(params: any = {}) {
}),
},
},
fundAllocation: {
title: "资金流向",
key: "fundAllocation",
col: { span: 12 },
component: {
name: "fs-dict-select",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
dict: dict({
data: getDictOptions(DICT_TYPE.contractFundFlow)
}),
},
rules: [{ required: true, message: "请选择资金流向" }],
},
fundDitch: {
title: "资金渠道",
key: "fundDitch",
col: { span: 12 },
component: {
name: "fs-dict-select",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
dict: dict({
data: getDictOptions(DICT_TYPE.contractFundingSource)
}),
},
rules: [{ required: true, message: "请选择资金渠道" }],
},
budgetSum: {
title: '预算金额',
key: 'budgetSum',
col: { span: 8 },
colon: false,
component: {
name: 'a-input-number',
vModel: 'value',
class: 'w-full',
min: 0,
max: 9999,
},
},
priceType: {
title: '',
key: 'priceType',
col: { span: 6 },
labelCol: { style: { width: "12px" } },
colon: false,
component: {
name: 'fs-dict-select',
vModel: 'value',
dict: dict({
data: getDictOptions(DICT_TYPE.contractCurrencyUnit)
}),
},
},
organiza: {
title: "组织式",
title: "组织方式",
key: "organiza",
col: { span: 12 },
col: { span: 8 },
component: {
name: "fs-dict-select",
name: "fs-dict-radio",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
@ -199,11 +201,7 @@ export function getFormSchema(params: any = {}) {
data: getDictOptions(DICT_TYPE.contractOrganizationForm)
}),
},
rules: [{ required: true, message: "请选择组织形式" }],
},
fileList: {
title: "相关附件",
key: "fileList",
rules: [{ required: true, message: "请选择组织方式" }],
},
}

View File

@ -20,7 +20,7 @@ export function getFormSchema(_params: any = {}) {
key: "projectProp",
col: { span: 12 },
component: {
name: "fs-dict-select",
name: "fs-dict-radio",
vModel: "value",
class: 'min-w-[200px]',
dict: dict({
@ -75,6 +75,7 @@ export function getFormSchema(_params: any = {}) {
component: {
name: "a-textarea",
vModel: "value",
autosize: { minRows: 4, maxRows: 6 }
},
},
qualificReq: {
@ -84,6 +85,7 @@ export function getFormSchema(_params: any = {}) {
component: {
name: "a-textarea",
vModel: "value",
autosize: { minRows: 4, maxRows: 6 }
},
},
isBid: {
@ -99,8 +101,8 @@ export function getFormSchema(_params: any = {}) {
// },
render({ form }) {
//注意此处的v-model写法
let options1 = getDictOptions(DICT_TYPE.sectionType,'number')
let options2 = getDictOptions(DICT_TYPE.sectionNum,'number')
let options1 = getDictOptions(DICT_TYPE.sectionType,'string')
let options2 = getDictOptions(DICT_TYPE.sectionNum,'string')
return (
<div class="flex">
@ -117,78 +119,58 @@ export function getFormSchema(_params: any = {}) {
);
}
},
fundAllocation: {
title: "资金流向",
key: "fundAllocation",
col: { span: 12 },
projectRange: {
title: "项目范围",
key: "projectRange",
col: { span: 24 },
component: {
name: "fs-dict-select",
name: "a-textarea",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
dict: dict({
data: getDictOptions(DICT_TYPE.contractFundFlow)
}),
autosize: { minRows: 4, maxRows: 6 }
},
rules: [{ required: true, message: "请选择资金流向" }],
},
fundDitch: {
title: "资金渠道",
key: "fundDitch",
col: { span: 12 },
projectContent: {
title: "项目内容",
key: "projectContent",
col: { span: 24 },
component: {
name: "fs-dict-select",
name: "a-textarea",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
dict: dict({
data: getDictOptions(DICT_TYPE.contractFundingSource)
}),
},
rules: [{ required: true, message: "请选择资金渠道" }],
},
budgetSum: {
title: '预算金额',
key: 'budgetSum',
col: { span: 8 },
colon: false,
component: {
name: 'a-input-number',
vModel: 'value',
class: 'w-full',
min: 0,
max: 9999,
},
},
priceType: {
title: '',
key: 'priceType',
col: { span: 6 },
labelCol: { style: { width: "12px" } },
colon: false,
component: {
name: 'fs-dict-select',
vModel: 'value',
dict: dict({
data: getDictOptions(DICT_TYPE.contractCurrencyUnit)
}),
autosize: { minRows: 4, maxRows: 6 }
},
},
organiza: {
title: "组织形式",
key: "organiza",
col: { span: 12 },
quality: {
title: "工期要求(质量要求)",
key: "quality",
col: { span: 24 },
labelWrap:true,
component: {
name: "fs-dict-select",
name: "a-textarea",
vModel: "value",
allowClear: false,
class: 'min-w-[200px]',
dict: dict({
data: getDictOptions(DICT_TYPE.contractOrganizationForm)
}),
autosize: { minRows: 4, maxRows: 6 }
},
},
stockNums: {
title: "工程量(采购量)",
key: "stockNums",
col: { span: 24 },
labelWrap:true,
component: {
name: "a-textarea",
vModel: "value",
autosize: { minRows: 4, maxRows: 6 }
},
},
stockPlanMx: {
title: "计划投资明细",
key: "stockPlanMx",
col: { span: 24 },
labelWrap:true,
component: {
name: "a-textarea",
vModel: "value",
autosize: { minRows: 4, maxRows: 6 }
},
rules: [{ required: true, message: "请选择组织形式" }],
},
}

View File

@ -46,7 +46,7 @@ const formBinding = ref({
initialForm: {
contractName: '',
priceType: 'CNY',
isBid: 0
isBid: '0'
},
labelCol: { style: { width: "120px" } },
columns: getFormSchema()
@ -148,26 +148,91 @@ async function handleSave() {
isLoading.value = true
try {
let form = formRef.value.form;
console.log(formRef.value)
await formRef.value.submit()
await formRefByBaseInfo.value.submit()
let contractForm = formRefByBaseInfo.value.form;
let bussinessForm = formRef.value.form;
bussinessForm.priceStyleName = getDictObj(DICT_TYPE.contractPriceStyle, bussinessForm.priceStyleId)?.label
bussinessForm.choiceTypeName = getDictObj(DICT_TYPE.contractSelectionMethod, bussinessForm.choiceType)?.label;
//
{
let tempFileList = contractForm.fileList
let tempFiles: any = []
if (fileList && tempFileList.length) {
tempFiles = await fileUploader.upload(tempFileList, { source: 'ht' })
}
console.log(tempFiles)
if (tempFiles) {
contractForm.fileUuid = (tempFiles.map((item) => item.fileUuid) || []).join(',')
}
}
//
{
let tempFileList = fileList.value
let tempFiles: any = []
if (fileList && tempFileList.length) {
tempFiles = await fileUploader.upload(tempFileList, { source: 'ht' })
}
console.log(tempFiles)
if (tempFiles) {
bussinessForm.fileUuid = (tempFiles.map((item) => item.fileUuid) || []).join(',')
}
}
let form = {
contractBaseInfo: contractForm,
selectMerchantsBasicInfo: bussinessForm,
biddingList: xGridRef.value?.getTableData().fullData,
};
if (form.selectMerchantsBasicInfo.isBid) {
let biddingList: any[] = xGridRef.value?.getTableData().fullData || [];
let index = 1;
for (const item of biddingList) {
if (!item.phaseName) {
message.error(`标段信息中的标段名称不能为空`);
return;
}
if (!item.phaseMoney) {
message.error(`标段信息中的预算金额不能为空`);
return;
}
if (!item.phaseDesc) {
message.error(`标段信息中的标段范围说明不能为空`);
return;
}
item.phaseSeq = index + "";
index++;
}
form.biddingList = biddingList;
}
console.log("提交表单", form)
return
const userStore = useUserStore()
let newForm = {}
//
let fileList = formRef.value.form.fileList
let files: any = []
if (fileList && fileList.length) {
files = await fileUploader.upload(fileList, { source: 'ht' })
}
console.log(files)
if (files) {
newForm.fileUuid = (files.map((item) => item.fileUuid) || []).join(',')
}
// let fileList = formRef.value.form.fileList
// let files: any = []
// if (fileList && fileList.length) {
// files = await fileUploader.upload(fileList, { source: 'ht' })
// }
// console.log(files)
// if (files) {
// newForm.fileUuid = (files.map((item) => item.fileUuid) || []).join(',')
// }
newForm = Object.assign({}, formRef.value.form, newForm)

View File

@ -3,6 +3,7 @@ import { useRender } from '#/hooks/useRender';
import dayjs from 'dayjs';
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
import { dict } from '@fast-crud/fast-crud';
import { unitComponentProps } from '#/common/unit'
export const PrimaryKey = 'guid';
@ -48,14 +49,10 @@ export function getFormSchema(_params: any = {}) {
autoSearchTrigger: 'enter',
show: true,
},
inputDepartName: {
inputDepartId: {
title: '承办单位',
key: 'inputDepartName',
component: {
name: 'a-input',
vModel: 'value',
allowClear: true,
},
key: 'inputUnitId',
component: unitComponentProps,
autoSearchTrigger: 'enter',
show: true,
},

View File

@ -41,6 +41,7 @@ const formBinding = ref({
},
zzb: {
colon: false,
class:'!mb-2',
render: () => {
return <a-divider orientation="left">总值班</a-divider>;
},
@ -86,6 +87,7 @@ const formBinding = ref({
},
jgbmld: {
colon: false,
class:'!mb-2',
render: () => {
return <a-divider orientation="left">机关部门领导</a-divider>;
},
@ -131,6 +133,7 @@ const formBinding = ref({
},
zb: {
colon: false,
class:'!mb-2',
render: () => {
return <a-divider orientation="left">值班</a-divider>;
},
@ -176,6 +179,7 @@ const formBinding = ref({
},
sj: {
colon: false,
class:'!mb-2',
render: () => {
return <a-divider orientation="left">司机</a-divider>;
},
@ -204,8 +208,9 @@ const formBinding = ref({
},
bz: {
colon: false,
class:'!mb-2',
render: () => {
return <a-divider orientation="left"></a-divider>;
return <a-divider orientation="left">值班备注</a-divider>;
},
},
remark: {
@ -269,3 +274,10 @@ const [Modal, modalApi] = useVbenModal({
<fs-form ref="formRef" v-bind="formBinding"> </fs-form>
</Modal>
</template>
<style scoped>
:deep(.ant-divider-horizontal.ant-divider-with-text){
margin: 0 !important;
}
</style>

View File

@ -66,14 +66,14 @@ export default defineConfig(async () => {
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/czg\/app/, '/'),
// mock代理目标地址
target: `http://10.71.221.222:8083/rl`,
target: `http://192.168.147.238:8083/rl`,
ws: true,
},
'/api/czg/uc': {
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/czg\/uc/, '/'),
// mock代理目标地址
target: `http://10.71.220.24:8082`,
target: `http://192.168.147.164:8082`,
ws: true,
},
'/api/zp/app': {
@ -90,6 +90,20 @@ export default defineConfig(async () => {
target: `http://192.168.147.164:8082`,
ws: true,
},
'/api/xmh/app': {
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/xmh\/app/, '/'),
// mock代理目标地址
target: `http://192.168.147.144:8083/rl`,
ws: true,
},
'/api/xmh/uc': {
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/xmh\/uc/, '/'),
// mock代理目标地址
target: `http://192.168.147.164:8082`,
ws: true,
},
},
},
},