constract和 property的写法

本文介绍了一种基于Spring框架的邮件服务配置方法,在不同环境中(如SCE测试环境及正式环境)进行灵活配置,以实现邮件发送功能。文章展示了如何通过构造参数注入的方式设置邮件服务所需的VelocityEngine和发件人地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<beans profile="test,local">-->
<!--<!– 本地,测试环境的 mail 服务配置 –>-->
<!--<bean name="sendMailService" class="cn.focus.dc.app.xinfang.service.SendMailService">-->
<!--<constructor-arg index="0"-->
<!--type="org.apache.velocity.app.VelocityEngine"-->
<!--ref="velocityEngine" />-->
<!--<constructor-arg index="1"-->
<!--type="org.springframework.mail.javamail.JavaMailSender" ref="mailSender" />-->
<!--<constructor-arg index="2" type="java.lang.String"-->
<!--value="${mail.from}" />-->
<!--</bean>-->
<!--</beans>-->


<!-- SCE 测试环境及正式环境下 mail 服务配置 -->
<bean name="sendMailService" class="cn.focus.dc.app.xinfang.service.SendMailService">
<constructor-arg index="0" type="org.apache.velocity.app.VelocityEngine"
ref="velocityEngine"/>
<property name="from" value="****@sohu-inc.com"/>
</bean>

@Autowired
private VelocityEngine velocityEngine;

private String from;

public SendMailService() {
}

public SendMailService(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}


public SendMailService(String from) {
this.from = from;
}
Error: Please import the top-level fullcalendar lib before attempting to import a plugin.下面是我的代码,并且使用的版本一致<template> <!-- 办公-我的日程页面 --> <div class="divBox"> <el-card body-style="padding:0 0 0 0; " class="normal-page"> <div class="header"> <span class="title">我的日程</span> <el-button type="primary" size="small" :icon="Plus" @click="addSchedule"> {{ $t('calendar.newschedule') }} </el-button> </div> <el-row :gutter="14"> <el-col :span="7"> <calendar-bar ref="calendarBar" @handle-date="handleDate" /> </el-col> <el-col :span="17" class="line" v-loading="loading" element-loading-text="数据正在加载中"> <div class="plan-tabs-content"></div> <!-- 我的日历 --> <div class="needToBeDealt"> <div class="add-btn"> <div class="content-right"></div> <div class="content-button"> <el-radio-group v-model="time" size="small" @change="selectChange"> <el-radio-button v-for="(itemn, indexn) in fromList" :key="indexn" :label="itemn.val" > {{ itemn.text }} </el-radio-button> </el-radio-group> </div> </div> <FullCalendar ref="calendar" id="calendar" style="height: calc(100vh - 150px)" :options="calendarOptions"> <template v-slot:slotLabelContent="arg"> <div class="calendar-timeline"> <!-- <span v-if="moment(arg.date).format('HH:mm') !== '00:00'">--> <!-- {{ moment(arg.date).format('HH:mm') }}--> <!-- </span>--> </div> </template> <template v-slot:dayHeaderContent="arg"> <div class="header-box"> <div class="day-header" :class="period == 1 ? 'ml30' : ''"> <!-- <span class="week">{{ getWeek(arg.date) }}</span>--> <!-- <span class="date" v-if="period !== 3">{{ moment(arg.date).format('D') }}</span>--> </div> </div> </template> <template v-slot:eventContent="arg"> <div class="item" :style="{ background: period == 3 ? getColorFn(arg.event.textColor, '0.1') : arg.event.color }" > <div class="flex over-title" @click="handleEventClick(arg)"> <img v-if="period !== 2" :src="arg.event.extendedProps.avatar" class="img" alt="" /> <div class="over-title" :style="{ color: period == 3 ? arg.event.textColor : arg.event.textColor }" > {{ arg.event.title }} </div> </div> <template v-if="arg.event.extendedProps.show > -1"> <span v-if="arg.event.extendedProps.finish == 2" class="el-icon-error" :style="{ color: arg.event.textColor }" ></span> <span v-else-if="arg.event.extendedProps.finish == 3" @click="putStatus('取消完成', 1, arg.event)" class="el-icon-success" :style="{ color: arg.event.textColor }" ></span> <span v-else class="yuan" :style="{ 'border-color': arg.event.textColor }" @click="putStatus('完成', 3, arg.event, arg)" ></span> </template> </div> </template> </FullCalendar> </div> </el-col> </el-row> </el-card> <!-- 通用弹窗表单 --> <add-todo ref="addTodo" @get-list="getList" :left-time="leftTime"></add-todo> <calendar-details ref="calendarDetails" @delete-fn="getList" @edit-fn="editFn" :date-info="dateInfo" ></calendar-details> <contract-dialog ref="contractDialog" :config="configContract" @is-ok="getList"></contract-dialog> <!-- 跟进弹窗 --> <el-dialog title="添加跟进记录" class="record" v-model="dialogVisible" width="40%"> <record-upload :form-info="formInfo" @change="recordChange"></record-upload> </el-dialog> <edit-examine ref="editExamine" :parameter-data="parameterData" :ids="formInfo.data.id" @schedule-record="scheduleRecord" ></edit-examine> </div> </template> <script> import FullCalendar from '@fullcalendar/vue3' // 核心库必须第一个导入 import dayGridPlugin from '@fullcalendar/daygrid' import timeGridPlugin from '@fullcalendar/timegrid' import interactionPlugin from '@fullcalendar/interaction' import listPlugin from '@fullcalendar/list' import { defineComponent, defineAsyncComponent, ref, reactive, onMounted, computed, toRefs, nextTick } from 'vue'; import { Plus } from '@element-plus/icons-vue'; //import { ElMessage } from 'element-plus'; import moment from 'moment'; // 正确顺序:先核心库再插件 // 样式导入(必须在插件之后) // import '@fullcalendar/common/main.css' // import '@fullcalendar/daygrid/main.css' // import '@fullcalendar/timegrid/main.css' // import '@fullcalendar/list/main.css' console.log(window.FullCalendar); // 检查全局对象 console.log(window.FullCalendarCore); // 如果你手动挂载了核心库 // 根据实际需要取消注释这些API导入 // import { // clientRemindDetailApi, // scheduleListApi, // scheduleStatusApi // } from '@/api/enterprise'; // import { configRuleApproveApi } from '@/api/config'; // import { toGetWeek, getColor } from '@/utils/format'; export default defineComponent({ name: 'WorkDealt', components: { CalendarBar: defineAsyncComponent(() => import('./components/calendarBar.vue')), AddTodo: defineAsyncComponent(() => import('./components/addTodo')), FullCalendar, CalendarDetails: defineAsyncComponent(() => import('./components/calendarDetails')) // ContractDialog: defineAsyncComponent(() => import('@/views/customer/contract/components/contractDialog')), // RecordUpload: defineAsyncComponent(() => import('@/views/customer/list/components/recordUpload')), // EditExamine: defineAsyncComponent(() => import('@/views/user/examine/components/editExamine')) }, setup() { const state = reactive({ loading: false, calendarApi: null, title: '', time: '1', cid: null, dialogVisible: false, configContract: {}, formInfo: { avatar: '', type: 'add', show: 1, data: {}, follow_id: 0 }, fromList: computed(() => [ {text: '日', val: '1'}, {text: '周', val: '2'}, {text: '月', val: '3'} ]), start_time: '', end_time: '', dateInfo: {}, type: [], period: 1, calendarOptions: { height: 'calc(100vh - 232px)', eventColor: '', initialDate: moment().format('YYYY-MM-DD HH:mm:ss'), plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin, listPlugin], handleWindowResize: true, displayEventTime: false, slotDuration: '00:60:00', scrollTime: '05:30:00', slotMinTime: '00:00:00', slotMaxTime: '24:00:00', headerToolbar: { left: '', center: 'prev title next', right: '' }, buttonText: { month: '月', week: '周', day: '天' }, allDaySlot: true, dayMaxEventRows: 6, allDayText: '', moreLinkContent: state => `还有${state.num}个日程`, weekends: true, nowIndicator: true, weekNumbers: false, slotLabelFormat: { hour: '2-digit', minute: '2-digit', meridiem: false, hour12: false }, selectable: true, displayEventEnd: false, initialView: 'timeGridDay', dateClick: (e) => handleDateClick(e), customButtons: { next: { text: 'PREV', click: () => next() }, prev: { text: 'PREV', click: () => prev() } }, events: [], slotEventOverlap: false, eventOverlap: false, locale: 'zh-cn', weekNumberCalculation: 'ISO' }, detailedData: {}, parameterData: { contract_id: '', customer_id: '', invoice_id: '', bill_id: '' }, leftTime: '', buildData: [], item: {}, status: 0 }) const calendarBar = ref(null); const addTodo = ref(null); const calendarDetails = ref(null); const contractDialog = ref(null); const editExamine = ref(null); const userId = ref(null); // 日期更新函数 const updateCalendarDates = () => { if (!state.calendarApi) return; state.title = moment(state.calendarApi.view.currentStart).format('YYYY-MM-DD'); state.start_time = state.title + ' 00:00:00'; state.end_time = state.title + ' 23:59:59'; }; onMounted(() => { const userInfo = JSON.parse(localStorage.getItem('userInfo')); if (userInfo) { userId.value = userInfo.userId; state.formInfo.avatar = userInfo.avatar; } // 使用 nextTick 确保在 DOM 更新后执行 nextTick(() => { if (calendarBar.value && calendarBar.value.getApi) { state.calendarApi = calendarBar.value.getApi(); dayRender(); updateCalendarDates(); } }); }); // 原始方法开始(保持所有方法逻辑不变) // const handleEventClick = e => { calendarDetails.value.open(e.event.extendedProps); } const recordChange = () => { state.dialogVisible = false; getList(); } const getConfigApprove = async () => { // 实际项目中取消注释 // const result = await configRuleApproveApi(0); // state.buildData = result.data; } const putStatus = async (text, status, item) => { const {extendedProps} = item; state.item = extendedProps; const bill_id = extendedProps.bill_id; switch (extendedProps.cid_value) { case 3: case 4: const id = bill_id.bill_id !== 0 ? bill_id.bill_id : bill_id.remind_id; if (status == 3) { // 实际项目中取消注释 // clientRemindDetailApi(id).then((res) => { // res.data.id = bill_id.remind_id; // state.parameterData.customer_id = res.data.eid; // state.parameterData.contract_id = res.data.cid; // // const switchType = res.data.types === 0 ? 'contract_refund_switch' : 'contract_renew_switch'; // const data = {id: state.buildData[switchType]}; // editExamine.value.open(data, res.data.cid, switchType, item, status); // }) } break; case 2: if (extendedProps.finish === 3) return false; state.formInfo.follow_id = bill_id ? bill_id.follow_id : 0; state.formInfo.data.eid = extendedProps.link_id; state.dialogVisible = true; break; default: scheduleRecord(extendedProps, status); } } const scheduleRecord = async (data = state.item, status = state.status) => { const {start_time: start, end_time: end, itemId: id} = data; const info = {status, start, end}; // 实际项目中取消注释 // await scheduleStatusApi(id, info); await getList(); } const handleDateClick = e => { state.detailedData = { startDate: moment(e.date).format('YYYY-MM-DD'), startTime: moment(e.date).format('HH:mm:ss'), endDate: moment(e.date).format('YYYY-MM-DD'), time: moment(e.date).format('YYYY-MM-DD HH:mm:ss') } addTodo.value.open(state.detailedData); } const dayRender = () => { document.documentElement.style.setProperty(`--fc-today-bg-color`, '#fff'); let dayTime = document.querySelectorAll('.fc-timegrid-slot-label-cushion'); dayTime[0]?.classList.add('fcTime'); document.querySelectorAll('.fc-button-primary').forEach(li => li.setAttribute('title', '')); } const day = () => { state.period = 1; state.calendarApi.changeView('timeGridDay'); getList(); removeTitle(); dayRender(); } const month = () => { state.period = 3; state.calendarApi.changeView('dayGridMonth'); getList(); removeTitle(); } const week = () => { state.period = 2; state.calendarApi.changeView('timeGridWeek'); getList(); removeTitle(); dayRender(); } const prev = () => { state.calendarApi.prev(); updateCalendarDates(); getList(); if (state.period === 2) { const date = calendarBar.value.value; calendarBar.value.value = moment(date).subtract(7, 'd').format('YYYY-MM-DD'); } else { calendarBar.value.value = moment(state.calendarApi.view.currentStart).format('YYYY-MM-DD'); } } const next = () => { state.calendarApi.next(); updateCalendarDates(); getList(); if (state.period == 2) { let date = calendarBar.value.value; calendarBar.value.value = moment(date).add(7, 'd').format('YYYY-MM-DD'); } else { calendarBar.value.value = moment(state.calendarApi.view.currentStart).format('YYYY-MM-DD'); } } const getList = () => { // 实际项目中取消注释 // scheduleListApi().then(res => { // let newArr = [] // res.data.forEach(item => { // // ...处理逻辑... // }) // state.calendarOptions.events = newArr // }) calendarBar.value?.getList(); } const findItem = (arr, key, val) => { for (var i = 0; i < arr.length; i++) { if (arr[i].id === val || arr[i].id == userId.value) { return 2; } } return -1; } // const getWeek = date => toGetWeek(date); const editFn = (id, type, date) => { let data = { id, type, edit: true, date } addTodo.value.openBox(data); } const handleDate = (data, val) => { state.cid = data.type; state.leftTime = data.time; if (val) { state.calendarApi.gotoDate(data.time); } setTimeout(() => { state.calendarApi = calendarBar.value.getApi(); state.time = 1; day(); getList(); }, 300); } const selectChange = e => { state.time = e; if (state.time == 1) { day(); } else if (state.time == 2) { week(); } else { month(); } } const addSchedule = () => addTodo.value.open(); // 临时 getColorFn 实现 - 实际项目中应该使用真实实现 const getColorFn = (thisColor, thisOpacity) => { // 如果是透明背景 if (state.period === 3) { // RGBA 格式 const r = parseInt(thisColor.slice(1, 3), 16); const g = parseInt(thisColor.slice(3, 5), 16); const b = parseInt(thisColor.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${thisOpacity})`; } return thisColor; } const removeTitle = () => { setTimeout(() => { document.querySelectorAll('.fc-daygrid-day-bottom a').forEach(li => li.title = ''); }, 300); } return { ...toRefs(state), Plus, calendarBar, addTodo, calendarDetails, contractDialog, editExamine, handleEventClick, recordChange, putStatus, scheduleRecord, handleDateClick, dayRender, day, month, week, prev, next, getList, findItem, // getWeek, editFn, handleDate, selectChange, addSchedule, getColorFn, removeTitle } } }) </script> <style lang="scss" scoped> .divBox { :deep(.fc-header-toolbar) { position: absolute; top: 0; left: 0; } .header { padding: 16px 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #dcdfe6; .title { font-weight: 500; font-size: 18px; color: #303133; } } .day-header { display: flex; flex-direction: column; justify-content: center; height: 52px; font-family: PingFang SC-Regular, PingFang SC; line-height: 20px; .week { font-size: 13px; color: #909399; } .date { font-size: 18px; color: #606266; font-weight: 800; } } .ml30 { margin-left: -30px; } :deep(.fc-timegrid-slot-label-cushion) { color: #909399; font-size: 12px; } .line { border-left: 1px solid #f0f2f5; } .item { width: 100%; display: flex; font-size: 14px; font-family: PingFang SC-Regular, PingFang SC; justify-content: space-between; align-items: center; padding-right: 4px; border-radius: 13px; .img { flex-shrink: 0; width: 18px; height: 18px; border-radius: 50%; margin-right: 5px; object-fit: cover; } .yuan { width: 12px; height: 12px; border-radius: 50px; border: 1px solid #fff; } } .over-title { width: 98% !important; overflow: hidden !important; white-space: nowrap; text-overflow: ellipsis !important; } } </style>
最新发布
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值