<c:out value="" />出错

本文介绍如何在JSP页面中引入Java Server Pages (JSP)的核心标签库,使用%@taglib指令来指定标签库的URI和前缀。

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

引入

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<?xml version="1.0" encoding="UTF-8"?> <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3"> <hashTree> <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="测试计划" enabled="true"> <stringProp name="TestPlan.comments"></stringProp> <boolProp name="TestPlan.functional_mode">false</boolProp> <boolProp name="TestPlan.serialize_threadgroups">false</boolProp> <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="TestPlan.user_define_classpath"></stringProp> </TestPlan> <hashTree> <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="线程组" enabled="true"> <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true"> <boolProp name="LoopController.continue_forever">false</boolProp> <intProp name="LoopController.loops">-1</intProp> </elementProp> <stringProp name="ThreadGroup.num_threads">1</stringProp> <stringProp name="ThreadGroup.ramp_time">1</stringProp> <longProp name="ThreadGroup.start_time">1591941099000</longProp> <longProp name="ThreadGroup.end_time">1591941099000</longProp> <boolProp name="ThreadGroup.scheduler">true</boolProp> <stringProp name="ThreadGroup.duration">28800</stringProp> <stringProp name="ThreadGroup.delay"></stringProp> <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> </ThreadGroup> <hashTree> <OnceOnlyController guiclass="OnceOnlyControllerGui" testclass="OnceOnlyController" testname="仅一次控制器" enabled="true"/> <hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口104 /" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/</stringProp> <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> <stringProp name="HTTPSampler.connect_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp> <stringProp name="TestPlan.comments">Detected the start of a redirect chain</stringProp> </HTTPSamplerProxy> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="Upgrade-Insecure-Requests" elementType="Header"> <stringProp name="Header.name">Upgrade-Insecure-Requests</stringProp> <stringProp name="Header.value">1</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口117 /iplat/cms/common/getUserName" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/iplat/cms/common/getUserName</stringProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> <stringProp name="HTTPSampler.connect_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp> </HTTPSamplerProxy> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口121 /iplat/bp/common/getAllApplication" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/iplat/bp/common/getAllApplication</stringProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> <stringProp name="HTTPSampler.connect_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp> </HTTPSamplerProxy> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口127 /iplat/html/www/front/contentList" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"> <elementProp name="categoryId" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> <stringProp name="Argument.name">categoryId</stringProp> <stringProp name="Argument.value">2</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> </elementProp> </collectionProp> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp> <stringProp name="HTTPSampler.path">/iplat/html/www/front/contentList</stringProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> <stringProp name="HTTPSampler.connect_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp> </HTTPSamplerProxy> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Content-Type" elementType="Header"> <stringProp name="Header.name">Content-Type</stringProp> <stringProp name="Header.value">application/x-www-form-urlencoded; charset=UTF-8</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口143 /iplat/valid/user" enabled="false"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"> <elementProp name="username" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> <stringProp name="Argument.name">username</stringProp> <stringProp name="Argument.value">${username}</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> </elementProp> </collectionProp> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp> <stringProp name="HTTPSampler.path">/iplat/valid/user</stringProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> <stringProp name="HTTPSampler.connect_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp> </HTTPSamplerProxy> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Content-Type" elementType="Header"> <stringProp name="Header.name">Content-Type</stringProp> <stringProp name="Header.value">application/x-www-form-urlencoded; charset=UTF-8</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> 把这段jmeter脚本改写成python
07-16
<template> <div class="vote-container"> <!-- 消息提示区域 (添加在顶部) --> <div v-if="showAlert" :class="['alert', alertType]"> {{ alertMessage }} </div> <!-- 投票人信息 --> <div class="voter-info" v-if="voterName && voterIdCard"> <p>投票人:{{ voterName }}</p> <p>身份证:{{ formattedIdCard }}</p> </div> <!-- 投票统计信息 --> <div class="stats"> <div class="stat"> <h3>经理投票</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (votes.A / 5) * 100 + '%' }"></div> </div> <p>{{ votes.A }} / 5</p> </div> <div class="stat"> <h3>厂长投票</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (votes.B / 5) * 100 + '%' }"></div> </div> <p>{{ votes.B }} / 5</p> </div> <div class="stat"> <h3>副厂长投票</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (votes.C / 15) * 100 + '%' }"></div> </div> <p>{{ votes.C }} / 15</p> </div> <div class="stat"> <h3>总票数</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (totalVotes / 25) * 100 + '%' }"></div> </div> <p>{{ totalVotes }} / 25</p> </div> </div> <!-- 被投票人列表 --> <div class="voters-grid"> <div v-for="voter in voters" :key="voter.id" class="voter-card"> <h4>{{ voter.name }}</h4> <p class="voter-id">ID: {{ voter.id }}</p> <div class="vote-options"> <button @click="castVote(voter, 'A')" :disabled="!canVote(voter, 'A')" :class="{ 'selected': voter.vote === 'A', 'disabled': !canVote(voter, 'A') }" > 经理 </button> <button @click="castVote(voter, 'B')" :disabled="!canVote(voter, 'B')" :class="{ 'selected': voter.vote === 'B', 'disabled': !canVote(voter, 'B') }" > 厂长 </button> <button @click="castVote(voter, 'C')" :disabled="!canVote(voter, 'C')" :class="{ 'selected': voter.vote === 'C', 'disabled': !canVote(voter, 'C') }" > 副厂长 </button> </div> </div> </div> <!-- 操作按钮 --> <div class="action-buttons"> <button @click="submitVotes" :disabled="!hasSelectedCandidates || isSubmitting">提交投票</button> <button @click="resetVotes" :disabled="isSubmitting">重置投票</button> </div> </div> </template> <script setup> import { ref, reactive, computed } from 'vue'; import { useRoute } from 'vue-router'; import { onMounted } from 'vue' const voters = ref([]); //候选人 const activeSurvey = ref({ id: null, //投票ID bt: '', // 标题 qydcl: '', dclx: '', //投票类型 tffs: '' }); // 添加消息提示状态 const alertMessage = ref(''); const showAlert = ref(false); const alertType = ref(''); // 'success' 或 'error' // 安全序列化函数 function safeStringify(obj) { const seen = new WeakSet(); return JSON.stringify(obj, (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { // 检测到循环引用,返回占位符或跳过 return "[Circular Reference Removed]"; } seen.add(value); } return value; }); } // onMounted生命周期钩子 onMounted(async () => { // 从sessionStorage获取投票人信息并立即清除 const voterInfo = sessionStorage.getItem('voterInfo'); if (voterInfo) { const { name, idCard } = JSON.parse(voterInfo); voterName.value = name; voterIdCard.value = idCard; sessionStorage.removeItem('voterInfo'); } // 加载候选人数据 voters.value = await fetchCandidates(); }); // 获取路由信息 const route = useRoute(); // 添加用于存储投票人信息的变量 const voterName = ref(''); const voterIdCard = ref(''); // 格式化身份证显示(安全脱敏) const formattedIdCard = computed(() => { if (!voterIdCard.value) return ''; // 显示前6位和后4位,中间用*代替 return voterIdCard.value.substring(0, 6) + '******' + voterIdCard.value.substring(voterIdCard.value.length - 4); }); onMounted(() => { // 从sessionStorage获取数据并立即清除 const voterInfo = sessionStorage.getItem('voterInfo'); if (voterInfo) { const { name, idCard } = JSON.parse(voterInfo); voterName.value = name; voterIdCard.value = idCard; // 关键:立即清除存储防止数据残留 sessionStorage.removeItem('voterInfo'); } }); //获取候选人明细 const fetchCandidates = async () => { try { const response = await fetch('/api/wechat/getInvestigate', { method: 'POST', body: JSON.stringify({ id: '9', dcl: '123' }) }); console.log('API响应:', response); const result = await response.json(); if (!result || !result.root) throw new Error('无效API响应'); // 提取候选人数据 const candidateArray = []; let idCounter = 1; // 自增计数器,名称序号 result.root.forEach(rootItem => { if (!rootItem.childEntList) return; rootItem.childEntList.forEach(candidate => { if (!candidate.dcbt || !candidate.dcxbt) return; candidateArray.push({ originalid: candidate.dcbt, name: candidate.dcxbt, vote: null, id:idCounter++, tmlx: candidate.tmlx, // 投票类型 }); }); }); return candidateArray; } catch (error) { console.error('获取候选人失败:', error); return []; // 返回空数组保持安全 } }; // 新增计算属性 - 获取已选择的候选人 const selectedCandidates = computed(() => { return voters.value .filter(v => v.vote) // 只过滤已投票的 .map(v => ({ id: v.originalid, // 候选人原始ID voteType: v.vote, // 投票类型(A/B/C) voteValue: v.vote === 'A' ? 17 : // 转换类型值 v.vote === 'B' ? 18 : 19, name: v.name, // 候选人姓名 tmlx: v.tmlx // 原始类型 })); }); // 检查是否有选择的候选人 const hasSelectedCandidates = computed(() => { return selectedCandidates.value.length > 0; }); // 投票统计 const votes = reactive({ A: 0, B: 0, C: 0 }); // 计算总票数 const totalVotes = computed(() => { return votes.A + votes.B + votes.C; }); // 投票方法 const canVote = (voter, type) => { // 情况1:用户取消当前选择的类型(总是允许) if (voter.vote === type) return true; // 情况2:用户从其他类型转换到当前类型 if (voter.vote && voter.vote !== type) { if (type === 'A' && votes.A >= 5) return false; if (type === 'B' && votes.B >= 5) return false; if (type === 'C' && votes.C >= 15) return false; } // 情况3:用户首次投票 if (!voter.vote) { if (type === 'A' && votes.A >= 5) return false; if (type === 'B' && votes.B >= 5) return false; if (type === 'C' && votes.C >= 15) return false; if (totalVotes.value >= 25) return false; } return true; }; // 投票方法 const castVote = (voter, type) => { // 如果已投票且点击相同类型,取消投票 if (voter.vote === type) { voter.vote = null; votes[type]--; return; } // 如果之前有投票,先取消 if (voter.vote !== null) { votes[voter.vote]--; } // 投新票 voter.vote = type; votes[type]++; }; //投票人信息 // 添加投票人信息数据模型 const voterInfo = reactive({ name: '', idNumber: '' }); // // 添加基本信息验证 // const isValid = computed(() => { // return voterInfo.name.trim() !== '' && // voterInfo.idNumber.trim() !== '' && // /^\d{17}[\dXx]$/.test(voterInfo.idNumber); // }); // 提交投票 // 防止重复提交 const isSubmitting = ref(false); // 提交投票到API const submitVotes = async () => { // 添加防御性检查 if (!hasSelectedCandidates.value) { showMessage('请先选择候选人', 'error'); return; } // 防止重复提交 if (isSubmitting.value) return; isSubmitting.value = true; try { // 按接口规范构建JSON数据结构 // const requestData = { // mainData: [ // { fieldName: "bt", fieldValue: activeSurvey.value.bt }, // { fieldName: "tprxm", fieldValue: voterName }, // { fieldName: "tprsfz", fieldValue: voterIdCard }, // { fieldName: "mb", fieldValue: activeSurvey.value.id }, // { fieldName: "dclx", fieldValue: activeSurvey.value.dclx }, // { fieldName: "tffs", fieldValue: activeSurvey.value.tffs }, // ], // workflowRequestTableRecords: selectedCandidates.value.map(candidate => ({ // workflowRequestTableFields: [ // { // fieldName: "dcbt", // fieldValue: candidate.originalid // }, // { // fieldName: "tmlx", // fieldValue: candidate.tmlx // }, // { // fieldName: "dcxx", // fieldValue: candidate.voteValue // 使用转换后的值 // } // ] // })) // }; const mainData = [ { fieldName: "bt", fieldValue: activeSurvey.value.bt }, { fieldName: "tprxm", fieldValue: voterName.value }, { fieldName: "tprsfz", fieldValue: voterIdCard.value }, { fieldName: "mb", fieldValue: activeSurvey.value.id }, { fieldName: "dclx", fieldValue: activeSurvey.value.dclx }, { fieldName: "tffs", fieldValue: activeSurvey.value.tffs } ]; const workflowRequestTableRecords = selectedCandidates.value.map(candidate => ({ workflowRequestTableFields: [ { fieldName: "dcbt", fieldValue: candidate.originalid }, { fieldName: "tmlx", fieldValue: candidate.tmlx }, { fieldName: "dcxx", fieldValue: candidate.vote === 'A' ? 17 : candidate.vote === 'B' ? 18 : 19 } ] })); const requestBody = { requestName: activeSurvey.value.bt, // 投票标题 workflowId: 118, // 固定工作流ID mainData, workflowRequestTableRecords }; // 发送POST请求 const response = await fetch('/api/wechat/addInvestigateWorkflow1', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: safeStringify(requestBody)// 使用安全序列化,避免重复引用 }); const result = await response.json(); // 根据API响应显示相应提示 if (result.code === 200) { // 成功处理 if (result.msg) { showMessage(result.msg, 'success'); }else { showMessage('投票提交成功!', 'success'); } // 存储已投票标识 localStorage.setItem('voted_' + voterIdCard.value, 'true'); } else { // 特殊处理"已提交"消息 if (result.msg === '你已提交或不满足提交条件') { showMessage(result.msg, 'error'); } else { // 其他错误处理 showMessage(`提交失败: ${result.msg || '未知错误'}`, 'error'); } } } catch (error) { console.error('提交失败:', error); // 检查是否已投票错误(假设后端返回409状态码) if (error.response?.status === 409) { alert('您已投过票,无法重复提交'); } else { alert('投票提交失败,请重试'); } } finally { isSubmitting.value = false; } }; // 重置投票 const resetVotes = () => { if (confirm('确定要重置所有投票吗?')) { voters.value.forEach(voter => { voter.vote = null; }); votes.A = 0; votes.B = 0; votes.C = 0; voterInfo.name = ''; voterInfo.idNumber = ''; } }; //后台响应信息showMessage const showMessage = (message, type = 'error') => { // 更新消息提示状态 alertMessage.value = message; showAlert.value = true; alertType.value = type; // 错误提示停留3秒,成功提示停留2秒 const timeout = type === 'error' ? 3000 : 2000; setTimeout(() => { showAlert.value = false; }, timeout); }; </script> <style scoped> /* 移动端垂直布局 */ @media (max-width: 480px) { .input-group { flex-direction: column; } } /* 平板/桌面端水平布局 */ @media (min-width: 768px) { .input-group { flex-direction: row; } } /* 消息提示样式 */ .alert { padding: 15px; margin-bottom: 20px; border-radius: 4px; text-align: center; position: fixed; top: 20px; left: 50%; transform: translateX(-50%); z-index: 1000; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); min-width: 300px; opacity: 0.95; } .alert.error { background-color: #ffebee; color: #b71c1c; border: 1px solid #ffcdd2; } .alert.success { background-color: #e8f5e9; color: #1b5e20; border: 1px solid #c8e6c9; } .vote-container { max-width: 1200px; margin: 0 auto; padding: 20px; } .stats { display: flex; justify-content: space-between; margin-bottom: 30px; background: #f5f7fa; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } .stat { flex: 1; text-align: center; padding: 0 15px; } .progress { height: 20px; background: #e0e0e0; border-radius: 10px; margin: 10px 0; overflow: hidden; } .progress-bar { height: 100%; background: #3498db; transition: width 0.3s; } .voters-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px; } .voter-card { background: white; border-radius: 8px; padding: 15px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: transform 0.2s; } .voter-card:hover { transform: translateY(-5px); } .voter-id { color: #777; font-size: 0.9rem; margin-bottom: 15px; } .vote-options { display: flex; justify-content: space-between; } .vote-options button { flex: 1; margin: 0 5px; padding: 8px 0; border: none; border-radius: 4px; cursor: pointer; transition: all 0.2s; } .vote-options button:not(.selected):hover { opacity: 0.9; transform: scale(1.05); } .vote-options button:first-child { background: #ff6b6b; color: white; } .vote-options button:nth-child(2) { background: #4ecdc4; color: white; } .vote-options button:last-child { background: #ffd166; color: white; } .selected { border: 2px solid #2c3e50 !important; font-weight: bold; box-shadow: 0 0 2 rgba(61, 60, 60, 0.5); } .disabled { opacity: 0.5 !important; cursor: not-allowed !important; } .action-buttons { margin-top: 30px; display: flex; justify-content: center; gap: 20px; } .action-buttons button { padding: 12px 30px; border: none; border-radius: 6px; cursor: pointer; font-size: 1rem; font-weight: 600; transition: all 0.2s; } .action-buttons button:first-child { background: #3498db; color: white; } .action-buttons button:first-child:disabled { background: #bdc3c7; cursor: not-allowed; } .action-buttons button:last-child { background: #e74c3c; color: white; } .action-buttons button:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } </style>为什么提交成功了,提示提交失败:success
06-12
#include <stdint.h> #include <string.h> // 状态定义 (使用位域优化) typedef enum { STATE_IDLE = 0, // 0000 STATE_DETECTING = 1, // 0001 (合并阈值检测和峰值检测) STATE_DEBOUNCING = 2, // 0010 STATE_CONFIRMED = 4, // 0100 STATE_COOLDOWN = 8, // 1000 STATE_TIMEOUT = 16 // 10000 } TouchState; // 优化后的触摸检测数据结构 (总大小: 10字节) typedef struct { int16_t current; // 当前值 (2字节) int16_t previous; // 前次值 (2字节) int16_t peak; // 峰值 (2字节) uint16_t timer; // 多功能计时器 (2字节) uint8_t flags; // 状态标志位域 (1字节) uint8_t resample_cnt; // 重采样计数器 (1字节) uint8_t shake_cnt; // 抖动计数 (1字节) int8_t direction; // 方向 (-1,0,1) (1字节) } TouchData; // 标志位定义 (使用位域) #define FLAG_TOUCH_DETECTED (1 << 0) #define FLAG_IN_COOLDOWN (1 << 1) // 配置参数 (常量存储在Flash) const uint16_t FIXED_THRESH = 30; // 固定阈值 const uint16_t TOUCH_THRESH = 50; // 触摸阈值 const uint8_t RESAMPLE_INTV = 5; // 重采样间隔 // 状态处理函数声明 static void handle_idle(TouchData* data); static void handle_detecting(TouchData* data); static void handle_debouncing(TouchData* data); static void handle_confirmed(TouchData* data); static void handle_cooldown(TouchData* data); static void handle_timeout(TouchData* data); // 主状态机函数 void OptimizedTouchDetection(TouchData* data) { // 更新当前值 data->current = LPF_High.out - LPF_Low.out; // 根据当前状态调用处理函数 switch (data->flags & 0xF0) { // 高4位存储状态 case STATE_IDLE: handle_idle(data); break; case STATE_DETECTING: handle_detecting(data); break; case STATE_DEBOUNCING: handle_debouncing(data); break; case STATE_CONFIRMED: handle_confirmed(data); break; case STATE_COOLDOWN: handle_cooldown(data); break; case STATE_TIMEOUT: handle_timeout(data); break; } // 更新前值用于下一次比较 data->previous = data->current; } //=== 状态处理函数实现 ===// // 空闲状态处理 static void handle_idle(TouchData* data) { if (abs(data->current) > FIXED_THRESH) { // 进入检测状态 data->flags = (STATE_DETECTING << 4); // 状态存储在flags高4位 data->resample_cnt = 0; } } // 检测状态处理 (合并阈值检测和峰值检测) static void handle_detecting(TouchData* data) { // 周期性重采样 (每5次调用记录一次) if (++data->resample_cnt >= RESAMPLE_INTV) { data->resample_cnt = 0; data->peak = data->current; // 记录采样值 } // 检测触摸阈值 int16_t abs_current = abs(data->current); if (abs_current > TOUCH_THRESH) { data->direction = (data->current < 0) ? -1 : 1; data->timer = 0; } // 检测峰值 (变化量开始减小) if (abs_current < abs(data->previous) && abs_current > TOUCH_THRESH) { // 记录峰值并重置计时器 data->peak = data->previous; data->timer = 0; // 进入去抖状态 data->flags = (STATE_DEBOUNCING << 4); data->shake_cnt = 0; } // 超时处理 (200ms) if (++data->timer > 200) { data->flags = (STATE_TIMEOUT << 4); } } // 去抖状态处理 static void handle_debouncing(TouchData* data) { data->timer++; // 检测方向反转 int16_t dir_check = data->direction * data->current; int16_t abs_current = abs(data->current); int16_t peak_quarter = abs(data->peak) >> 2; // peak/4 if (dir_check < 0 && abs_current > peak_quarter) { // 抖动计数 if (data->timer < 20) { // 20ms去抖窗口 data->shake_cnt++; } } // 抖动过大或超时 (200ms) if (data->shake_cnt > 2 || data->timer > 200) { data->flags = (STATE_TIMEOUT << 4); } // 有效触摸确认 else if (data->timer > 20) { // 20ms后确认 data->flags = (STATE_CONFIRMED << 4); } } // 确认状态处理 static void handle_confirmed(TouchData* data) { // 设置触摸标志 data->flags |= FLAG_TOUCH_DETECTED; // 进入冷却状态 data->flags = (STATE_COOLDOWN << 4) | FLAG_IN_COOLDOWN; data->timer = 0; } // 冷却状态处理 static void handle_cooldown(TouchData* data) { data->timer++; // 退出冷却条件:变化量小于阈值或超时(50ms) if (abs(data->current) < TOUCH_THRESH || data->timer > 50) { data->flags = (STATE_IDLE << 4); } } // 超时状态处理 static void handle_timeout(TouchData* data) { // 重置所有状态 memset(data, 0, sizeof(TouchData)); data->flags = (STATE_IDLE << 4); } 将代码中的结构体改为: typedef struct { s8 is_touch_detected; s8 is_in_cooldown; s8 direction; s16 current_value; s16 previous_value ; s16 peak_value ; s16 resampled_value; s16 shake_count; s16 timer; }TouchCmp;
最新发布
08-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值