升级IE8后,VS出现ParameterType.Value.length为空或不是对象(Line:842)的解决办法

升级IE8后-ParameterType.Value.length为空或不是对象(Line:842)的解决办法

今天难得在家用了下VS2008,跑出个问题来:

症状就是安装了IE8以后,右键Class->Add Functions/Variables。

出现错误:

'ParameterType.Value.length'为空或不是对象(Line:842)

看看是IE8的安全设置问题,应该是C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\VsWizard.dll 这个文件的ActiveX控件在web browser control中加载不成功,被ie8的安全属性设置禁止了。解决方法如下:

启动注册表编辑器 regedit

找到“HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet

Settings\Zones”, 建立一个名为1000的新键(如果没有的话).

在这个1000的键下,建立如下DWORD内容:

Name = 1207

Type = REG_DWORD

Data = 0x000000

或者直接写注册表

REGEDIT4

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1000]
@=""
"1207"=dword:00000000

难得写篇技术文章,自己折腾了很久,希望别人不折腾

PS:学得越多,就觉得自己要学的越多!

原文地址:http://www.fantasyray.com/lbs/article.asp?id=270

-------------------------------------------

自己写了个注册表文件,上传到了资源里了,http://download.youkuaiyun.com/source/1378893,下载后"右键"->"合并",重启VS即可。

其实也就是把下面几句放到记事本里,然后保存一个后缀是.reg的文件,合并就行了。

REGEDIT4

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1000]
@=""
"1207"=dword:00000000

<template> <el-dialog :title="'编辑参数'" :close-on-click-modal="false" append-to-body :visible.sync="visible" class="JNPF-dialog JNPF-dialog_center" lock-scroll width="1600px"> <el-row :gutter="15" class=""> <el-form ref="elForm" :model="dataForm" :rules="rules" size="small" label-width="100px" label-position="right"> <template v-if="!loading"> <el-col :span="12" v-if="jnpf.hasFormP('equipmentledgerid')"> <el-form-item label="设备设施" prop="equipmentledgerid"> <JNPFTreeSelect v-model="getequipmentledger" @change="selectequipment(), eqchangeData()" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable :options="equipmentledgeridOptions" :props="equipmentledgeridProps"> </JNPFTreeSelect> </el-form-item> </el-col> <el-col :span="12" v-if="jnpf.hasFormP('processid')"> <el-form-item label="工序" prop="processid"> <JNPFTreeSelect v-model="getprocess" placeholder="请选择" clearable :disabled="true" :style='{ "width": "100%" }' filterable :options="processidOptions" :props="processidProps"> </JNPFTreeSelect> </el-form-item> </el-col> <el-col :span="24"> <el-form-item label-width="0"> <div class="JNPF-common-title"> <h2>设备参数明细</h2> <el-button style="position: absolute; left: 20vh; z-index: 99; background-color: #409EFF; color: white;" icon="el-icon-search" @click="getequiptypepara()"> 获取设备类型参数 </el-button> </div> <el-table :data="dataForms" size='mini' overflow-x: scroll> <el-table-column type="index" width="50" label="序号" align="center" fixed="left" /> <el-table-column prop="processid" label="工序" width="150" align="center"> <template slot="header"> <span class="required-sign">*</span>工序 </template> <template slot-scope="scope"> <JNPFTreeSelect v-model="scope.row.processid" :disabled="true" @change="changeData('processid', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable :options="processidOptions" :props="processidProps"> </JNPFTreeSelect> </template> </el-table-column> <el-table-column prop="equipmentledgerid" label="设备设施" width="200" align="center"> <template slot="header"> <span class="required-sign">*</span>设备设施 </template> <template slot-scope="scope"> <JNPFTreeSelect v-model="scope.row.equipmentledgerid" :disabled="true" @change="changeData('equipmentledgerid', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable :options="equipmentledgeridOptions" :props="equipmentledgeridProps"> </JNPFTreeSelect> </template> </el-table-column> <el-table-column prop="fullname" label="参数名称" width="150" align="center" fixed="left"> <template slot="header"> <span class="required-sign">*</span>参数名称 </template> <template slot-scope="scope"> <el-input v-model="scope.row.fullname" @change="changeData('fullname', -1)" :disabled="true" placeholder="请输入" clearable :style='{ "width": "100%" }'> </el-input> </template> </el-table-column> <el-table-column prop="tag" label="DAtag" width="200" align="center"> <template slot="header"> <span class="required-sign">*</span>DAtag </template> <template slot-scope="scope"> <el-input v-model="scope.row.tag" @change="changeData('tag', -1)" placeholder="请输入" clearable :style='{ "width": "100%" }'> </el-input> </template> </el-table-column> <el-table-column prop="datatypes" label="数据类型" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>数据类型 </template> <template slot-scope="scope"> <el-select v-model="scope.row.datatypes" @change="changeData('datatypes', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in datatypesOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="parametertype" label="参数类型" width="100" align="center"> <template slot-scope="scope"> <el-select v-model="scope.row.parametertype" @change="changeData('parametertype', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in parametertypeOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="unit" label="单位" width="100" align="center"> <template slot-scope="scope"> <el-input v-model="scope.row.unit" @change="changeData('unit', -1)" placeholder="请输入" clearable :style='{ "width": "100%" }'> </el-input> </template> </el-table-column> <el-table-column prop="isrealtime" label="曲线" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>曲线 </template> <template slot-scope="scope"> <el-select v-model="scope.row.isrealtime" @change="changeData('isrealtime', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in isrealtimeOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="enabledmark" label="可用" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>可用 </template> <template slot-scope="scope"> <el-select v-model="scope.row.enabledmark" @change="changeData('enabledmark', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in enabledmarkOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="isconstantvalue" label="恒值" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>恒值 </template> <template slot-scope="scope"> <el-select v-model="scope.row.isconstantvalue" @change="changeData('isconstantvalue', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in isconstantvalueOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="isonline" label="在线" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>在线 </template> <template slot-scope="scope"> <el-select v-model="scope.row.isonline" @change="changeData('isonline', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in isonlineOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="isrunning" label="运行" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>运行 </template> <template slot-scope="scope"> <el-select v-model="scope.row.isrunning" @change="changeData('isrunning', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in isrunningOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="iszero" label="0值" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>0值 </template> <template slot-scope="scope"> <el-select v-model="scope.row.iszero" @change="changeData('iszero', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in iszeroOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="ishahf" label="高幅高频" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>高幅高频 </template> <template slot-scope="scope"> <el-select v-model="scope.row.ishahf" @change="changeData('ishahf', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in ishahfOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="isontime" label="实时" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>实时 </template> <template slot-scope="scope"> <el-select v-model="scope.row.isontime" @change="changeData('isontime', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in isontimeOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="isdispatch" label="调度" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>调度 </template> <template slot-scope="scope"> <el-select v-model="scope.row.isdispatch" @change="changeData('isdispatch', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in isdispatchOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="ishigh" label="上限" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>上限 </template> <template slot-scope="scope"> <el-select v-model="scope.row.ishigh" @change="changeData('ishigh', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in ishighOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="highthreshold" label="上阈值" width="150" align="center"> <template slot-scope="scope"> <el-input-number v-model="scope.row.highthreshold" :controls="false" @change="changeData('highthreshold', -1)" placeholder="数字文本" :step="1" :precision="2"> </el-input-number> </template> </el-table-column> <el-table-column prop="islow" label="下限" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>下限 </template> <template slot-scope="scope"> <el-select v-model="scope.row.islow" @change="changeData('islow', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in islowOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="lowthreshold" label="下阈值" width="150" align="center"> <template slot-scope="scope"> <el-input-number v-model="scope.row.lowthreshold" :controls="false" @change="changeData('lowthreshold', -1)" placeholder="数字文本" :step="1" :precision="2"> </el-input-number> </template> </el-table-column> <el-table-column prop="runtag" label="运行tag" width="200" align="center"> <template slot-scope="scope"> <el-input v-model="scope.row.runtag" @change="changeData('runtag', -1)" placeholder="请输入" clearable :style='{ "width": "100%" }'> </el-input> </template> </el-table-column> <el-table-column prop="labels" label="功能标签" width="200" align="center"> <template slot-scope="scope"> <el-select v-model="scope.row.labels" @change="changeData('labels', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable :multiple="true"> <el-option v-for="(item, index) in labelsOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="issync" label="同步" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>同步 </template> <template slot-scope="scope"> <el-select v-model="scope.row.issync" @change="changeData('issync', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable> <el-option v-for="(item, index) in issyncOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="syncparaencode" label="同步参数编码" width="150" align="center"> <template slot-scope="scope"> <el-input v-model="scope.row.syncparaencode" @change="changeData('syncparaencode', -1)" placeholder="请输入" clearable :style='{ "width": "100%" }'> </el-input> </template> </el-table-column> <el-table-column prop="accuracys" label="数据精度" width="100" align="center"> <template slot="header"> <span class="required-sign">*</span>数据精度 </template> <template slot-scope="scope"> <el-select v-model="scope.row.accuracys" @change="changeData('accuracys', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }'> <el-option v-for="(item, index) in accuracysOptions" :key="index" :label="item.fullName" :value="item.enCode" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="duration" label="时长" width="150" align="center"> <template slot-scope="scope"> <el-input-number v-model="scope.row.duration" :controls="false" @change="changeData('duration', -1)" placeholder="数字文本" :step="1"> </el-input-number> </template> </el-table-column> <el-table-column prop="sortcode" label="排序" width="150" align="center"> <template slot-scope="scope"> <el-input-number v-model="scope.row.sortcode" :controls="false" @change="changeData('sortcode', -1)" placeholder="数字文本" :step="1"> </el-input-number> </template> </el-table-column> <el-table-column prop="description" label="描述" width="200" align="center"> <template slot-scope="scope"> <el-input v-model="scope.row.description" @change="changeData('description', -1)" placeholder="请输入" clearable :style='{ "width": "100%" }'> </el-input> </template> </el-table-column> <el-table-column label="操作" width="50" fixed="right"> <template slot-scope="scope"> <el-button size="mini" type="text" class="JNPF-table-delBtn" @click="delentryList(scope.$index)">删除</el-button> </template> </el-table-column> </el-table> <!-- <div class="table-actions" @click="addentryList()"> <el-button type="text" icon="el-icon-plus">添加</el-button> </div> --> </el-form-item> </el-col> </template> </el-form> <SelectDialog v-if="selectDialogVisible" :config="currTableConf" :formData="dataForm" ref="selectDialog" @select="addForSelect" @close="selectDialogVisible = false" /> </el-row> <span slot="footer" class="dialog-footer"> <el-button @click="visible = false"> 取 消</el-button> <el-button type="primary" @click="dataFormSubmits()" :loading="btnLoading"> 确 定</el-button> </span> </el-dialog> </template> <script> import request from '@/utils/request' import { getDataInterfaceRes } from '@/api/systemData/dataInterface' import { getDictionaryDataSelector } from '@/api/systemData/dictionary' export default { components: {}, props: [], data() { return { visible: false, loading: false, btnLoading: false, selectDialogVisible: false, currTableConf: {}, addTableConf: { }, tableRows: { }, currVmodel: "", getequipmentledger: "", devicetypeparalist: [], getprocess: "", dataForms: [], dataForm: { equipmentledgerid: "", processid: "", encode: '', fullname: '', tag: '', datatypes: "", parametertype: "", unit: '', isrealtime: "0", enabledmark: "1", isconstantvalue: "0", isonline: "0", isrunning: "0", iszero: "0", ishahf: "0", isontime: "0", isdispatch: "0", ishigh: "0", highthreshold: undefined, islow: "0", lowthreshold: undefined, runtag: '', labels: [], issync: "0", syncparaencode: '', accuracys: "ma", duration: undefined, sortcode: undefined, description: '', creatoruserid: "", creatortime: "", lastmodifyuserid: "", lastmodifytime: "", }, rules: { getequipmentledger: [ { required: true, message: '请选择', trigger: 'change' }, ], getprocessid: [ { required: true, message: '请选择', trigger: 'change' }, ], fullname: [ { required: true, message: '请输入', trigger: 'blur' }, ], tag: [ { required: true, message: '请输入', trigger: 'blur' }, ], datatypes: [ { required: true, message: '请选择', trigger: 'change' }, ], isrealtime: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], enabledmark: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], isconstantvalue: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], isonline: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], isrunning: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], iszero: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], ishahf: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], isontime: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], isdispatch: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], ishigh: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], islow: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], issync: [ { required: true, message: '请至少选择一个', trigger: 'change' }, ], }, equipmentledgeridOptions: [], equipmentledgeridProps: { "label": "F_FullName", "value": "F_Id", "children": "children" }, processidOptions: [], processidProps: { "label": "processname", "value": "id", "children": "children" }, datatypesOptions: [], parametertypeOptions: [], isrealtimeOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], enabledmarkOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], isconstantvalueOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], isonlineOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], isrunningOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], iszeroOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], ishahfOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], isontimeOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], isdispatchOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], ishighOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], islowOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], labelsOptions: [], issyncOptions: [{ "fullName": "是", "id": "1" }, { "fullName": "否", "id": "0" }], accuracysOptions: [], eqinfolist: [], childIndex: -1, isEdit: false, interfaceRes: { equipmentledgerid: [ ], processid: [ ], encode: [ ], fullname: [ ], tag: [ ], datatypes: [ ], parametertype: [ ], unit: [ ], isrealtime: [ ], enabledmark: [ ], isconstantvalue: [ ], isonline: [ ], isrunning: [ ], iszero: [ ], ishahf: [ ], isontime: [ ], isdispatch: [ ], ishigh: [ ], highthreshold: [ ], islow: [ ], lowthreshold: [ ], runtag: [ ], labels: [ ], issync: [ ], syncparaencode: [ ], accuracys: [ ], duration: [ ], sortcode: [ ], description: [ ], creatoruserid: [ ], creatortime: [ ], lastmodifyuserid: [ ], lastmodifytime: [ ], }, } }, computed: {}, watch: {}, created() { this.dataAll() }, mounted() { }, methods: { sparepartscostentryExist() { let isOk = true; for (let i = 0; i < this.dataForms.length; i++) { const e = this.dataForms[i]; if (!e.equipmentledgerid) { this.$message({ message: '设备设施不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.processid) { this.$message({ message: '工序不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.fullname) { this.$message({ message: '参数名称不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.tag) { this.$message({ message: 'tag不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.datatypes) { this.$message({ message: '数据类型不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.isrealtime) { this.$message({ message: '曲线不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.enabledmark) { this.$message({ message: '是否有效不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.isconstantvalue) { this.$message({ message: '恒值不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.isonline) { this.$message({ message: '在线不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.isrunning) { this.$message({ message: '运行不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.iszero) { this.$message({ message: '0值不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.ishahf) { this.$message({ message: '高幅高频不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.isontime) { this.$message({ message: '实时不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.isdispatch) { this.$message({ message: '调度不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.ishigh) { this.$message({ message: '是否上限不能为', type: 'error', duration: 1000 }); isOk = false break } if (e.ishigh == "1" && !e.highthreshold) { this.$message({ message: '是否上限为是,上阈值不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.islow) { this.$message({ message: '是否下限不能为', type: 'error', duration: 1000 }); isOk = false break } if (e.islow == "1" && !e.lowthreshold) { this.$message({ message: '是否下限为是,下阈值不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.issync) { this.$message({ message: '同步分析不能为', type: 'error', duration: 1000 }); isOk = false break } if (e.issync == "1" && !e.syncparaencode) { this.$message({ message: '是否同步分析为是,同步分析参数编码不能为', type: 'error', duration: 1000 }); isOk = false break } if (!e.accuracys) { this.$message({ message: '数据精度不能为', type: 'error', duration: 1000 }); isOk = false break } } return isOk; }, selectequipment() { if (this.getequipmentledger != null && this.getequipmentledger != '') { // console.log("this.getequipmentledger", this.getequipmentledger); //工序赋值 //调取列表接口 request({ url: '/api/example/Equipmentparameter/getparalist', method: 'post', data: { "equipmentid": this.getequipmentledger } }).then(res => { this.dataForms = res.data if (this.dataForms.length == 0) { this.getequiptypepara() } }); } }, geteqinfolist() { getDataInterfaceRes('626301338401114181', null).then(res => { let data = res.data this.eqinfolist = data }) }, eqchangeData() { const selectedOption = this.eqinfolist.find(option => option.F_id === this.getequipmentledger); if (selectedOption) { this.getprocess = selectedOption.F_processCode } }, getequiptypepara() { request({ url: '/api/example/Equipmentparameter/getDevicetypeparalist', method: 'post', data: { "equipmentid": this.getequipmentledger } }).then(res => { this.devicetypeparalist = res.data console.log("this.devicetypeparalist", this.devicetypeparalist); if (this.dataForms.length == 0) { this.devicetypeparalist.forEach(item => { let item1 = { equipmentledgerid: this.getequipmentledger, processid: this.getprocess, encode: '', fullname: item.parametername, tag: '', datatypes: item.datatype, parametertype: "", unit: item.unit, isrealtime: "0", enabledmark: "1", isconstantvalue: "0", isonline: "0", isrunning: "0", iszero: "0", ishahf: "0", isontime: "0", isdispatch: "0", ishigh: "0", highthreshold: undefined, islow: "0", lowthreshold: undefined, runtag: '', labels: [], issync: "0", syncparaencode: '', accuracys: "ma", duration: undefined, sortcode: item.sort, description: '', creatoruserid: "", creatortime: "", lastmodifyuserid: "", lastmodifytime: "", } console.log("this.dataForms", this.dataForms); this.dataForms.push(item1) }) } else { for (let h = 0; h < this.devicetypeparalist.length; h++) { let numbers = 0 for (let j = 0; j < this.dataForms.length; j++) { if (this.dataForms[j].fullname == this.devicetypeparalist[h].parametername) { numbers++ } } if (numbers == 0) { let item1111 = { equipmentledgerid: this.getequipmentledger, processid: this.getprocess, encode: '', fullname: this.devicetypeparalist[h].parametername, tag: '', datatypes: this.devicetypeparalist[h].datatype, parametertype: "", unit: this.devicetypeparalist[h].unit, isrealtime: "0", enabledmark: "1", isconstantvalue: "0", isonline: "0", isrunning: "0", iszero: "0", ishahf: "0", isontime: "0", isdispatch: "0", ishigh: "0", highthreshold: undefined, islow: "0", lowthreshold: undefined, runtag: '', labels: [], issync: "0", syncparaencode: '', accuracys: "ma", duration: undefined, sortcode: undefined, description: '', creatoruserid: "", creatortime: "", lastmodifyuserid: "", lastmodifytime: "", } this.dataForms.push(item1111) } } } console.log("this.dataForms", this.dataForms); }); }, changeData(model, index) { this.isEdit = false this.childIndex = index let modelAll = model.split("-"); let faceMode = ""; for (let i = 0; i < modelAll.length; i++) { faceMode += modelAll[i]; } for (let key in this.interfaceRes) { if (key != faceMode) { let faceReList = this.interfaceRes[key] for (let i = 0; i < faceReList.length; i++) { if (faceReList[i].relationField == model) { let options = 'get' + key + 'Options'; if (this[options]) { this[options]() } this.changeData(key, index) } } } } }, changeDataFormData(type, data, model, index, defaultValue) { if (!this.isEdit) { if (type == 2) { for (let i = 0; i < this.dataForm[data].length; i++) { if (index == -1) { this.dataForm[data][i][model] = defaultValue } else if (index == i) { this.dataForm[data][i][model] = defaultValue } } } else { this.dataForm[data] = defaultValue } } }, dataAll() { this.getequipmentledgeridOptions(); this.getprocessidOptions(); this.getdatatypesOptions(); this.getparametertypeOptions(); this.getlabelsOptions(); this.getaccuracysOptions(); this.geteqinfolist(); }, getequipmentledgeridOptions() { const index = this.childIndex let templateJsonList = JSON.parse(JSON.stringify(this.interfaceRes.equipmentledgerid)) for (let i = 0; i < templateJsonList.length; i++) { let json = templateJsonList[i]; if (json.relationField) { let relationFieldAll = json.relationField.split("-"); let val = json.defaultValue; if (relationFieldAll.length > 1 && index > -1) { val = this.dataForm[relationFieldAll[0] + 'List'] && this.dataForm[relationFieldAll[0] + 'List'].length ? this.dataForm[relationFieldAll[0] + 'List'][index][relationFieldAll[1]] : '' } else { val = this.dataForm[relationFieldAll] } json.defaultValue = val } } let template = { paramList: templateJsonList } getDataInterfaceRes('626403889863723077', template).then(res => { let data = res.data this.equipmentledgeridOptions = data this.changeDataFormData(1, 'equipmentledgerid', 'equipmentledgerid', index, '') }) }, getprocessidOptions() { const index = this.childIndex let templateJsonList = JSON.parse(JSON.stringify(this.interfaceRes.processid)) for (let i = 0; i < templateJsonList.length; i++) { let json = templateJsonList[i]; if (json.relationField) { let relationFieldAll = json.relationField.split("-"); let val = json.defaultValue; if (relationFieldAll.length > 1 && index > -1) { val = this.dataForm[relationFieldAll[0] + 'List'] && this.dataForm[relationFieldAll[0] + 'List'].length ? this.dataForm[relationFieldAll[0] + 'List'][index][relationFieldAll[1]] : '' } else { val = this.dataForm[relationFieldAll] } json.defaultValue = val } } let template = { paramList: templateJsonList } getDataInterfaceRes('629188405816723525', template).then(res => { let data = res.data this.processidOptions = data this.changeDataFormData(1, 'processid', 'processid', index, '') }) }, getdatatypesOptions() { getDictionaryDataSelector('434610983026105029').then(res => { this.datatypesOptions = res.data.list }) }, getparametertypeOptions() { getDictionaryDataSelector('434611137372297925').then(res => { this.parametertypeOptions = res.data.list }) }, getlabelsOptions() { getDictionaryDataSelector('625963845608802373').then(res => { this.labelsOptions = res.data.list }) }, getaccuracysOptions() { getDictionaryDataSelector('700226475051192965').then(res => { this.accuracysOptions = res.data.list }) }, clearData() { this.dataForm.equipmentledgerid = ""; this.dataForm.processid = ""; this.dataForm.encode = ''; this.dataForm.fullname = ''; this.dataForm.tag = ''; this.dataForm.datatypes = ""; this.dataForm.parametertype = ""; this.dataForm.unit = ''; this.dataForm.isrealtime = "0"; this.dataForm.enabledmark = "1"; this.dataForm.isconstantvalue = "0"; this.dataForm.isonline = "0"; this.dataForm.isrunning = "0"; this.dataForm.iszero = "0"; this.dataForm.ishahf = "0"; this.dataForm.isontime = "0"; this.dataForm.isdispatch = "0"; this.dataForm.ishigh = "0"; this.dataForm.highthreshold = undefined, this.dataForm.islow = "0"; this.dataForm.lowthreshold = undefined, this.dataForm.runtag = ''; this.dataForm.labels = []; this.dataForm.issync = "0"; this.dataForm.syncparaencode = ''; this.dataForm.accuracys = "ma"; this.dataForm.duration = undefined, this.dataForm.sortcode = undefined, this.dataForm.description = ''; this.dataForm.creatoruserid = ""; this.dataForm.creatortime = ""; this.dataForm.lastmodifyuserid = ""; this.dataForm.lastmodifytime = ""; }, addentryList() { let item = { equipmentledgerid: "", processid: "", encode: '', fullname: '', tag: '', datatypes: "", parametertype: "", unit: '', isrealtime: "0", enabledmark: "1", isconstantvalue: "0", isonline: "0", isrunning: "0", iszero: "0", ishahf: "0", isontime: "0", isdispatch: "0", ishigh: "0", highthreshold: undefined, islow: "0", lowthreshold: undefined, runtag: '', labels: [], issync: "0", syncparaencode: '', accuracys: "ma", duration: undefined, sortcode: undefined, description: '', creatoruserid: "", creatortime: "", lastmodifyuserid: "", lastmodifytime: "", } this.dataForms.push(item) }, delentryList(index) { this.dataForms.splice(index, 1); }, init(id) { if (id) { this.getequipmentledger = id; this.visible = true; this.eqchangeData() this.selectequipment() } else { this.visible = true; // this.$nextTick(() => { // this.$refs['elForm'].resetFields(); // if (this.dataForm.id) { // this.loading = true // request({ // url: '/api/example/Equipmentparameter/' + this.dataForm.id, // method: 'get' // }).then(res => { // this.dataInfo(res.data) // this.loading = false // }); // } else { this.clearData() // } // }); // this.$store.commit('generator/UPDATE_RELATION_DATA', {}) } }, dataFormSubmits() { if (!this.sparepartscostentryExist()) return this.btnLoading = true request({ url: '/api/example/Equipmentparameter/createlist', method: 'post', data: { list: JSON.stringify(this.dataForms), // 假设后端需要这个列表 equipid: this.getequipmentledger // 假设 getequipmentledger 是一个对象,并且有 id 属性 } }).then((res) => { this.$message({ message: res.msg, type: 'success', duration: 1000, onClose: () => { this.visible = false this.btnLoading = false this.$emit('refresh', true) } }) }).catch(() => { this.btnLoading = false }) }, // 表单提交 dataFormSubmit() { this.$refs['elForm'].validate((valid) => { if (valid) { this.request() } }) }, request() { this.btnLoading = true let _data = this.dataList() if (!this.dataForm.id) { request({ url: '/api/example/Equipmentparameter', method: 'post', data: _data }).then((res) => { this.$message({ message: res.msg, type: 'success', duration: 1000, onClose: () => { this.visible = false this.btnLoading = false this.$emit('refresh', true) } }) }).catch(() => { this.btnLoading = false }) } else { request({ url: '/api/example/Equipmentparameter/' + this.dataForm.id, method: 'PUT', data: _data }).then((res) => { this.$message({ message: res.msg, type: 'success', duration: 1000, onClose: () => { this.visible = false this.btnLoading = false this.$emit('refresh', true) } }) }).catch(() => { this.btnLoading = false }) } }, openSelectDialog(key) { this.currTableConf = this.addTableConf[key] this.currVmodel = key this.selectDialogVisible = true this.$nextTick(() => { this.$refs.selectDialog.init() }) }, addForSelect(data) { for (let i = 0; i < data.length; i++) { let item = { ...this.tableRows[this.currVmodel], ...data[i] } this.dataForm[this.currVmodel].push(item) } }, dataList() { var _data = JSON.parse(JSON.stringify(this.dataForms)); _data.labels = Array.isArray(_data.labels) ? JSON.stringify(_data.labels) : '[]' return _data; }, dataInfo(dataAll) { let _dataAll = dataAll _dataAll.labels = _dataAll.labels ? JSON.parse(_dataAll.labels) : [] this.dataForm = _dataAll this.isEdit = true this.dataAll() this.childIndex = -1 }, }, } </script> 上述代码,运行时在列表中功能标签不显示数据,实际有数据,而且点击下拉已选数据有显示<el-table-column prop="labels" label="功能标签" width="200" align="center"> <template slot-scope="scope"> <el-select v-model="scope.row.labels" @change="changeData('labels', -1)" placeholder="请选择" clearable :style='{ "width": "100%" }' filterable :multiple="true"> <el-option v-for="(item, index) in labelsOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> </el-select> </template> </el-table-column>,但不能选择操作。
09-13
<?xml version="1.0" encoding="UTF-8" ?> <!-- ~ /* ~ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. ~ */ --> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.huawei.it.tgmes.tmas.prodforecast.dao.IPfcResgroupPromiseDao"> <sql id ="hasEmptySearch"> <if test=" queryFactoryFlag != null and queryFactoryFlag eq 'Y'.toString() and hasEmptyFlag != null and (hasEmptyFlag eq 'Y'.toString() or hasEmptyFlag eq 'N'.toString() ) "> <if test=" hasEmptyFlag eq 'Y'.toString() " > and exists </if> <if test="hasEmptyFlag eq 'N'.toString() "> and not exists </if> (select 1 from t_pfc_forecast_resgroup_bucket pfrbc where <choose> <when test="functionType != null and functionType eq '2'.toString()" > (pfrbc.high_end_auto_line is null or pfrbc.standard_auto_line is null or pfrbc.low_end_auto_line is null) </when> <otherwise> (pfrbc.factory_qty is null or pfrbc.factory_line_qty is null) </otherwise> </choose> and pfrbc.operation_flag = '1' and pfrbc.pfr_id = pfr.pfr_id) </if> <if test=" queryFactoryFlag != null and queryFactoryFlag eq 'N'.toString() and hasEmptyFlag != null and (hasEmptyFlag eq 'Y'.toString() or hasEmptyFlag eq 'N'.toString() ) "> <if test=" hasEmptyFlag eq 'Y'.toString() " > and exists </if> <if test=" hasEmptyFlag eq 'N'.toString() "> and not exists </if> (select 1 from t_pfc_forecast_resgroup_bucket pfrbc where (pfrbc.ie_qty is null or pfrbc.ie_line_qty is null) and pfrbc.operation_flag in ('1','2') and pfrbc.pfr_id = pfr.pfr_id) </if> </sql> <sql id ="planIDSearch"> and pfr.plan_id in <choose> <when test=" planIDList != null and planIDList.size > 0 " > <foreach collection="planIDList" item="planID" separator="," index="index" open="(" close=")"> #{planID,jdbcType=VARCHAR} </foreach> </when> <otherwise> (select max(t.plan_id) from T_PFC_FORECAST_RESGROUP t where t.promise_type = '0') </otherwise> </choose> </sql> <sql id ="commonFieldSearch"> <if test=" supplyCenterCodeList != null and supplyCenterCodeList.size > 0 "> and pfr.supply_center_code in <foreach collection="supplyCenterCodeList" item="supplyCenterCode" separator="," index="index" open="(" close=")"> #{supplyCenterCode,jdbcType=VARCHAR} </foreach> </if> <if test=" prodLineCodeList != null and prodLineCodeList.size > 0 "> and pfr.prod_line_code in <foreach collection="prodLineCodeList" item="prodLineCode" separator="," index="index" open="(" close=")"> #{prodLineCode,jdbcType=VARCHAR} </foreach> </if> <if test=" prodAreaCodeList != null and prodAreaCodeList.size > 0 "> and pfr.prod_area_code in <foreach collection="prodAreaCodeList" item="prodAreaCode" separator="," index="index" open="(" close=")"> #{prodAreaCode,jdbcType=VARCHAR} </foreach> </if> <if test=" prodFamilyCodeList != null and prodFamilyCodeList.size > 0 "> and pfr.prod_family_code in <foreach collection="prodFamilyCodeList" item="prodFamilyCode" separator="," index="index" open="(" close=")"> #{prodFamilyCode,jdbcType=VARCHAR} </foreach> </if> <if test=" prodSeriesCodeList != null and prodSeriesCodeList.size > 0 "> and pfr.prod_series_code in <foreach collection="prodSeriesCodeList" item="prodSeriesCode" separator="," index="index" open="(" close=")"> #{prodSeriesCode,jdbcType=VARCHAR} </foreach> </if> <if test=" prodResgroupList != null and prodResgroupList.size > 0 "> and pfr.prod_resgroup in <foreach collection="prodResgroupList" item="prodResgroup" separator="," index="index" open="(" close=")"> #{prodResgroup,jdbcType=VARCHAR} </foreach> </if> <if test="factoryCodeList != null and factoryCodeList.size > 0"> and pfr.factory_code in <foreach collection="factoryCodeList" item="factoryCode" separator="," index="index" open="(" close=")"> #{factoryCode,jdbcType=VARCHAR} </foreach> </if> <if test="siteCodeList != null and siteCodeList.size > 0"> and pfr.site_code in <foreach collection="siteCodeList" item="siteCode" separator="," index="index" open="(" close=")"> #{siteCode,jdbcType=VARCHAR} </foreach> </if> <if test="locationNameList != null and locationNameList.size > 0"> and pfr.location_name in <foreach collection="locationNameList" item="locationName" separator="," index="index" open="(" close=")"> #{locationName,jdbcType=VARCHAR} </foreach> </if> <if test="mfgTypeList != null and mfgTypeList.size > 0"> and pfr.mfg_type in <foreach collection="mfgTypeList" item="mfgType" separator="," index="index" open="(" close=")"> #{mfgType,jdbcType=VARCHAR} </foreach> </if> <if test="supplyModeList != null and supplyModeList.size > 0"> and pfr.supply_mode in <foreach collection="supplyModeList" item="supplyMode" separator="," index="index" open="(" close=")"> #{supplyMode,jdbcType=VARCHAR} </foreach> </if> <if test="produceTypeCodeList != null and produceTypeCodeList.size > 0"> and pfr.produce_type_code in <foreach collection="produceTypeCodeList" item="produceTypeCode" separator="," index="index" open="(" close=")"> #{produceTypeCode,jdbcType=VARCHAR} </foreach> </if> </sql> <sql id= "condition"> and pfr.promise_type = '0' <if test=" factoryVisibleFlagStr != null and factoryVisibleFlagStr eq 'Y'.toString() "> and pfr.factory_visible_flag = 'Y' </if> <include refid="hasEmptySearch"/> <include refid="commonFieldSearch"/> <include refid="planIDSearch"/> </sql> <select id="getPfcResgroupListByCondition" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroup"> select pfr_id id, plan_id, supply_center_id, supply_center_code, supply_center_name_cn, supply_center_name_en, prod_line_code, prod_line_cn_name, prod_line_en_name, prod_area_code, prod_area_cn_name, prod_area_en_name, prod_family_code, prod_family_cn_name, prod_family_en_name, prod_series_code, prod_series_cn_name, prod_series_en_name, prod_resgroup, prod_resgroup_desc, process_plan_useraccount, process_plan_username, mfg_type, plan_operation_enty_name, produce_type_code produce_type, produce_type_cn, produce_type_en, factory_code, factory_name, overseas_ckd_flag, remark, created_by, creation_date, last_updated_by, last_updated_date, vendor_code, location_code, site_code, location_name from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> <if test="permissionFlag == true"> and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = pfr.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) </if> </where> </select> <select id="getPfcResgroupBucketList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroupBucket"> select pfrb.pfrb_id as id, pfrb.pfr_id as pfrID, pfrb.bucket, pfrb.bucket_type, pfrb.system_qty, pfrb.system_line_qty, pfrb.promise_qty, pfrb.promise_line_qty, pfrb.promise_qty_account, pfrb.factory_qty, pfrb.factory_line_qty, pfrb.ie_qty, pfrb.ie_line_qty, pfrb.high_end_auto_line, pfrb.standard_auto_line, pfrb.low_end_auto_line, pfrb.remark, pfrb.created_by, pfrb.creation_date, pfrb.last_updated_by, pfrb.last_updated_date from T_PFC_FORECAST_RESGROUP pfr left join T_PFC_FORECAST_RESGROUP_BUCKET pfrb on pfrb.pfr_id = pfr.pfr_id <where> <include refid="condition"/> <if test=" pfrIDList!= null and pfrIDList.size > 0"> and pfrb.pfr_id in <foreach collection="pfrIDList" item="pfrID" open="(" separator="," close=")"> #{pfrID,jdbcType=VARCHAR} </foreach> </if> <choose> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'Y'.toString() " > and pfrb.operation_flag = '1' </when> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'N'.toString() " > and pfrb.operation_flag in ('1','2') </when> <otherwise> and 1 = 2 </otherwise> </choose> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> </where> </select> <select id="getPfcResgroupBucketSumList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.PfcForecastResgroupBucketSum"> select pfrb.bucket, sum(coalesce(pfrb.high_end_auto_line, 0) + coalesce(pfrb.standard_auto_line, 0) + coalesce(pfrb.low_end_auto_line, 0)) as sumNum from T_PFC_FORECAST_RESGROUP pfr left join T_PFC_FORECAST_RESGROUP_BUCKET pfrb on pfrb.pfr_id = pfr.pfr_id <where> <include refid="condition"/> <if test=" pfrIDList!= null and pfrIDList.size > 0"> and pfrb.pfr_id in <foreach collection="pfrIDList" item="pfrID" open="(" separator="," close=")"> #{pfrID,jdbcType=VARCHAR} </foreach> </if> <choose> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'Y'.toString() " > and pfrb.operation_flag = '1' </when> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'N'.toString() " > and pfrb.operation_flag in ('1','2') </when> <otherwise> and 1 = 2 </otherwise> </choose> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> </where> group by pfrb.bucket </select> <select id="getBucketSumListForProdSeries" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.PfcForecastResgroupBucketSum"> select pfr.prod_series_en_name, pfrb.bucket, sum(coalesce(pfrb.high_end_auto_line, 0) + coalesce(pfrb.standard_auto_line, 0) + coalesce(pfrb.low_end_auto_line, 0)) as sumNum from T_PFC_FORECAST_RESGROUP pfr left join T_PFC_FORECAST_RESGROUP_BUCKET pfrb on pfrb.pfr_id = pfr.pfr_id <where> <include refid="condition"/> <if test=" pfrIDList!= null and pfrIDList.size > 0"> and pfrb.pfr_id in <foreach collection="pfrIDList" item="pfrID" open="(" separator="," close=")"> #{pfrID,jdbcType=VARCHAR} </foreach> </if> <choose> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'Y'.toString() " > and pfrb.operation_flag = '1' </when> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'N'.toString() " > and pfrb.operation_flag in ('1','2') </when> <otherwise> and 1 = 2 </otherwise> </choose> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> </where> group by pfr.prod_series_en_name, pfrb.bucket </select> <update id="updateFactoryPromiseList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.UpdatePfcForecastResgroupBucket"> <foreach collection="updatePfcForecastResgroupBuckets" item="bucket"> <if test=" bucket.typeCode != null"> update t_pfc_forecast_resgroup_bucket pfrb set <if test=" bucket.typeCode eq 'FACTORY_QTY'.toString() "> factory_qty = #{bucket.factoryQty,jdbcType=INTEGER}, </if> <if test=" bucket.typeCode eq 'FACTORY_LINE_QTY'.toString() "> factory_line_qty = #{bucket.factoryLineQty,jdbcType=DOUBLE}, </if> <if test=" bucket.typeCode eq 'HIGH_END_AUTO_LINE'.toString() "> high_end_auto_line = #{bucket.highEndAutoLine,jdbcType=DOUBLE}, </if> <if test=" bucket.typeCode eq 'STANDARD_AUTO_LINE'.toString() "> standard_auto_line = #{bucket.standardAutoLine,jdbcType=DOUBLE}, </if> <if test=" bucket.typeCode eq 'LOW_END_AUTO_LINE'.toString() "> low_end_auto_line = #{bucket.lowEndAutoLine,jdbcType=DOUBLE}, </if> <if test=" bucket.typeCode eq 'FACTORY_QTY'.toString() || bucket.typeCode eq 'FACTORY_LINE_QTY'.toString() "> factory_last_updated_by = #{bucket.lastUpdatedBy,jdbcType=VARCHAR}, factory_last_updated_date = cast(#{bucket.lastUpdatedDate} as timestamp), </if> last_updated_by = #{bucket.lastUpdatedBy,jdbcType=VARCHAR}, last_updated_date = cast(#{bucket.lastUpdatedDate} as timestamp) where <choose> <when test="authFactoryCodeList != null and authFactoryCodeList.size > 0" > exists (select 1 from t_pfc_forecast_resgroup pfr where pfr.pfr_id = pfrb.pfr_id and pfr.factory_visible_flag = 'Y' and pfr.factory_code in <foreach collection="authFactoryCodeList" item="authFactoryCode" separator="," index="index" open="(" close=")"> #{authFactoryCode,jdbcType=VARCHAR} </foreach> ) </when> <otherwise> 1 = 2 </otherwise> </choose> and pfrb.operation_flag = '1' and pfrb.pfrb_id = #{bucket.id,jdbcType=VARCHAR}; </if> </foreach> </update> <delete id="deleteForecastResgroupTempbyUser" parameterType="java.lang.String" > delete from t_pfc_forecast_resgroup_temp t where t.last_updated_by = #{lastUpdatedBy,jdbcType=VARCHAR}; delete from t_pfc_forecast_resgroup_bk_tp t where t.last_updated_by = #{lastUpdatedBy,jdbcType=VARCHAR}; </delete> <insert id="batchInsertForecastResgroupTemp" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroup"> <if test=" pfcForecastResgroupList != null and pfcForecastResgroupList.size > 0 "> <foreach collection="pfcForecastResgroupList" item="pfcForecastResgroup"> insert into T_PFC_FORECAST_RESGROUP_TEMP( PFR_ID, PLAN_ID, SUPPLY_CENTER_NAME_CN, PROD_LINE_CN_NAME, PROD_AREA_CN_NAME, PROD_FAMILY_CN_NAME, PROD_SERIES_CN_NAME, PROD_RESGROUP_DESC, PROCESS_PLAN_USERACCOUNT, MFG_TYPE, PLAN_OPERATION_ENTY_NAME, PRODUCE_TYPE_CN, OVERSEAS_CKD_FLAG, LAST_UPDATED_BY, LAST_UPDATED_DATE, SITE_CODE, LOCATION_NAME) values ( #{pfcForecastResgroup.id,jdbcType=VARCHAR}, #{pfcForecastResgroup.planID,jdbcType=VARCHAR}, #{pfcForecastResgroup.supplyCenterNameCn,jdbcType=VARCHAR}, #{pfcForecastResgroup.prodLineCnName,jdbcType=VARCHAR}, #{pfcForecastResgroup.prodAreaCnName,jdbcType=VARCHAR}, #{pfcForecastResgroup.prodFamilyCnName,jdbcType=VARCHAR}, #{pfcForecastResgroup.prodSeriesCnName,jdbcType=VARCHAR}, #{pfcForecastResgroup.prodResgroupDesc,jdbcType=VARCHAR}, #{pfcForecastResgroup.processPlanUseraccount,jdbcType=VARCHAR}, #{pfcForecastResgroup.mfgType,jdbcType=VARCHAR}, #{pfcForecastResgroup.planOperationEntyName,jdbcType=VARCHAR}, #{pfcForecastResgroup.produceTypeCn,jdbcType=VARCHAR}, #{pfcForecastResgroup.overseasCkdFlag,jdbcType=VARCHAR}, #{pfcForecastResgroup.lastUpdatedBy,jdbcType=VARCHAR}, cast(#{pfcForecastResgroup.lastUpdatedDate} as timestamp), #{pfcForecastResgroup.siteCode,jdbcType=VARCHAR}, #{pfcForecastResgroup.locationName,jdbcType=VARCHAR}); <foreach collection="pfcForecastResgroup.pfcForecastResgroupBucketList" item="bucket"> insert into T_PFC_FORECAST_RESGROUP_BK_TP( PFR_ID, BUCKET, BUCKET_TYPE, FACTORY_QTY, FACTORY_LINE_QTY, IE_QTY, IE_LINE_QTY, LAST_UPDATED_BY, LAST_UPDATED_DATE) values ( #{bucket.pfrID,jdbcType=VARCHAR}, #{bucket.bucket,jdbcType=VARCHAR}, #{bucket.bucketType,jdbcType=VARCHAR}, #{bucket.factoryQty,jdbcType=INTEGER}, #{bucket.factoryLineQty}, #{bucket.ieQty,jdbcType=INTEGER}, #{bucket.ieLineQty}, #{bucket.lastUpdatedBy,jdbcType=VARCHAR}, cast(#{bucket.lastUpdatedDate} as timestamp)); </foreach> </foreach> </if> </insert> <select id="getImportForecastResgroupExist" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroup" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroup"> select pfr.plan_id as planID, pfr.supply_center_name_cn, pfr.mfg_type, pfr.plan_operation_enty_name, pfr.prod_resgroup_desc, pfr.produce_type_cn, pfr.factory_code, pfr.location_name, pfr.pfr_id id, pfr.factory_visible_flag from t_pfc_forecast_resgroup pfr where pfr.promise_type = '0' and (pfr.plan_id, pfr.supply_center_name_cn, pfr.mfg_type, pfr.plan_operation_enty_name, pfr.prod_resgroup_desc, pfr.produce_type_cn, pfr.location_name) in <foreach collection="itemList" item="item" separator="," index="index" open="(" close=")"> (#{item.planID}, #{item.supplyCenterNameCn}, #{item.mfgType}, #{item.planOperationEntyName}, #{item.prodResgroupDesc}, #{item.produceTypeCn}, #{item.locationName}) </foreach> </select> <update id="updateFactoryPromiseListByIdBuketNew" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroupBucket"> update t_pfc_forecast_resgroup_bucket b set factory_qty = COALESCE(cast(#{item.factoryQty} as Integer), b.ie_qty), factory_line_qty = COALESCE(#{item.factoryLineQty,jdbcType=DOUBLE}, b.ie_line_qty), last_updated_by = #{item.lastUpdatedBy,jdbcType=VARCHAR}, last_updated_date = cast(#{item.lastUpdatedDate,jdbcType=TIMESTAMP} as timestamp), ie_last_updated_by = #{item.lastUpdatedBy,jdbcType=VARCHAR}, ie_last_updated_date = cast(#{item.lastUpdatedDate,jdbcType=TIMESTAMP} as timestamp) where b.pfr_id = #{item.insertId,jdbcType=VARCHAR} and to_char(b.BUCKET, 'yy-mm-dd') = to_char(cast(#{item.bucket,jdbcType=TIMESTAMP} as timestamp), 'yy-mm-dd') and b.operation_flag = '1'; </update> <update id="updateTerminalAutoLinePromiseListById" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroupBucket"> update t_pfc_forecast_resgroup_bucket b set <if test="item.highEndAutoLine != null"> high_end_auto_line = #{item.highEndAutoLine,jdbcType=DOUBLE}, </if> <if test="item.standardAutoLine != null"> standard_auto_line = #{item.standardAutoLine,jdbcType=DOUBLE}, </if> <if test="item.lowEndAutoLine != null"> low_end_auto_line = #{item.lowEndAutoLine,jdbcType=DOUBLE}, </if> last_updated_by = #{item.lastUpdatedBy,jdbcType=VARCHAR}, last_updated_date = cast(#{item.lastUpdatedDate,jdbcType=TIMESTAMP} as timestamp) where b.pfr_id = #{item.insertId,jdbcType=VARCHAR} and to_char(b.BUCKET, 'yy-mm-dd') = to_char(cast(#{item.bucket,jdbcType=TIMESTAMP} as timestamp), 'yy-mm-dd') and b.operation_flag = '1'; </update> <update id="updateIEPromiseListFromSelectTemp" parameterType="java.util.List"> <foreach collection="tempList" item="item"> update t_pfc_forecast_resgroup_bucket b set ie_qty = coalesce(cast(#{item.ie_qty} as Integer),b.ie_qty), ie_line_qty = coalesce(#{item.ie_line_qty,jdbcType=DOUBLE},b.ie_line_qty), last_updated_by = #{item.last_updated_by}, last_updated_date =cast(#{item.last_updated_date} as timestamp), ie_last_updated_by = #{item.ie_last_updated_by}, ie_last_updated_date = cast(#{item.ie_last_updated_date} as timestamp) where b.pfrb_id = #{item.pfrb_id}; </foreach> </update> <select id="getPlanIDList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.plan_id as key, pfr.plan_id as value from T_PFC_FORECAST_RESGROUP pfr where pfr.promise_type = '0' group by pfr.plan_id order by pfr.plan_id desc </select> <select id="getMaxPlanID" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="java.lang.String"> select max(pfr.plan_id) from T_PFC_FORECAST_RESGROUP pfr where pfr.promise_type = '0' </select> <select id="getThisMonthPlanIDList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="string"> select o.plan_id from ( select pfr.plan_id,(regexp_matches(pfr.plan_id, '[0-9]+'))[1] str from T_PFC_FORECAST_RESGROUP pfr where pfr.promise_type = '0' ) o where str between cast(#{beginDateStr,jdbcType=VARCHAR} as varchar) and cast(#{endDateStr,jdbcType=VARCHAR} as varchar) group by o.plan_id </select> <select id="getPfcResgroupDateList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select 'f'||to_char(pfrb.bucket, 'yyyymmdd') as key, to_char(pfrb.bucket, 'yyyy/mm/dd')||(case when pfrb.bucket_type = 'WEEK' then '()' else '()' end ) as value from T_PFC_FORECAST_RESGROUP_BUCKET pfrb, T_PFC_FORECAST_RESGROUP pfr where pfr.plan_id in <foreach collection="planIDList" item="planID" separator="," index="index" open="(" close=")"> #{planID,jdbcType=VARCHAR} </foreach> and pfrb.PFR_ID = pfr.PFR_ID and pfrb.bucket is not null and pfrb.bucket_type is not null and pfr.promise_type = '0' <choose> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'Y'.toString() " > and pfrb.operation_flag = '1' </when> <when test=" queryFactoryFlag != null and queryFactoryFlag eq 'N'.toString() " > and pfrb.operation_flag in ('1','2') </when> <otherwise> and 1 = 2 </otherwise> </choose> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> group by pfrb.bucket,pfrb.bucket_type order by pfrb.bucket asc </select> <select id="getSupplyCenterList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.supply_center_code as key, pfr.supply_center_name_cn as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> </where> group by pfr.supply_center_code,pfr.supply_center_name_cn </select> <select id="getSupplyCenterList2" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.supply_center_code as key, pfr.supply_center_name_cn as value from T_PFC_FORECAST_RESGROUP pfr where 1=1 <choose> <when test=" planIDList != null and planIDList.size > 0 " > and pfr.plan_id in <foreach collection="planIDList" item="planID" separator="," index="index" open="(" close=")"> #{planID,jdbcType=VARCHAR} </foreach> </when> </choose> group by pfr.supply_center_code,pfr.supply_center_name_cn </select> <select id="getMfgTypeList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.mfg_type as key, pfr.mfg_type as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> </where> group by pfr.mfg_type </select> <select id="getProduceTypeList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.produce_type_code as key, pfr.produce_type_cn as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> </where> group by pfr.produce_type_code,pfr.produce_type_cn </select> <select id="getProdLineList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.prod_line_code as key, pfr.prod_line_cn_name as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> <if test="permissionFlag == true"> and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = pfr.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) </if> </where> group by pfr.prod_line_code,pfr.prod_line_cn_name </select> <select id="getProdAreaList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.prod_area_code as key, pfr.prod_area_cn_name as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> <if test="permissionFlag == true"> and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = pfr.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) </if> </where> group by pfr.prod_area_code,pfr.prod_area_cn_name </select> <select id="getProdFamilyList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.prod_family_code as key, pfr.prod_family_cn_name as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> <if test="permissionFlag == true"> and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = pfr.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) </if> </where> group by pfr.prod_family_code,pfr.prod_family_cn_name </select> <select id="getProdSeriesList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.prod_series_code as key, pfr.prod_series_en_name as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> <if test="permissionFlag == true"> and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = pfr.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) </if> </where> group by pfr.prod_series_code,pfr.prod_series_en_name </select> <select id="getProdResgroupList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.prod_resgroup as key, pfr.prod_resgroup_desc as value from T_PFC_FORECAST_RESGROUP pfr <where> <include refid="condition"/> </where> group by pfr.prod_resgroup,pfr.prod_resgroup_desc </select> <select id="getFactoryList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.factory_code as key, pfr.factory_name as value from t_pfc_forecast_resgroup pfr <where> <include refid="condition"/> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> </where> group by pfr.factory_code,pfr.factory_name </select> <select id="getLocationList" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.QueryPfcResgroupPromiseCondition" resultType="com.huawei.it.tgmes.tmas.basedata.entity.vo.KeyValue"> select pfr.site_code as key, pfr.location_name as value from t_pfc_forecast_resgroup pfr <where> <include refid="condition"/> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> </where> group by pfr.site_code,pfr.location_name </select> <select id="getForecastPlanDates" parameterType="map" resultType="java.lang.String"> select FN_GET_FORECAST_DATES(#{planID,jdbcType=VARCHAR},#{operationFlag,jdbcType=VARCHAR},#{bucketType,jdbcType=VARCHAR}) </select> <update id="calcMinFactoryLineQty1"> UPDATE T_PFC_FORECAST_RESGROUP_BUCKET SET FACTORY_LINE_QTY = HUMAN_LINE_QTY WHERE HUMAN_LINE_QTY IS NOT NULL AND PFR_ID = any(#{pfrIdArray}) </update> <select id="getPfcResgroupBucketById" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroup"> select pfrb.pfrb_id as id, pfrb.pfr_id as pfrID, pfr.plan_id from T_PFC_FORECAST_RESGROUP pfr left join T_PFC_FORECAST_RESGROUP_BUCKET pfrb on pfrb.pfr_id = pfr.pfr_id where pfrb.pfrb_id = #{pfrbId,jdbcType=VARCHAR} <if test="flag"> and pfrb.operation_flag = '1' </if> <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:pfr.factory_code"></addProgram> ]]> </select> <select id="getFactoryQtyData" resultType="com.huawei.it.tgmes.tmas.ebc.entity.bo.TiPfcForecastResgroup"> select t.plan_id, t.prod_line_cn_name, t.prod_area_cn_name, t.prod_family_cn_name, t.prod_series_cn_name, t.prod_resgroup_desc, t.produce_type_cn, t.overseas_ckd_flag, r.bucket, r.bucket_type, r.promise_qty, r.factory_qty, r.promise_line_qty, r.factory_line_qty, t.factory_code, t.factory_name, r.created_by, r.creation_date, r.last_updated_by, r.last_updated_date from T_PFC_FORECAST_RESGROUP t left join T_PFC_FORECAST_RESGROUP_BUCKET r on t.pfr_id = r.pfr_id where t.promise_type = '0' and t.factory_visible_flag = 'Y' and r.operation_flag = '1' and t.plan_id = #{maxPlanId} and t.factory_code in <foreach collection="factoryList" item="factoryList" open="(" separator="," close=")"> #{factoryList.valueInfo,jdbcType=VARCHAR} </foreach> </select> <select id="getLastPlanId" parameterType="string" resultType="string"> select max(plan_id) from T_PFC_FORECAST_RESGROUP where plan_id <![CDATA[ < ]]> #{planId}; </select> <select id="getForecastHeadInfo" parameterType="string" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.PfcForecastResgroupAutoLineVO"> select h.pfr_id, h.plan_id, h.supply_center_name_cn, h.plan_operation_enty_name, h.mfg_type, h.produce_type_code, h.site_code, h.prod_resgroup from t_pfc_forecast_resgroup h where plan_id = #{planId} and promise_type = '0' and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = h.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:h.factory_code"></addProgram> ]]> </select> <select id="getForecastAutoLineInfo" parameterType="string" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.PfcForecastResgroupAutoLineVO"> select h.plan_id, h.supply_center_name_cn, h.plan_operation_enty_name, h.mfg_type, h.produce_type_code, h.site_code, h.prod_resgroup, b.bucket, b.high_end_auto_line, b.low_end_auto_line, b.standard_auto_line from t_pfc_forecast_resgroup h inner join t_pfc_forecast_resgroup_bucket b on b.pfr_id = h.pfr_id where plan_id = #{planId} and b.operation_flag = '1' and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = h.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) <![CDATA[ <addProgram prepend ="and" dimensions2Fields="FactoryInfo:h.factory_code"></addProgram> ]]> </select> <update id="updateForecastAutoLine" parameterType="com.huawei.it.tgmes.tmas.prodforecast.entity.vo.PfcForecastResgroupAutoLineVO"> update t_pfc_forecast_resgroup_bucket set high_end_auto_line = #{vo.highEndAutoLine}, standard_auto_line = #{vo.standardAutoLine}, low_end_auto_line = #{vo.lowEndAutoLine}, last_updated_by = #{vo.lastUpdatedBy}, last_updated_date = #{vo.lastUpdatedDate} where bucket = #{vo.bucket} and pfr_id = #{vo.pfrId} </update> <select id="getProdLineAreaFamilySeriesById" resultType="com.huawei.it.tgmes.tmas.prodforecast.entity.bo.PfcForecastResgroup"> select prod_line_code, prod_area_code, prod_family_code, prod_series_code from t_pfc_forecast_resgroup h <where> <if test="pfrIdArray != null and pfrIdArray.length > 0"> h.pfr_id = any(#{pfrIdArray}) </if> </where> </select> <select id="getPfrIdById" resultType="String"> select pfr_id from t_pfc_forecast_resgroup_bucket h <where> <if test="idArray != null and idArray.length > 0"> h.pfrb_id = any(#{idArray}) </if> </where> </select> <select id="calcPermissionPfrIdByPlanId" resultType="string"> select pfr.pfr_id from T_PFC_FORECAST_RESGROUP pfr where plan_id = #{planID} and exists ( select 1 from t_product_type_rel_v r where r.prod_line_code = pfr.prod_line_code <![CDATA[ <addProgram prepend ="and" dimensions2Fields="ProductTypeInfo:r.product_type"></addProgram> ]]> ) </select> </mapper> 结合这个分析是不是13周前的日期是天维度,13周之后是周维度, /** * 功能类型:1 【1-3系统月工厂承诺】; 2 【未来1-3个月终端工厂承诺】 */ private String functionType;
最新发布
10-28
<template> <div class="app-container"> <el-tabs v-model="activeTab" class="setting-tabs" type="border-card"> <!-- 收件人管理标签页 --> <el-tab-pane label="收件人管理" name="receivers"> <el-card class="setting-card"> <template #header> <div class="card-header"> <el-icon class="header-icon"><User /></el-icon> <span>收件人管理</span> <el-text type="info" class="header-desc">管理接收提醒邮件的人员信息</el-text> </div> </template> <div class="card-content"> <!-- 选择用户区域 --> <el-form inline class="add-receiver-form"> <el-form-item label="选择用户"> <el-input v-model="userSearchText" placeholder="点击搜索框选择用户" readonly @click="openUserSelectModal" class="user-select-input" > <template #suffix> <el-icon class="search-icon" @click.stop="openUserSelectModal"> <Search /> </el-icon> </template> </el-input> </el-form-item> <el-form-item> <el-button type="primary" :icon="Plus" @click="handleAddSelectedUsers" :disabled="selectedUserIds.length === 0" > 添加到收件人列表 </el-button> </el-form-item> </el-form> <!-- 已选用户预览 --> <div v-if="selectedUserIds.length > 0" class="selected-users-preview"> <el-tag v-for="userId in selectedUserIds" :key="userId" closable @close="removeSelectedUser(userId)" class="selected-tag" > {{ getUserNameById(userId) }} </el-tag> </div> <!-- 已选收件人列表 --> <div class="receiver-list-container"> <el-table :data="filteredReceivers" border stripe :loading="receiverLoading" class="receiver-table" max-height="400" row-key="recipientId" > <el-table-column type="index" label="序号" width="80" align="center" /> <el-table-column prop="recipientName" label="姓名" width="160" /> <el-table-column prop="email" label="邮箱地址" min-width="200"> <template #default="scope"> <el-tooltip :content="scope.row.email || '未设置邮箱'" placement="top"> <span class="email-text">{{ scope.row.email || '未设置邮箱' }}</span> </el-tooltip> </template> </el-table-column> <el-table-column label="状态" width="120" align="center"> <template #default="scope"> <el-switch v-model="scope.row.status" active-value="1" inactive-value="0" @change="handleStatusChange(scope.row)" :loading="scope.row.statusLoading" /> </template> </el-table-column> <el-table-column label="是否默认" width="120" align="center"> <template #default="scope"> <el-checkbox v-model="scope.row.isDefault" :true-label="1" :false-label="0" @change="handleDefaultChange(scope.row)" :disabled="scope.row.defaultDisabled" /> </template> </el-table-column> <el-table-column label="排序" width="100" align="center"> <template #default="scope"> <el-input-number v-model="scope.row.sort" min="0" @change="handleSortChange(scope.row)" size="small" :disabled="scope.row.sortDisabled" /> </template> </el-table-column> <el-table-column label="操作" width="160" align="center"> <template #default="scope"> <el-button size="small" type="text" @click="handleEditReceiver(scope.row)" :icon="Edit" :disabled="scope.row.operateDisabled" /> <el-button size="small" type="text" text-color="#F53F3F" @click="handleDeleteReceiver(scope.row.recipientId)" :icon="Delete" :disabled="scope.row.operateDisabled" /> </template> </el-table-column> </el-table> <div v-if="filteredReceivers.length === 0 && !receiverLoading" class="empty-state"> <el-empty description="暂无收件人,请从系统用户中选择" /> </div> <div class="form-actions"> <el-button type="primary" @click="handleSaveReceivers" :icon="Check" :loading="saveReceiversLoading" > 保存收件人设置 </el-button> </div> </div> </div> </el-card> </el-tab-pane> <!-- 发送配置标签页 --> <el-tab-pane label="发送配置" name="config"> <el-card class="setting-card"> <template #header> <div class="card-header"> <el-icon class="header-icon"><Clock /></el-icon> <span>发送配置</span> <el-text type="info" class="header-desc">配置邮件发送服务器及提醒频率</el-text> </div> </template> <div class="card-content"> <el-form :model="sendConfig" :rules="configRules" ref="configFormRef" class="config-form" label-width="160px" > <!-- 基础SMTP配置 --> <el-collapse v-model="activeCollapse" class="config-collapse"> <el-collapse-item title="SMTP服务器配置" name="smtp"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="是否启用邮件发送" prop="enable"> <el-switch v-model="sendConfig.enable" active-value="1" inactive-value="0" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="发件人显示名称" prop="senderName"> <el-input v-model="sendConfig.senderName" placeholder="请输入发件人显示名称" class="input-control" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="SMTP服务器地址" prop="host"> <el-input v-model="sendConfig.host" placeholder="如: smtp.qq.com" class="input-control" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="SMTP服务器端口" prop="port"> <el-input-number v-model="sendConfig.port" min="1" max="65535" class="input-control" placeholder="如: 587" /> </el-form-item> </el-col> </el-row> </el-collapse-item> <!-- 提醒频率配置 --> <el-collapse-item title="提醒频率配置" name="frequency"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="发送频率" prop="frequency"> <el-select v-model="sendConfig.frequency" placeholder="请选择发送频率" class="input-control" @change="handleFrequencyChange" > <el-option label="每天" value="daily" /> <el-option label="每周" value="weekly" /> <el-option label="每月" value="monthly" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="发送时间" prop="sendTime"> <el-time-picker v-model="sendConfig.sendTime" format="HH:mm" value-format="HH:mm" placeholder="选择发送时间" class="input-control" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="提前__天" prop="advanceTime"> <el-input-number v-model="sendConfig.advanceTime" min="0" placeholder="请输入提前天数" class="input-control" /> </el-form-item> </el-col> </el-row> </el-collapse-item> </el-collapse> <el-form-item class="form-actions"> <el-button type="primary" @click="handleSaveConfig" :icon="Check" :loading="saveConfigLoading" > 保存发送配置 </el-button> </el-form-item> </el-form> </div> </el-card> </el-tab-pane> <!-- 邮件模板标签页 --> <el-tab-pane label="邮件模板" name="template"> <el-card class="setting-card"> <template #header> <div class="card-header"> <el-icon class="header-icon"><Document /></el-icon> <span>邮件模板</span> <el-text type="info" class="header-desc">自定义提醒邮件的模板内容</el-text> </div> </template> <div class="card-content"> <!-- 模板类型选择 --> <el-radio-group v-model="activeTemplateType" class="template-type-group" @change="handleTemplateTypeChange" :disabled="templateLoading" > <el-radio-button label="license">项目授权到期提醒</el-radio-button> <el-radio-button label="maintenance">项目运维到期提醒</el-radio-button> </el-radio-group> <el-form :model="currentTemplate" :rules="templateRules" ref="templateFormRef" class="template-form" label-width="140px" :disabled="templateLoading" > <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="模板名称" prop="templateName"> <el-input v-model="currentTemplate.templateName" placeholder="请输入模板名称" class="input-control" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="模板状态" prop="status"> <el-switch v-model="currentTemplate.status" active-value="1" inactive-value="0" /> </el-form-item> </el-col> </el-row> <el-form-item label="邮件标题" prop="subject"> <el-input v-model="currentTemplate.subject" placeholder="请输入邮件标题" class="input-control" /> <el-text type="info" class="help-text">点击下方变量可快速插入</el-text> </el-form-item> <el-form-item label="邮件内容" prop="content"> <el-input v-model="currentTemplate.content" type="textarea" rows="10" placeholder="请输入邮件内容" class="input-control" /> <div class="template-variables"> <el-text type="info">支持变量:</el-text> <el-tag v-for="(desc, key) in getAvailableVariables()" :key="key" class="variable-tag" @click="insertVariable(key)" > ${key} <span class="variable-desc">={{ desc }}</span> </el-tag> </div> </el-form-item> <el-form-item> <el-button type="primary" @click="handlePreviewTemplate" :icon="View" class="preview-btn" > 预览 </el-button> <el-button type="success" @click="handleSaveTemplate" :icon="Check" :loading="saveTemplateLoading" > 保存模板 </el-button> </el-form-item> </el-form> </div> </el-card> </el-tab-pane> <!-- 提醒规则配置标签页 --> <el-tab-pane label="提醒规则" name="reminder"> <el-card class="setting-card"> <template #header> <div class="card-header"> <el-icon class="header-icon"><Star /></el-icon> <span>提醒规则配置</span> <el-text type="info" class="header-desc">设置项目到期提醒的触发条件与规则</el-text> </div> </template> <div class="card-content"> <el-form :model="reminderRule" :rules="reminderRules" ref="reminderFormRef" class="reminder-form" label-width="180px" > <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="是否启用提醒规则" prop="enable"> <el-switch v-model="reminderRule.enable" active-value="1" inactive-value="0" @change="handleRuleEnableChange" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="提醒触发类型" prop="triggerType"> <el-select v-model="reminderRule.triggerType" placeholder="请选择触发类型" class="input-control" :disabled="reminderRule.enable === '0'" > <el-option label="按到期时间" value="expireDate" /> <el-option label="按剩余天数" value="remainingDays" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20" v-if="reminderRule.enable === '1'"> <el-col :span="12"> <el-form-item label="提前提醒天数" prop="advanceDays" :rules="[ { required: reminderRule.triggerType === 'remainingDays', message: '请输入提前提醒天数', trigger: 'blur' }, { type: 'number', min: 0, message: '提前天数不能为负数', trigger: 'blur' } ]" > <el-input-number v-model="reminderRule.advanceDays" min="0" placeholder="如:7(提前7天提醒)" class="input-control" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="重复提醒间隔" prop="repeatInterval"> <el-select v-model="reminderRule.repeatInterval" placeholder="请选择重复间隔" class="input-control" > <el-option label="不重复" value="none" /> <el-option label="每天" value="daily" /> <el-option label="每3天" value="3days" /> <el-option label="每周" value="weekly" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20" v-if="reminderRule.enable === '1'"> <el-col :span="24"> <el-form-item label="适用项目类型" prop="projectTypes"> <el-select v-model="reminderRule.projectTypes" placeholder="请选择适用项目类型(可多选)" class="input-control" multiple > <el-option label="授权项目" value="license" /> <el-option label="运维项目" value="maintenance" /> <el-option label="定制开发项目" value="custom" /> </el-select> </el-form-item> </el-col> </el-row> <el-form-item class="form-actions"> <el-button type="primary" @click="handleSaveReminderRule" :icon="Check" :loading="saveReminderLoading" > 保存提醒规则 </el-button> </el-form-item> </el-form> </div> </el-card> </el-tab-pane> </el-tabs> <!-- 用户选择弹窗 --> <el-dialog v-model="userSelectModalVisible" title="选择用户" width="70%" max-height="80vh" :before-close="handleModalClose" :close-on-click-modal="false" > <div class="user-modal-content"> <!-- 搜索框 --> <el-input v-model="modalSearchQuery" placeholder="输入用户名邮箱搜索" class="modal-search-input" @input="handleModalSearch" > <template #suffix> <el-icon> <Search /> </el-icon> </template> </el-input> <!-- 用户列表 --> <el-table :data="filteredModalUsers" border stripe :loading="modalUserLoading" class="user-select-table" max-height="500px" @selection-change="handleUserSelectionChange" row-key="userId" > <el-table-column type="selection" width="55" /> <el-table-column prop="userId" label="用户ID" width="100" /> <el-table-column prop="userName" label="姓名" width="120" /> <el-table-column prop="email" label="邮箱地址" min-width="200"> <template #default="scope"> <el-tooltip :content="scope.row.email || '未设置邮箱'" placement="top"> <span class="email-text">{{ scope.row.email || '未设置邮箱' }}</span> </el-tooltip> </template> </el-table-column> <el-table-column prop="deptName" label="部门" width="150" /> <el-table-column prop="status" label="状态" width="100" align="center"> <template #default="scope"> <el-tag :type="scope.row.status === '0' ? 'success' : 'danger'"> {{ scope.row.status === '0' ? '启用' : '禁用' }} </el-tag> </template> </el-table-column> </el-table> <!-- 分页 --> <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :total="totalUsers" :page-sizes="[10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" @size-change="handlePageSizeChange" @current-change="handlePageChange" class="user-pagination" /> </div> <template #footer> <el-button @click="resetUserSelection">清选择</el-button> <el-button type="primary" @click="confirmUserSelection">确认选择</el-button> </template> </el-dialog> </div> </template> <script setup> import { ref, reactive, computed, onMounted, watch } from 'vue' import { User, Clock, Document, Plus, Edit, Delete, Check, View, Search, Star } from '@element-plus/icons-vue' import { ElMessage, ElMessageBox, ElTooltip } from 'element-plus' import emailApi from '@/api/project/email' import useUserStore from '@/store/modules/user' // 基础状态管理 const activeTab = ref('receivers') const userStore = useUserStore() const currentUserId = userStore.id || 'admin' // 加载状态管理 const receiverLoading = ref(false) const modalUserLoading = ref(false) const saveReceiversLoading = ref(false) const saveConfigLoading = ref(false) const saveTemplateLoading = ref(false) const templateLoading = ref(false) const saveReminderLoading = ref(false) // 收件人管理核心逻辑 const selectedUserIds = ref([]) const userSearchText = ref('') const receivers = ref([]) // 过滤已删除的收件人(修复:使用数字0判断) const filteredReceivers = computed(() => { return receivers.value.filter(item => item.status !== 0) }) // 用户选择弹窗核心逻辑 const userSelectModalVisible = ref(false) const modalSearchQuery = ref('') const currentPage = ref(1) const pageSize = ref(10) const totalUsers = ref(0) const modalUsers = ref([]) const selectedModalUsers = ref([]) const filteredModalUsers = computed(() => { if (!modalSearchQuery.value) return modalUsers.value const query = modalSearchQuery.value.toLowerCase() return modalUsers.value.filter(user => user.userName.toLowerCase().includes(query) || (user.email && user.email.toLowerCase().includes(query)) || (user.deptName && user.deptName.toLowerCase().includes(query)) ) }) // 发送配置核心逻辑 const sendConfig = reactive({ enable: '1', senderName: '', host: '', port: 587, frequency: 'daily', sendTime: '09:00', advanceTime: 10, createBy: currentUserId, updateBy: currentUserId }) const configRules = reactive({ senderName: [{ required: true, message: '请输入发件人显示名称', trigger: 'blur' }], host: [{ required: true, message: '请输入SMTP服务器地址', trigger: 'blur' }], port: [ { required: true, message: '请输入SMTP服务器端口', trigger: 'blur' }, { type: 'number', message: '端口必须为数字', trigger: 'blur' } ], sendTime: [{ required: true, message: '请选择发送时间', trigger: 'change' }], advanceTime: [ { required: true, message: '请输入提前天数', trigger: 'blur' }, { type: 'number', message: '提前天数必须为数字', trigger: 'blur' } ] }) const configFormRef = ref(null) const activeCollapse = ref(['smtp', 'frequency']) // 邮件模板核心逻辑 const activeTemplateType = ref('license') const emailTemplates = reactive({ license: { templateId: '', templateName: '项目授权到期提醒', type: 'license', status: '1', isDefault: '1', subject: '【重要提醒】${projectName} 授权即将到期', content: '尊敬的${userName}:\n\n您负责的项目 "${projectName}" 授权将于 ${expireDate} 到期,请及时处理。\n\n授权信息:\n- 授权类型:${licenseType}\n- 授权范围:${licenseScope}\n- 授权编号:${licenseCode}\n\n到期后,系统将无法正常使用,请提前做好续费升级准备。\n\n如有疑问,请联系管理员。', createBy: currentUserId, updateBy: currentUserId }, maintenance: { templateId: '', templateName: '项目运维到期提醒', type: 'maintenance', status: '1', isDefault: '1', subject: '【重要提醒】${projectName} 运维服务即将到期', content: '尊敬的${userName}:\n\n您负责的项目 "${projectName}" 运维服务将于 ${expireDate} 到期,请及时处理。\n\n运维服务信息:\n- 服务内容:${maintenanceContent}\n- 服务提供商:${serviceProvider}\n- 服务级别:${serviceLevel}\n\n到期后,将不再提供技术支持和维护服务,请提前做好准备。\n\n如有疑问,请联系管理员。', createBy: currentUserId, updateBy: currentUserId } }) const currentTemplate = computed({ get() { return emailTemplates[activeTemplateType.value] }, set(value) { emailTemplates[activeTemplateType.value] = { ...value, updateBy: currentUserId } } }) const templateRules = reactive({ templateName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }], subject: [{ required: true, message: '请输入邮件标题', trigger: 'blur' }], content: [{ required: true, message: '请输入邮件内容', trigger: 'blur' }] }) const templateFormRef = ref(null) // 提醒规则核心逻辑 const reminderRule = reactive({ enable: '1', triggerType: 'remainingDays', advanceDays: 7, repeatInterval: 'daily', projectTypes: ['license', 'maintenance'], createBy: currentUserId, updateBy: currentUserId }) const reminderRules = reactive({ enable: [{ required: true, message: '请选择是否启用规则', trigger: 'change' }], triggerType: [{ required: true, message: '请选择提醒触发类型', trigger: 'change' }], repeatInterval: [{ required: true, message: '请选择重复提醒间隔', trigger: 'change' }], projectTypes: [{ required: true, message: '请选择适用项目类型', trigger: 'change' }] }) const reminderFormRef = ref(null) // 工具函数 const debounce = (fn, delay) => { let timer = null return function(...args) { if (timer) clearTimeout(timer) timer = setTimeout(() => fn.apply(this, args), delay) } } const getUserNameById = (userId) => { let user = modalUsers.value.find(u => u.userId === userId) if (!user) user = receivers.value.find(r => r.userId === userId) return user ? user.userName : '未知用户' } const getAvailableVariables = () => { const baseVars = { projectName: '项目名称', expireDate: '到期时间', userName: '接收人姓名', projectManager: '项目经理', projectStartDate: '项目开始日期' } if (activeTemplateType.value === 'license') { return { ...baseVars, licenseType: '授权类型', licenseScope: '授权范围', licenseCode: '授权编号', licenseIssuer: '授权颁发方' } } return { ...baseVars, maintenanceContent: '运维内容', serviceProvider: '服务提供商', serviceLevel: '服务级别', maintenanceContact: '运维联系人' } } // 事件处理函数 const openUserSelectModal = async () => { modalSearchQuery.value = '' currentPage.value = 1 selectedModalUsers.value = [] userSelectModalVisible.value = true await fetchModalUsers() const existingIds = receivers.value.map(r => r.userId) modalUsers.value.forEach(user => { if (existingIds.includes(user.userId)) { selectedModalUsers.value.push(user) } }) } const fetchModalUsers = async () => { modalUserLoading.value = true try { const res = await emailApi.getUserList({ keyword: modalSearchQuery.value, pageNum: currentPage.value, pageSize: pageSize.value }) modalUsers.value = res.rows || [] totalUsers.value = res.total || 0 } catch (error) { ElMessage.error('获取用户列表失败:' + (error.msg || error.message)) console.error('用户列表请求错误:', error) } finally { modalUserLoading.value = false } } const removeSelectedUser = (userId) => { selectedUserIds.value = selectedUserIds.value.filter(id => id !== userId) } // 修复:添加选中用户到收件人列表 const handleAddSelectedUsers = async () => { if (selectedUserIds.length === 0) { ElMessage.warning('请先在弹窗中选择用户') return } const newReceivers = selectedModalUsers.value .filter(user => !receivers.value.some(r => r.userId === user.userId)) .map(user => ({ recipientId: '', recipientName: user.userName, email: user.email || '', userId: user.userId, isDefault: 0, // 修复:使用数字0 status: 1, // 修复:使用数字1表示启用 sort: receivers.value.length + 1, createBy: currentUserId, updateBy: currentUserId })) if (newReceivers.length === 0) { ElMessage.info('所选用户已在收件人列表中,无需重复添加') selectedUserIds.value = [] return } saveReceiversLoading.value = true try { const res = await emailApi.saveReceivers(newReceivers) if (res.code === 200) { // 修复:从Page对象的records属性获取数据 receivers.value = [...receivers.value, ...(res.records || newReceivers)] ElMessage.success(`成功添加 ${newReceivers.length} 位用户到收件人列表`) } else { throw new Error(res.msg || '添加失败') } } catch (error) { ElMessage.error('添加用户失败:' + error.message) console.error('添加收件人错误:', error) } finally { saveReceiversLoading.value = false selectedUserIds.value = [] } } // 修复:切换收件人状态 const handleStatusChange = async (row) => { row.statusLoading = true try { // 修复:使用数字类型状态值 const newStatus = row.status === 1 ? 0 : 1 const res = await emailApi.updateReceiver({ ...row, status: newStatus, updateBy: currentUserId }) if (res.code !== 200) throw new Error(res.msg || '状态更新失败') row.status = newStatus ElMessage.success('状态更新成功') } catch (error) { row.status = row.status === 1 ? 0 : 1 ElMessage.error('状态更新失败:' + error.message) console.error('更新收件人状态错误:', error) } finally { row.statusLoading = false } } // 修复:切换收件人默认状态 const handleDefaultChange = async (row) => { // 修复:使用数字类型 const newIsDefault = row.isDefault === 1 ? 0 : 1 if (newIsDefault === 1) { receivers.value.forEach(item => { if (item.recipientId !== row.recipientId) { item.isDefault = 0 } }) } row.defaultDisabled = true try { const res = await emailApi.updateReceiver({ ...row, isDefault: newIsDefault, updateBy: currentUserId }) if (res.code !== 200) throw new Error(res.msg || '默认状态更新失败') row.isDefault = newIsDefault ElMessage.success('默认状态更新成功') } catch (error) { row.isDefault = row.isDefault === 1 ? 0 : 1 ElMessage.error('默认状态更新失败:' + error.message) console.error('更新默认状态错误:', error) } finally { row.defaultDisabled = false } } const handleSortChange = async (row) => { row.sortDisabled = true try { const res = await emailApi.updateReceiver({ ...row, updateBy: currentUserId }) if (res.code !== 200) throw new Error(res.msg || '排序更新失败') ElMessage.success('排序更新成功') } catch (error) { ElMessage.error('排序更新失败:' + error.message) console.error('更新排序错误:', error) } finally { row.sortDisabled = false } } const handleEditReceiver = async (row) => { try { const { value: newEmail } = await ElMessageBox.prompt( `编辑 ${row.recipientName} 的邮箱`, '编辑收件人邮箱', { inputValue: row.email || '', inputPlaceholder: '请输入有效的邮箱地址', inputPattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, inputErrorMessage: '请输入有效的邮箱地址' } ) const res = await emailApi.updateReceiver({ ...row, email: newEmail, updateBy: currentUserId }) if (res.code === 200) { row.email = newEmail ElMessage.success('邮箱编辑成功') } else { throw new Error(res.msg || '编辑失败') } } catch (error) { if (error !== 'cancel') { ElMessage.error('编辑失败:' + (error.message || '操作取消')) } } } const handleDeleteReceiver = async (recipientId) => { try { await ElMessageBox.confirm( '确定要删除该收件人吗?删除后将无法恢复', '删除确认', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' } ) const res = await emailApi.deleteReceiver(recipientId) if (res.code === 200) { receivers.value = receivers.value.filter(r => r.recipientId !== recipientId) ElMessage.success('收件人删除成功') } else { throw new Error(res.msg || '删除失败') } } catch (error) { if (error !== 'cancel') { ElMessage.error('删除失败:' + (error.message || '操作取消')) } } } const handleSaveReceivers = async () => { if (receivers.value.length === 0) { ElMessage.warning('暂无收件人可保存') return } saveReceiversLoading.value = true try { const receiversWithUpdateBy = receivers.value.map(r => ({ ...r, updateBy: currentUserId })) const res = await emailApi.saveReceivers(receiversWithUpdateBy) if (res.code === 200) { ElMessage.success('收件人设置保存成功') } else { throw new Error(res.msg || '保存失败') } } catch (error) { ElMessage.error('保存失败:' + error.message) console.error('保存收件人错误:', error) } finally { saveReceiversLoading.value = false } } // 发送配置事件 const handleSaveConfig = async () => { const form = configFormRef.value if (!form) return try { await form.validate() sendConfig.updateBy = currentUserId saveConfigLoading.value = true const res = await emailApi.saveSendConfig(sendConfig) if (res.code === 200) { ElMessage.success('发送配置保存成功') } else { throw new Error(res.msg || '保存失败') } } catch (error) { if (error.name !== 'ValidateError') { ElMessage.error('保存失败:' + (error.message || '表单验证失败')) } console.error('保存发送配置错误:', error) } finally { saveConfigLoading.value = false } } const handleFrequencyChange = () => { ElMessage.info(`已选择发送频率:${ sendConfig.frequency === 'daily' ? '每天' : sendConfig.frequency === 'weekly' ? '每周' : '每月' }`) } // 邮件模板事件 const handleTemplateTypeChange = async () => { const currentForm = templateFormRef.value if (currentForm) { try { await currentForm.validate() const hasChange = JSON.stringify(currentTemplate.value) !== JSON.stringify(emailTemplates[activeTemplateType.value]) if (hasChange) { await ElMessageBox.confirm( '当前模板有未保存的修改,切换类型将丢失,是否继续?', '切换模板确认', { type: 'warning' } ) } } catch (error) { if (error === 'cancel') { activeTemplateType.value = activeTemplateType.value === 'license' ? 'maintenance' : 'license' } } } templateLoading.value = true try { await fetchEmailTemplates() } catch (error) { ElMessage.error('切换模板失败:' + error.message) } finally { templateLoading.value = false } } const insertVariable = (key) => { currentTemplate.value.content += `\${${key}}` } const handlePreviewTemplate = () => { const basePreviewData = { projectName: '企业资源管理系统V3.0', expireDate: '2024-12-31', userName: '张经理', projectManager: '李工程师', projectStartDate: '2023-01-15' } let previewData, previewTitle if (activeTemplateType.value === 'license') { previewTitle = '项目授权到期提醒预览' previewData = { ...basePreviewData, licenseType: '企业版年度授权', licenseScope: '全模块使用权限', licenseCode: 'LIC-20230115-8762', licenseIssuer: '北京科技有限公司' } } else { previewTitle = '项目运维到期提醒预览' previewData = { ...basePreviewData, maintenanceContent: '系统日常维护、漏洞修复、性能优化、数据备份', serviceProvider: '技术支持部', serviceLevel: '7×24小时响应', maintenanceContact: '王技术员 (13800138000)' } } let previewSubject = currentTemplate.value.subject let previewContent = currentTemplate.value.content Object.keys(previewData).forEach(key => { const reg = new RegExp(`\\\${${key}}`, 'g') previewSubject = previewSubject.replace(reg, previewData[key]) previewContent = previewContent.replace(reg, previewData[key]) }) previewContent = previewContent.replace(/\n/g, '<br>') ElMessageBox.alert( `<h3 style="margin-bottom: 15px; color: #333;">${previewSubject}</h3> <div style="text-align: left; line-height: 1.8; color: #666;">${previewContent}</div>`, previewTitle, { dangerouslyUseHTMLString: true, width: '60%', confirmButtonText: '关闭预览' } ) } const handleSaveTemplate = async () => { const form = templateFormRef.value if (!form) return try { await form.validate() const templateData = { ...currentTemplate.value, type: activeTemplateType.value, updateBy: currentUserId } saveTemplateLoading.value = true const res = await emailApi.saveEmailTemplate(templateData) if (res.code === 200) { if (res.data?.templateId) { emailTemplates[activeTemplateType.value].templateId = res.data.templateId } ElMessage.success('邮件模板保存成功') } else { throw new Error(res.msg || '保存失败') } } catch (error) { if (error.name !== 'ValidateError') { ElMessage.error('保存失败:' + (error.message || '表单验证失败')) } console.error('保存模板错误:', error) } finally { saveTemplateLoading.value = false } } // 提醒规则事件 const handleRuleEnableChange = () => { if (reminderRule.enable === '0') { ElMessage.info('提醒规则已禁用,将不再触发到期提醒') } } const handleSaveReminderRule = async () => { const form = reminderFormRef.value if (!form) return try { await form.validate() reminderRule.updateBy = currentUserId saveReminderLoading.value = true const res = await emailApi.saveReminderRule(reminderRule) if (res.code === 200) { ElMessage.success('提醒规则保存成功') } else { throw new Error(res.msg || '保存失败') } } catch (error) { if (error.name !== 'ValidateError') { ElMessage.error('保存失败:' + (error.message || '表单验证失败')) } console.error('保存提醒规则错误:', error) } finally { saveReminderLoading.value = false } } // 弹窗分页与搜索事件 const handleModalSearch = debounce(async () => { currentPage.value = 1 await fetchModalUsers() }, 300) const handlePageSizeChange = async (size) => { pageSize.value = size currentPage.value = 1 await fetchModalUsers() } const handlePageChange = async (page) => { currentPage.value = page await fetchModalUsers() } const handleUserSelectionChange = (selection) => { selectedModalUsers.value = selection selectedUserIds.value = selection.map(user => user.userId) } const confirmUserSelection = () => { userSelectModalVisible.value = false } const resetUserSelection = () => { selectedModalUsers.value = [] selectedUserIds.value = [] } const handleModalClose = () => { selectedModalUsers.value = [] selectedUserIds.value = [] userSelectModalVisible.value = false } // 生命周期与数据加载 onMounted(() => { Promise.all([ fetchReceivers(), fetchSendConfig(), fetchEmailTemplates(), fetchReminderRule() ]).catch(error => { console.error('初始数据加载失败:', error) }) }) watch(selectedUserIds, (newVal) => { userSearchText.value = newVal.length > 0 ? `已选择 ${newVal.length} 位用户` : '' }) // 修复:从后端获取收件人列表(关键修复) const fetchReceivers = async () => { receiverLoading.value = true try { const res = await emailApi.listReceivers() // 关键修复:从Page对象的records属性获取数据列表 receivers.value = res.records || [] console.log('获取到的收件人数据:', receivers.value) } catch (error) { ElMessage.error('获取收件人列表失败:' + (error.msg || error.message)) console.error('获取收件人错误:', error) } finally { receiverLoading.value = false } } const fetchSendConfig = async () => { try { const res = await emailApi.getSendConfig() if (res.code === 200 && res.data) { Object.assign(sendConfig, res.data) } } catch (error) { ElMessage.error('获取发送配置失败:' + (error.msg || error.message)) console.error('获取发送配置错误:', error) } } const fetchEmailTemplates = async () => { templateLoading.value = true try { const res = await emailApi.getEmailTemplate() const templates = res.rows || [] if (Array.isArray(templates)) { templates.forEach(template => { if (template.type === 'license' || template.type === 'maintenance') { emailTemplates[template.type] = { ...emailTemplates[template.type], ...template, updateBy: currentUserId } } }) } } catch (error) { ElMessage.error('获取邮件模板失败:' + (error.msg || error.message)) console.error('获取模板错误:', error) } finally { templateLoading.value = false } } const fetchReminderRule = async () => { try { const res = await emailApi.getReminderRule() if (res.code === 200 && res.data) { Object.assign(reminderRule, res.data) } } catch (error) { ElMessage.error('获取提醒规则失败:' + (error.msg || error.message)) console.error('获取提醒规则错误:', error) } } </script> <style scoped> .setting-tabs { width: 100%; margin-bottom: 20px; } .setting-card { margin-bottom: 24px; border-radius: 8px; } .card-header { display: flex; align-items: center; gap: 10px; padding: 12px 0; } .header-icon { color: #409eff; font-size: 18px; } .header-desc { margin-left: 8px; font-size: 12px; color: #666; } .card-content { padding: 20px; } .add-receiver-form { margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #f0f0f0; } .user-select-input { width: 420px; cursor: pointer; } .search-icon { cursor: pointer; color: #999; } .selected-users-preview { margin: 16px 0; display: flex; gap: 8px; flex-wrap: wrap; } .selected-tag { background-color: #f5f7fa; color: #666; } .receiver-list-container { margin-top: 16px; } .receiver-table { width: 100%; border-radius: 4px; } .empty-state { padding: 60px 0; text-align: center; } .form-actions { margin-top: 24px; text-align: right; } .config-collapse { margin-top: 16px; } .config-form { margin-top: 8px; } .template-type-group { margin-bottom: 24px; padding: 12px; background-color: #f5f7fa; border-radius: 4px; } .template-variables { margin-top: 12px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .variable-tag { cursor: pointer; white-space: nowrap; background-color: #ecf5ff; color: #409eff; } .variable-desc { font-size: 11px; color: #888; margin-left: 5px; } .help-text { margin-left: 8px; font-size: 12px; color: #666; } .preview-btn { margin-right: 12px; } .reminder-form { margin-top: 16px; } .user-modal-content { display: flex; flex-direction: column; gap: 16px; } .modal-search-input { width: 100%; } .user-select-table { width: 100%; } .user-pagination { margin-top: 16px; text-align: right; } .email-text { display: inline-block; width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } @media (max-width: 1200px) { .user-select-input { width: 320px; } } @media (max-width: 768px) { .user-select-input { width: 100%; } .card-content { padding: 12px; } .template-type-group { flex-direction: column; gap: 8px; } .el-row { flex-direction: column; gap: 16px !important; } .el-col { width: 100% !important; } } </style> 使用若依框架编写后端代码
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值