线性渐变-linear-gradient和滤镜opacity/filter的透明效果兼容性解决方案及其RGB/RGBA与16进制转换方法

本文介绍了RGBA颜色模式及线性渐变在不同浏览器中的兼容性解决方案,包括使用CSS3PIE插件和IE滤镜等方法,确保跨浏览器的一致表现。

第一篇:滤镜opacity/filter的透明效果兼容性解决方案RGB/RGBA介绍


项目中需要实现透明遮罩效果,使用opacity/filter会使得内部元素都透明,而实际中的文字内容我们不想让其透明化,这时候就需要考虑其他的实现方法。

我们知道,RGB色彩就是常说的三原色,RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,故而也称为加色模式。RGB模式又称RGB色空间。RGB色彩系统几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

与加色模式对应的是适合印刷的CMYK色彩模式,也称减色色彩模式。CMYK代表印刷上用的四种颜色,C代表青色(Cyan),M代表洋红色(Magenta),Y代表黄色(Yellow),K代表黑色(Black)。因为在实际引用中,青色、洋红色和黄色很难叠加形成真正的黑色,最多不过是褐色而已。因此才引入了K——黑色。黑色的作用是强化暗调,加深暗部色彩。CMYK模式是最佳的打印模式,因RGB模式尽管色彩多,但不能完全打印出来。用CMYK模式编辑虽然能够避免色彩的损失,但运算速度很慢。所以现实中的设备,如扫描仪和显示器,都是在RGB模式编辑,再转换为CMYK模式,其中加入了一些必要的色彩校正技术手段,最终打印/输出。

在前端开发中,我们不只用到RGB比较多,而且RGBA也会常常用到。实际上,RGBA是在RGB的基础上增加了控制alpha透明度的参数A。其中,R、G、B三个参数的整数取值范围为:0 ~ 255,百分数值的取值范围为:0.0% ~ 100.0%。超出范围的数值将被截至其最接近的取值极限。不过,并非所有浏览器都支持使用百分数值。A参数,取值在0~1之间,不可为负值。

直接了当的说,RGBa模式是一种包含透明效果的颜色设置方法,语法如下:

//CSS Document
div {
   background: rgba(0, 0, 0, 0.5);
}

它允许我们为元素添加透明色。或许我们习惯了使用”opacity“,它很简单易用,但是,opacity会使所有的子元素都变成透明的,而且很难去解决这个问题。(除非使用怪异的定位hack) 跨浏览器透明同样颇为棘手。

通过RGBa,我们可以将一个元素设置为透明,而不会影响其子元素:

RGBA的浏览器兼容性

类型Internet ExplorerFirefoxChromeOperaSafari
版本(×)IE6(√)Firefox 3.0.10(√)Chrome 2.0.x(√)Opera 9.64(√)Safari 4
(×)IE7    
(×)IE8    
(√)IE9



不兼容的解决方案:声明一个保留颜色

并非所有的浏览器支持RGBa,所以如果允许的话,可以声明一个保留色彩。这个色彩应该是可靠的——所有的浏览器都支持。不声明就意味着,在不支持RGBa的浏览器里面,没有使用颜色。    

div {
   background: rgb(200, 54, 54); /* The Fallback */
   background: rgba(200, 54, 54, 0.5);
}

不过,这条退路在某些古董级浏览器中依然无效。

RGBa的浏览器支持情况

浏览器,版本,操作系统 测试结果 退路
Firefox 3.0.5 (OS X, Windows XP, Vista) 支持
Firefox 2.0.0.18 (PC) 不支持 纯色
Safari 4 (Developer Preview, Mac) 支持
Safari 3.2.1 (PC) 支持
Mobile Safari (iPhone) 支持
Opera 9.6.1 不支持 纯色
IE 5.5 (PC via IETester) 不支持 无色
IE 6 (PC via IETester) 不支持 纯色
IE 7 不支持 纯色
IE 8 beta 2 不支持 纯色
Google Chrome 1.0.154.43 支持
Google Chrome 1.0.154.46 支持
Netscape 4.8 (PC) 不支持 没有颜色
SeaMonkey 1.1.14 不支持 无色
SeaMonkey 1.1.16 不支持 纯色
SeaMonkey 2.0 beta3 支持
Sunrise 1.7.5 支持
Stainless 0.2.5 支持
Flock 2.0.2 支持
BlackBerry Storm Browser 支持 纯色
Camino 1.6.6 不支持 纯色

上面的数据是通过测试demo得到的,该测试页面包含了更多更完整的浏览器兼容性列表。(译自: css-tricks)

最佳解决方案:对IE浏览器的更好的退路

方案一:CSS3PIE

插件CSS3PIE 可以使得IE 6-9 版本能够输出大多数非常有用CSS3修饰特性。当然,CSSPIE可以让color、background、 box-shadow支持RGBA

div.demo{
	color:rgba(0,0,0,.5);
	background:rgba(0,0,0,.5);
	-pie-background:rgba(0,0,0,.5);/*IE6-9*/
	box-shadow: 1px 1px rgba(0,0,0,.5);/*仅在未设置模糊值的情况下支持rgba*/
} 

方案二:filter滤镜

通过IE滤镜让背景色透明化,模拟rgba透明效果。

因为IE浏览器支持条件注释,我们可以抛弃RGB并使用IE的一个私有CSS滤镜来实现同样的效果:

<!--[if IE]>
   <style type="text/css">
   .color-block {
       background:transparent;
       filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#79C83636,endColorstr=#79C83636);
       zoom: 1;
    }
    </style>
<![endif]-->

注意:StartColorStr和EndColorStr的值,前两位是十六进制的透明度,后面六位是十六进制的颜色。

2位透明度的换算方法:x=alpha*255 ,将计算的结果x转换成十六进制即可。

经测试,RGBa颜色可以用于border,不过,不同的浏览器对于border的RGBa支持不太一样,不过唯一的不同是,FF在border的拐角处会出现叠加,比如透明度是0.4,那么在FF中,四个角的透明度会变成0.8,而支持RGBa的非FF浏览器不会出现这种情况。这一点本人暂未验证。


第二篇:线性渐变-linear-gradient的介绍,RGB/RGBA与16进制转换方法


下面结合网络上的各种说法,总结一下线性渐变语法及其RGBA颜色模式和16进制颜色转变的方法:

CSS3新增的颜色渐变属性极大的丰富了网络色彩的世界,也进一步增强了前端开发人员工作的便利性和页面的可维护性。

线性渐变在Mozilla下的语法:

-moz-linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* )

线性渐变在Webkit下的语法:

-webkit-linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* )//最新发布书写语法

-webkit-gradient(<type>, <point> [, <radius>]?, <point> [, <radius>]? [, <stop>]*) //老式语法书写

线性渐变在Trident (IE)下的语法:

filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=#111CCC, endColorstr=#1CC222);

-ms-filter: "progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#111CCC, endColorstr=#1CC222)";

对比:

火狐下的样式background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);

IE下: filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#B2FFFFFF', endColorstr='#00FFFFFF',GradientType=0 ); /* IE6-9 */

语法:

filter:progid:DXImageTransform.Microsoft.Gradient(enabled=bEnabled,startColorStr=iWidth,endColorStr=iWidth)

属性:

enabled:可选项。布尔值(Boolean)。设置或检索滤镜是否激活。 true | false

  true: 默认值。滤镜激活。

  false:滤镜被禁止。

startColorStr:可选项。字符串(String)。设置或检索色彩渐变的开始颜色和透明度。

  其格式为 #AARRGGBB 。 AA 、 RR 、 GG 、 BB 为十六进制正整数。取值范围为 00 - FF 。 RR 指定红色值, GG 指定绿色值, BB 指定蓝色值,参阅 #RRGGBB 颜色单位。 AA 指定透明度。 00 是完全透明。 FF 是完全不透明。超出取值范围的值将被恢复为默认值。

  取值范围为 #FF000000 - #FFFFFFFF 。默认值为 #FF0000FF 。不透明蓝色。

EndColorStr:可选项。字符串(String)。设置或检索色彩渐变的结束颜色和透明度。参阅 startColorStr 属性。默认值为 #FF000000 。不透明黑色。

特性:

Enabled:可读写。布尔值(Boolean)。参阅 enabled 属性。

GradientType:可读写。整数值(Integer)。设置或检索色彩渐变的方向。1 | 0

  1:默认值。水平渐变。

  0:垂直渐变。

StartColorStr:可读写。字符串(String)。参阅 startColorStr 属性。

StartColor:可读写。整数值(Integer)。设置或检索色彩渐变的开始颜色。 取值范围为 0 - 4294967295 。 0 为透明。 4294967295 为不透明白色。

EndColorStr:可读写。字符串(String)。设置或检索色彩渐变的结束颜色和透明度。参阅 startColorStr 属性。默认值为 #FF000000 。不透明黑色。

EndColor:可读写。整数值(Integer)。设置或检索色彩渐变的结束颜色。 取值范围为 0 - 4294967295 。 0 为透明。 4294967295 为不透明白色。当在脚本中使用此特性时,也可以用十六进制格式: 0xAARRGGBB 。

说明:在对象的背景和内容之间显示定制的色彩层。

当此效果通过转变显示时,在渐变册色彩层之上的文本程序性的初始化为透明的,当色彩渐变实现后,文本颜色会以其定义的值更新。

测试demo代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
<!--
body{
	font-weight:bold;
	font-size:20px;
}
#out{
   color:blue;
   width:400px;
   height:300px;
   background:url("http://data.travel.china.com/travelhtml/pic/200903/p12378735145832.jpg") scroll center center no-repeat transparent;
   position:relative;
}
div.demo {
   //background: rgb(200, 54, 54); /* The Fallback */
   background: rgba(200, 54, 54, 0.5);
   //opacity:.3;
   //filter:alpha(opacity=80);
   position:absolute;
   left:0;
   top:0;
   padding:50px;
   color:red;
   
}

-->
</style>
<!--[if IE]>
   <style type="text/css">
   /*startColorStr与endColorStr是经过rgba(200, 54, 54, 0.5)换算而来*/
   .color-block {
       background:transparent;
       filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#79C83636,endColorstr=#79C83636);
       zoom: 1;
    } 
    </style>
<![endif]-->
<title>线性渐变-linear-gradient和滤镜opacity/filter的透明效果兼容性解决方案及其RGB/RGBA与16进制转换方法</title>
</head>

<body>

<div  id="out" class="">
	<span>外层div:这是背景图片</span>
	<div class="demo color-block">
		<span>内层div:测试透明效果</span>
	<div>
</div>
</body>
</html>

在FF,Chrome,IE下测试通过,预览效果图:


附:滤镜的实用案例
 
哀悼日,各网站页面全部用黑白色,用以下滤镜!!

为方便站点哀悼,特提供css滤镜代码,以表哀悼。以下为全站CSS代码。

html { filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1); }

使用方法:这段代码可以变网页为黑白,将代码加到CSS最顶端就可以实现素装

如果网站没有使用CSS,可以在网页/模板的HTML代码和 之间插入:

<style type="text/css">
html{
	filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
}
</style>

有一些站长的网站可能使用这个css 不能生效,是因为网站没有使用最新的网页标准协议

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

请将网页最头部的替换为以上代码。

有一些网站FLASH动画的颜色不能被CSS滤镜控制,可以在FLASH代码的和之间插入:

最简单的把页面变成灰色的代码是在head 之间加

<style>
html {
    FILTER: gray
}
</style>

最后,附上一些常用的在线调色工具:

RGB颜色转换十六进制颜色http://www.quman.org/article/article0009.html

Gradient Generator  http://gradcolor.com/

CSS3 PIE (which makes Internet Explorer 6-9 capable of rendering several of the most useful CSS3 decoration features.)http://css3pie.com/



<template> <div class="equipment-monitoring"> <!-- 设备监测标题 --> <div class="monitoring-header"> <div class="header-icon"> <div class="header-title text_show">设备监测</div> <div class="header-dropdown"> <el-dropdown trigger="click"> <span class="dropdown-link"> 主机 <i class="el-icon-arrow-down el-icon--right"></i> </span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>主机1</el-dropdown-item> <el-dropdown-item>主机2</el-dropdown-item> <el-dropdown-item>主机3</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </div> </div> <!-- 设备统计指标 --> <div class="monitoring-stats"> <div class="monitoring-stats-left"></div> <div class="monitoring-stats-right"> <div class="stats-item"> <div class="stats-content"> <div class="stats-label">设备总数</div> <div class="stats-number">{{ deviceStats.total }}</div> </div> </div> <div class="stats-item"> <div class="stats-content"> <div class="stats-label">在线数</div> <div class="stats-number">{{ deviceStats.online }}</div> </div> </div> <div class="stats-item"> <div class="stats-content"> <div class="stats-label">离线数</div> <div class="stats-number">{{ deviceStats.offline }}</div> </div> </div> <div class="stats-item"> <div class="stats-content"> <div class="stats-label">今日报警数</div> <div class="stats-number">{{ deviceStats.alarm }}</div> </div> </div> <div class="stats-item"> <div class="stats-content"> <div class="stats-label">今日故障数</div> <div class="stats-number">{{ deviceStats.fault }}</div> </div> </div> </div> </div> <!-- 设备走势图 --> <div class="monitoring-chart"> <div class="chart-header"> <div class="chart-title"> <img style="width: 40px; height: 36px; margin-right: 2px" src="../assets/images/safeHospital/left_dev.png" mode="scaleToFill" /> <div class="text_show chart-title-text">设备走势图</div> </div> <div class="chart-controls"> <div class="chart-control-item-box"> <div class="chart-control-item" :class="{ active: timeRange === 'today' }" @click="handleTimeRangeChange('today')" > 今日 </div> <div class="chart-control-item" :class="{ active: timeRange === 'week' }" @click="handleTimeRangeChange('week')" > 本周 </div> <div class="chart-control-item" :class="{ active: timeRange === 'month' }" @click="handleTimeRangeChange('month')" > 本月 </div> <div class="chart-control-item" :class="{ active: timeRange === 'custom' }" @click="handleTimeRangeChange('custom')" > 自定义 </div> </div> </div> </div> <div class="chart-container" ref="deviceChart"></div> </div> </div> </template> <script> import * as echarts from "echarts5"; export default { name: "EquipmentMonitoring", data() { return { timeRange: "today", deviceStats: { total: 32856, online: 26645, offline: 3645, alarm: 1264, fault: 666, }, chartData: { today: { xAxis: [ "00:00", "04:00", "08:00", "12:00", "16:00", "20:00", "24:00", ], series: [ { name: "在线", data: [3200, 2800, 3500, 3800, 4200, 4000, 3600], color: "#07D1FA", }, { name: "离线", data: [800, 1200, 500, 200, 300, 500, 400], color: "#FFA500", }, { name: "报警", data: [100, 150, 200, 180, 120, 80, 60], color: "#00FF00", }, { name: "故障", data: [50, 80, 120, 100, 60, 40, 30], color: "#FF6B6B", }, ], }, week: { xAxis: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], series: [ { name: "在线", data: [3200, 3400, 3600, 3264, 3800, 3500, 3300], color: "#07D1FA", }, { name: "离线", data: [800, 600, 400, 636, 200, 500, 700], color: "#FFA500", }, { name: "报警", data: [100, 120, 140, 160, 180, 150, 130], color: "#00FF00", }, { name: "故障", data: [50, 60, 70, 80, 90, 75, 65], color: "#FF6B6B", }, ], }, month: { xAxis: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], series: [ { name: "在线", data: [3200, 3500, 3800, 4000, 4200, 4100, 4000], color: "#07D1FA", }, { name: "离线", data: [2800, 4500, 2700, 0, 3000, 1400, 500], color: "#FFA500", }, { name: "报警", data: [1600, 4120, 2140, 3160, 180, 4170, 1960], color: "#00FF00", }, { name: "故障", data: [2950, 4560, 700, 3380, 1290, 4585, 2280], color: "#FF6B6B", }, ], }, }, deviceChart: null, }; }, mounted() { this.initChart(); }, beforeDestroy() { if (this.deviceChart) { this.deviceChart.dispose(); } }, methods: { handleTimeRangeChange(value) { this.timeRange = value; // 修复:切换时更新 timeRange this.updateChart(); }, initChart() { this.deviceChart = echarts.init(this.$refs.deviceChart); this.updateChart(); }, updateChart() { const data = this.chartData[this.timeRange] || this.chartData.today; const option = { backgroundColor: "transparent", grid: { left: "3%", right: "4%", bottom: "3%", top: "15%", containLabel: true, }, legend: { data: ["在线", "离线", "报警", "故障"], textStyle: { color: "#ffffff", fontSize: 12, }, top: 0, left: 20, itemWidth: 12, itemHeight: 12, icon: "rect", itemStyle: { borderRadius: 8, // 增大圆角值(如6px,更容易观察效果) backgroundColor: "auto", // 自动继承系列颜色(也可显式设置,如 #07D1FA) borderWidth: 0, // 去除边框干扰 }, }, xAxis: { type: "category", boundaryGap: false, data: data.xAxis, axisLine: { lineStyle: { color: "rgba(255, 255, 255, 0.3)", }, }, axisLabel: { color: "#ffffff", fontSize: 12, }, }, yAxis: { type: "value", max: 5000, minInterval: 100, // 减小 y 轴间距 axisLine: { lineStyle: { color: "rgba(255, 255, 255, 0.3)", }, }, axisLabel: { color: "#ffffff", fontSize: 12, }, splitLine: { lineStyle: { color: "rgba(255, 255, 255, 0.1)", }, }, }, tooltip: { trigger: "item", axisPointer: { show: false }, borderColor: "transparent", // 边框透明 backgroundColor: require("../assets/images/safeHospital/left_tooltip.png"), // 使用 require 加载图片 show: true, // 默认不展示 triggerOn: "mousemove", // 鼠标悬浮才展示 formatter: function (data) { let tooltipHtml = `<div style="background: url(${require("../assets/images/safeHospital/left_tooltip.png")}) no-repeat; background-size: 100% 100%;width: 100%;height: 100%;padding: 10px; border-radius: 5px;">`; tooltipHtml += `<p style="color: white; font-size: 14px;">${data.name}</p>`; tooltipHtml += `<p style="color: #fff; font-size: 12px;">${data.seriesName}: ${data.value}</p>`; tooltipHtml += `</div>`; return tooltipHtml; }, }, series: data.series.map((item) => ({ name: item.name, type: "line", smooth: true, showSymbol: false, barWidth: 20, data: item.data, itemStyle: { normal: { color: item.color, width: 2, }, }, emphasis: { // 悬停时显示标记 symbol: "circle", symbolSize: 8, // 点的大小 itemStyle: { color: "yellow", // 点的颜色 }, }, })), }; this.deviceChart.setOption(option); }, }, }; </script> <style scoped lang="scss"> .equipment-monitoring { width: 100%; height: 100%; padding: 0px; // background: linear-gradient(135deg, #0e1c41 0%, #1a2b5c 100%); border-radius: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); position: relative; // overflow: hidden; &::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="stars" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="100" height="100" fill="url(%23stars)"/></svg>'); opacity: 0.3; pointer-events: none; } .text_show { -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-image: linear-gradient( 180deg, #ffffff 0%, #ffffff 50%, #7dd0ff 85% ); font-family: YouSheBiaoTiHei-Regular; } .monitoring-header { display: flex; align-items: center; margin-bottom: 20px; position: relative; z-index: 1; .header-icon { width: 100%; height: 59px; background: url("../assets/images/safeHospital/ai_title.png") no-repeat; background-size: 100% 100%; position: relative; display: flex; align-items: center; justify-content: space-between; .header-title { font-size: 20px; font-weight: 400; color: #ffffff; position: absolute; top: 20px; left: 75px; font-size: 22px; letter-spacing: 4px; text-shadow: 0px 4px 4px rgba(255, 255, 255, 0.1); } .header-dropdown { position: absolute; right: 10px; top: 33px; background: linear-gradient( 251deg, #6e9cd4 0%, #304f91 50%, #01040f 100% ); border-radius: 4px; box-shadow: inset 0px -3px 10px 0px rgba(47, 84, 140, 0.5), inset 0px 3px 10px 0px rgba(47, 84, 140, 0.5); .dropdown-link { color: #fff; cursor: pointer; height: 30px; line-height: 30px; display: block; padding: 0px 12px; box-shadow: inset 0px -3px 10px 0px rgba(47, 84, 140, 0.5), inset 0px 3px 10px 0px rgba(47, 84, 140, 0.5); border-radius: 4px; border: 1px solid; border-image: linear-gradient(150deg, #304f91, #eaf5ff) 1 1; background: transparent; box-shadow: none !important; font-family: PingFang SC; font-weight: 400; font-size: 14px; } } } } .monitoring-stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0px; margin-bottom: 5px; position: relative; z-index: 1; background: rgba(3, 30, 60, 0.8); padding: 6px; .monitoring-stats-left { // 直角三角形 width: 0; height: 0; border-top: 10px solid #5500ff; /* 控制三角形颜色 */ border-right: 10px solid transparent; } .monitoring-stats-right { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; position: relative; z-index: 1; padding: 6px 0; } .stats-item { background: linear-gradient( 180deg, rgba(10, 55, 106, 0) 0%, #0a376a 100% ); padding: 10px 8px; text-align: center; transition: all 0.3s ease; backdrop-filter: blur(10px); &:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3); border-color: rgba(255, 255, 255, 0.2); } .stats-icon { width: 50px; height: 50px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; position: relative; &::before { content: ""; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; border-radius: 50%; background: linear-gradient( 45deg, transparent, rgba(255, 255, 255, 0.1), transparent ); animation: rotate 3s linear infinite; } i { font-size: 24px; color: #ffffff; z-index: 1; } &.device-total { background: linear-gradient(135deg, #07d1fa 0%, #0056b3 100%); } &.device-online { background: linear-gradient(135deg, #00ff00 0%, #00cc00 100%); } &.device-offline { background: linear-gradient(135deg, #ffa500 0%, #ff8c00 100%); } &.device-alarm { background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%); } &.device-fault { background: linear-gradient(135deg, #ff6b6b 0%, #dc143c 100%); } } .stats-content { .stats-number { font-size: 24px; font-weight: 700; color: #ffffff; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } .stats-label { width: 70px; margin: 5px 0; font-size: 12px; color: rgba(255, 255, 255, 0.8); } } } } .monitoring-chart { background: rgba(3, 30, 60, 0.7); // border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; // padding: 20px; position: relative; z-index: 1; backdrop-filter: blur(10px); .chart-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 3px; .chart-title { width: 40%; display: flex; align-items: center; justify-content: center; .chart-title-text { margin-left: 10px; font-size: 22px; font-weight: 400; color: #ffffff; letter-spacing: 2px; text-shadow: 0px 4px 4px rgba(255, 255, 255, 0.1); } } .chart-controls { .chart-control-item-box { display: flex; align-items: center; justify-content: center; } .chart-control-item { padding: 0 5px; line-height: 25px; text-align: center; border-radius: 4px; border-radius: 4px 4px 4px 4px; border: 1px solid; border-image: linear-gradient( 150deg, rgba(107, 145, 196, 0.2), #2f548c ) 1 1; padding: 0 10px; margin-right: 10px; font-size: 14px; color: #59759c; text-align: center; cursor: pointer; &.active { color: #fff; cursor: pointer; height: 25px; line-height: 25px; display: block; padding: 0px 12px; box-shadow: inset 0px -3px 10px 0px rgba(47, 84, 140, 0.5), inset 0px 3px 10px 0px rgba(47, 84, 140, 0.5); border-radius: 4px; border: 1px solid; border-image: linear-gradient(150deg, #304f91, #eaf5ff) 1 1; background: transparent; box-shadow: none !important; font-family: PingFang SC; font-weight: 400; font-size: 14px; } } ::v-deep .el-radio-group { .el-radio-button { .el-radio-button__inner { background: transparent; border: 1px solid rgba(7, 209, 250, 0.3); color: rgba(255, 255, 255, 0.7); padding: 6px 12px; font-size: 12px; &:hover { color: #07d1fa; border-color: rgba(7, 209, 250, 0.5); } } &.is-active .el-radio-button__inner { background: linear-gradient(135deg, #07d1fa 0%, #0056b3 100%); border-color: #07d1fa; color: #ffffff; } } } } } .chart-container { height: 300px; width: 100%; } } } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes float { 0%, 100% { transform: translateY(0px); } 50% { transform: translateY(-5px); } } </style> 更改之后还是没有展示点位 showSymbol: true,才展示,我想实现鼠标悬停才展示
07-29
<template> <view class="container"> <view class="header"> <text class="header-title">在线投诉举报平台</text> <text class="header-subtitle">诚信是企业生存发展的根本</text> </view> <!-- 欢迎页面 --> <view v-if="showWelcome" class="welcome-section"> <view class="welcome-image"> <image src="/static/OnlinComplaint.jpg" mode=""></image> </view> <view class="welcome-content"> <text class="welcome-text">欢迎举报</text> <text class="welcome-text indent">诚信是做人做事的根本,同样诚信的企业才能生存发展。其亚的任何人,无论职务的高低,都应谨守廉洁并自觉接受各方监督。</text> <text class="welcome-text indent">任何单位个人都有有权举报其亚员工的违法违纪行为。同时,我们将对您提供的信息严格保密,一经查实,将根据公司制度给予相应奖励。</text> <text class="welcome-text indent">您可以选择匿名举报,无需填写个人联系方式。</text> </view> <view class="accept-box" :class="{disabled: countdown > 0}" @tap="handleAccept" > <text>我已阅读并理解上述内容</text> <view class="timer"> {{ countdown }}s </view> </view> </view> <!-- 表单页面 --> <view v-else class="form-section"> <view class="section-title"> <uni-icons type="compose" size="24" color="#3498db"></uni-icons> <text>投诉信息</text> </view> <view class="form-row"> <view class="form-col"> <view class="form-group"> <label for="title" class="required">投诉标题</label> <input type="text" id="title" placeholder="请输入投诉标题" v-model="formData.title" :class="{error: errors.title}" @blur="validateField('title')" > <text v-if="errors.title" class="error-text">{{ errors.title }}</text> </view> </view> <view class="form-col"> <view class="form-group"> <label for="category" class="required">类别</label> <picker @change="bindPickerChange" :value="categoryIndex" :range="categories.map(item => item.label)" class="picker" @blur="validateField('category')" > <view class="picker-content" :class="{placeholder: !formData.category, error: errors.category}"> {{ formData.category || '请选择投诉类别' }} </view> </picker> <text v-if="errors.category" class="error-text">{{ errors.category }}</text> </view> </view> </view> <view class="form-row"> <view class="form-col"> <view class="form-group"> <label for="complaineeName" class="required">被投诉人姓名</label> <input type="text" id="complaineeName" placeholder="请输入被投诉人姓名" v-model="formData.complaineeName" :class="{error: errors.complaineeName}" @blur="validateField('complaineeName')" > <text v-if="errors.complaineeName" class="error-text">{{ errors.complaineeName }}</text> </view> </view> <view class="form-col"> <view class="form-group"> <label for="company" class="required">被投诉人公司</label> <input type="text" id="company" placeholder="请输入公司名称" v-model="formData.company" :class="{error: errors.company}" @blur="validateField('company')" > <text v-if="errors.company" class="error-text">{{ errors.company }}</text> </view> </view> </view> <view class="form-row"> <view class="form-col"> <view class="form-group"> <label for="department" class="required">被投诉人部门</label> <input type="text" id="department" placeholder="请输入部门名称" v-model="formData.department" :class="{error: errors.department}" @blur="validateField('department')" > <text v-if="errors.department" class="error-text">{{ errors.department }}</text> </view> </view> </view> <view class="form-group"> <label for="content" class="required">投诉内容</label> <textarea id="content" placeholder="请您如实详细填写投诉内容(时间、地点、事件、经过)" v-model="formData.content" :class="{error: errors.content}" @blur="validateField('content')" ></textarea> <view class="content-counter"> <text>{{ formData.content.length }}/2000</text> </view> <text v-if="errors.content" class="error-text">{{ errors.content }}</text> </view> <view class="section-title"> <uni-icons type="paperclip" size="24" color="#3498db"></uni-icons> <text>上传附件</text> </view> <view class="upload-area" @tap="chooseAndUploadFile" :class="{disabled: uploadDisabled}"> <view class="upload-icon"> <uni-icons type="cloud-upload" size="48" color="#3498db"></uni-icons> </view> <view class="upload-text">点击上传到此处</view> <view class="file-types">支持word文档、照片、MP3、MP4等格式,每次上传文件大小不超过10M,附件过大请发投诉渠道邮箱</view> <view v-if="uploading" class="upload-progress"> <uni-progress :percent="uploadProgress" stroke-width="48" activeColor="#3498db"></uni-progress> </view> </view> <view v-if="files.length > 0" class="file-list"> <view v-for="(file, index) in files" :key="index" class="file-item"> <uni-icons type="paperclip" size="18" color="#3498db"></uni-icons> <view class="file-info"> <text class="file-name">{{ file.name }}</text> <text class="file-size">({{ formatFileSize(file.size) }})</text> </view> <view class="delete-btn" @tap="removeFile(index)" >X <uni-icons type="close" size="16" color="#ffffff" ></uni-icons> </view> </view> </view> <view class="section-title"> <uni-icons type="person" size="24" color="#3498db"></uni-icons> <text>联系方式(选填,支持匿名)</text> </view> <view class="form-row"> <view class="form-col"> <view class="form-group"> <label for="name">姓名(选填)</label> <input type="text" id="name" placeholder="请输入您的姓名(选填)" v-model="formData.name" :class="{error: errors.name}" @blur="validateField('name')" > <text v-if="errors.name" class="error-text">{{ errors.name }}</text> </view> </view> <view class="form-col"> <view class="form-group"> <label for="phone">手机号(选填)</label> <input type="number" id="phone" placeholder="请输入您的手机号(选填)" v-model="formData.phone" :class="{error: errors.phone}" @blur="validateField('phone')" > <text v-if="errors.phone" class="error-text">{{ errors.phone }}</text> </view> </view> </view> <view class="form-row"> <view class="form-col"> <view class="form-group"> <label for="email">邮箱(选填)</label> <input type="email" id="email" placeholder="请输入您的邮箱(选填)" v-model="formData.email" :class="{error: errors.email}" @blur="validateField('email')" > <text v-if="errors.email" class="error-text">{{ errors.email }}</text> </view> </view> </view> <view class="privacy-note"> 您可以选择匿名举报,无需填写个人联系方式。如填写联系方式,我们会对您的个人信息及投诉内容进行严格保密,便于后续跟进调查。 </view> <button class="submit-btn" @tap="submitForm" :disabled="uploading || processing"> <template v-if="processing">处理中...</template> <template v-else>提交投诉</template> </button> </view> </view> </template> <script setup> import { ref, onMounted } from 'vue'; import { onShow } from '@dcloudio/uni-app'; // 存储openID的变量 const openId = ref(''); // 表单数据 const formData = ref({ title: '', category: '', // 存储显示的类别名称 categoryValue: '', // 存储实际提交的类别值 complaineeName: '', company: '', department: '', content: '', name: '', // 可选 phone: '', // 可选 email: '' // 可选 }); // 错误信息 const errors = ref({}); // 文件列表 - 存储上传成功后的文件信息 const files = ref([]); // 上传状态管理 const uploading = ref(false); const uploadProgress = ref(0); const uploadDisabled = ref(false); // 处理状态(用于获取OpenID提交过程中) const processing = ref(false); // 类别选择(包含显示文本对应的值) const categories = ref([ { label: '财务违规', value: '1' }, { label: '道德问题', value: '2' }, { label: '职场骚扰', value: '3' }, { label: '安全隐患', value: '4' } ]); const categoryIndex = ref(-1); // 欢迎页状态 const showWelcome = ref(true); const countdown = ref(5); // 处理接受按钮点击 const handleAccept = () => { if (countdown.value > 0) return; showWelcome.value = false; }; // 选择类别 - 同时记录显示文本实际值 const bindPickerChange = (e) => { categoryIndex.value = e.detail.value; const selected = categories.value[e.detail.value]; formData.value.category = selected.label; // 显示用 formData.value.categoryValue = selected.value; // 实际提交用 validateField('category'); // 选择后立即验证 }; // 选择并上传文件 const chooseAndUploadFile = async () => { if (uploading.value) return; try { // 选择文件 const res = await uni.chooseFile({ count: 5 - files.value.length, // 限制总文件数不超过5个 type: 'all', extension: ['png', 'jpg', 'jpeg', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'mp3', 'mp4'], }); if (res.tempFiles && res.tempFiles.length > 0) { // 开始上传 uploadFiles(res.tempFiles); } } catch (err) { console.log('选择文件失败', err); uni.showToast({ title: '选择文件失败', icon: 'error', duration: 2000 }); } }; // 上传文件到服务器 const uploadFiles = async (tempFiles) => { uploading.value = true; uploadDisabled.value = true; uploadProgress.value = 0; // 显示加载弹窗(小圆圈) uni.showLoading({ title: '正在上传...', mask: true // 防止背景点击 }); try { // 计算总文件大小 const totalSize = tempFiles.reduce((sum, file) => sum + file.size, 0); let uploadedSize = 0; // 逐个上传文件 for (let i = 0; i < tempFiles.length; i++) { const file = tempFiles[i]; await new Promise((resolve, reject) => { uni.uploadFile({ url: '/api/file/upload', filePath: file.path, name: 'file', header: {}, timeout: 360000, // 1分钟超时 // 移除进度更新逻辑(不再需要) success: (res) => { try { const response = JSON.parse(res.data); if (res.statusCode === 200 && response.code === 200 && response.data) { uploadedSize += file.size; files.value.push({ name: response.data.name, size: file.size, url: response.data.url, id: Date.now() + i }); resolve(); } else { throw new Error(response.msg || `文件上传失败,错误代码: ${response.code}`); } } catch (err) { reject(err); } }, fail: (err) => { reject(new Error(`上传失败: ${err.errMsg}`)); } }); }); } // 文件上传成功后提示 uni.showToast({ title: '文件上传成功', icon: 'success' }); } catch (err) { console.error('文件上传失败', err); uni.showToast({ title: err.message || '文件上传失败', icon: 'error' }); } finally { // 关闭加载弹窗 uni.hideLoading(); uploading.value = false; uploadDisabled.value = false; uploadProgress.value = 0; } }; // 移除文件 const removeFile = (index) => { files.value.splice(index, 1); }; // 格式化文件大小 const formatFileSize = (bytes) => { if (bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }; // 单个字段验证 const validateField = (field) => { const value = formData.value[field]; let error = ''; switch(field) { case 'title': if (!value) error = '请输入投诉标题'; else if (value.length > 100) error = '标题长度不能超过100个字符'; break; case 'category': if (!value) error = '请选择投诉类别'; break; case 'complaineeName': if (!value) error = '请输入被投诉人姓名'; else if (value.length > 50) error = '姓名长度不能超过50个字符'; break; case 'company': if (!value) error = '请输入被投诉人公司'; else if (value.length > 100) error = '公司名称长度不能超过100个字符'; break; case 'department': if (!value) error = '请输入被投诉人部门'; else if (value.length > 100) error = '部门名称长度不能超过100个字符'; break; case 'content': if (!value) error = '请输入投诉内容'; else if (value.length < 1) error = '投诉内容不能为空'; break; case 'name': if (value && value.length > 50) error = '姓名长度不能超过50个字符'; break; case 'phone': const phoneRegex = /^1[3-9]\d{9}$/; if (value && value.trim() !== '' && !phoneRegex.test(value)) { error = '请输入有效的手机号码'; } break; case 'email': const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (value && value.trim() !== '' && !emailRegex.test(value)) { error = '请输入有效的邮箱地址'; } break; } errors.value[field] = error; return !error; }; // 表单验证 - 验证所有必填项格式 const validateForm = () => { errors.value = {}; let isValid = true; // 验证所有字段 const allFields = ['title', 'category', 'complaineeName', 'company', 'department', 'content', 'name', 'phone', 'email']; allFields.forEach(field => { if (!validateField(field)) { isValid = false; } }); return isValid; }; // 提交表单 const submitForm = async () => { if (uploading.value || processing.value) { uni.showToast({ title: '操作处理中,请稍后', icon: 'none', duration: 2000 }); return; } // 先验证表单 const isValid = validateForm(); if (!isValid) { // 滚动到第一个错误字段 const firstErrorField = Object.keys(errors.value).find(key => errors.value[key]); if (firstErrorField) { const element = document.getElementById(firstErrorField); if (element) { element.scrollIntoView({ behavior: 'smooth', block: 'center' }); // 给错误字段添加闪烁效果 element.classList.add('error-highlight'); setTimeout(() => element.classList.remove('error-highlight'), 1000); } } const firstError = Object.values(errors.value).find(msg => msg); if (firstError) { uni.showToast({ title: firstError, icon: 'none', duration: 2000 }); } return; } processing.value = true; try { // 从本地缓存获取OpenID const openId = uni.getStorageSync('wechat_openid') || ''; // 准备提交的数据 const submitData = { title: formData.value.title, complaintType: formData.value.categoryValue, bcomplaintName: formData.value.complaineeName, bcomplaintCompany: formData.value.company, bcomplaintDept: formData.value.department, bcomplaintContent: formData.value.content, processingStatus: "1", fileUrl: files.value.map(file => file.url).join(','), complaintPerson: formData.value.name || '', phoneNumber: formData.value.phone || '', email: formData.value.email || '', wxUserId: openId // 将openID传入wxUserId字段 }; uni.showLoading({ title: '提交中...', mask: true }); // 提交表单数据到接口 await new Promise((resolve, reject) => { uni.request({ url: '/api/incorruptFront/addComplainTs', method: 'POST', data: submitData, header: { 'Content-Type': 'application/json' }, success: (res) => { if (res.statusCode === 200 && res.data.code === 200) { resolve(res.data); } else { reject(new Error(res.data.msg || '提交失败')); } }, fail: (err) => { reject(new Error(`网络错误: ${err.errMsg}`)); } }); }); uni.hideLoading(); uni.showToast({ title: '投诉信息已提交', icon: 'success', duration: 2000 }); // 2秒后返回首页 setTimeout(() => { uni.reLaunch({ url: '/pages/index/index' }); }, 2000); } catch (error) { console.error('提交表单失败', error); uni.hideLoading(); uni.showToast({ title: error.message || '提交失败,请重试', icon: 'error', duration: 2000 }); } finally { processing.value = false; } }; // 页面加载 onMounted(() => { // 启动倒计时 const timer = setInterval(() => { if (countdown.value > 0) { countdown.value--; } else { clearInterval(timer); } }, 1000); // 从缓存获取openID openId.value = uni.getStorageSync('wechat_openid') || ''; }); </script> <style lang="scss"> /* 基础样式保持不变 */ .container { display: flex; flex-direction: column; min-height: 100vh; background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); padding: 20rpx; } .header { background: linear-gradient(135deg, #3498db 0%, #2c3e50 100%); color: white; text-align: center; padding: 40rpx 20rpx; border-radius: 0 0 30rpx 30rpx; margin-bottom: 20rpx; box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.15); } .header-title { display: block; font-size: 40rpx; font-weight: bold; margin-bottom: 15rpx; letter-spacing: 1rpx; } .header-subtitle { font-size: 28rpx; opacity: 0.9; } .welcome-section { padding: 30rpx; transition: all 0.5s ease; } .welcome-image { width: 100%; height: 300rpx; border-radius: 20rpx; overflow: hidden; box-shadow: 0 8rpx 25rpx rgba(0, 0, 0, 0.1); display: flex; justify-content: center; align-items: center; } .welcome-image image { width: 100%; height: 100%; object-fit: cover; } .welcome-content { background-color: #f8f9fa; border-radius: 20rpx; padding: 30rpx; line-height: 1.8; font-size: 28rpx; color: #333; box-shadow: inset 0 0 10rpx rgba(0, 0, 0, 0.05); margin-bottom: 30rpx; } .welcome-text { display: block; margin-bottom: 20rpx; } .accept-box { display: flex; justify-content: center; align-items: center; padding: 25rpx; background-color: #e3f2fd; border-radius: 20rpx; cursor: pointer; transition: all 0.3s ease; border: 2rpx solid #bbdefb; box-shadow: 0 4rpx 15rpx rgba(0, 0, 0, 0.1); } .accept-box.disabled { background-color: #f5f5f5; cursor: not-allowed; opacity: 0.7; } .accept-box .timer { background-color: #e74c3c; color: white; width: 70rpx; height: 70rpx; border-radius: 50%; display: flex; justify-content: center; align-items: center; margin-left: 20rpx; font-weight: bold; font-size: 30rpx; } .form-section { padding: 30rpx; } .section-title { font-size: 34rpx; color: #2c3e50; margin-bottom: 30rpx; padding-bottom: 15rpx; border-bottom: 2rpx solid #3498db; display: flex; align-items: center; text { margin-left: 15rpx; font-weight: bold; } } .form-group { margin-bottom: 35rpx; position: relative; } .form-row { &.full-width { display: flex; flex-wrap: wrap; margin: 0 -15rpx; margin-bottom: 40rpx; } } .form-col { flex: 1; padding: 0 15rpx; min-width: 300rpx; } label { display: block; margin-bottom: 15rpx; font-weight: 500; color: #2c3e50; font-size: 30rpx; } label.required::after { content: "*"; color: #e74c3c; margin-left: 8rpx; } input, select, textarea, .picker-content { width: 100%; padding: 25rpx; border: 2rpx solid #e0e0e0; border-radius: 15rpx; font-size: 28rpx; transition: all 0.3s ease; background-color: #fff; } input:focus, select:focus, textarea:focus, .picker-content:active { border-color: #3498db; outline: none; box-shadow: 0 0 0 3rpx rgba(52, 152, 219, 0.2); } textarea { min-height: 200rpx; resize: vertical; } /* 新增的内容计数器样式 */ .content-counter { text-align: right; font-size: 24rpx; color: #999; margin-top: 10rpx; } .picker-content { display: flex; align-items: center; min-height: 80rpx; /* 确保选择器高度输入框一致 */ &.placeholder { color: #999; } } .upload-area { border: 2rpx dashed #3498db; border-radius: 20rpx; padding: 40rpx 30rpx; text-align: center; background-color: #e3f2fd; cursor: pointer; transition: all 0.3s ease; margin-bottom: 30rpx; } .upload-area.disabled { background-color: #f5f5f5; border-color: #bdc3c7; cursor: not-allowed; } .upload-area:active:not(.disabled) { background-color: #bbdefb; transform: scale(0.98); } .upload-icon { margin-bottom: 20rpx; } .upload-text { color: #2c3e50; margin-bottom: 20rpx; font-size: 30rpx; font-weight: 500; } .file-types { color: #7f8c8d; font-size: 26rpx; margin-bottom: 20rpx; } .upload-progress { width: 80%; margin: 20rpx auto 0; } .progress-text { display: block; margin-top: 10rpx; font-size: 26rpx; color: #3498db; } .file-list { margin-top: 20rpx; margin-bottom: 30rpx; } .file-item { display: flex; align-items: center; padding: 20rpx; background-color: #f8f9fa; border-radius: 15rpx; margin-bottom: 15rpx; border-left: 4rpx solid #3498db; } /* 优化文件信息显示 */ .file-info { flex: 1; margin: 0 15rpx; min-width: 0; /* 允许容器收缩 */ } .file-name { display: block; font-size: 28rpx; color: #2c3e50; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; /* 不换行,超出部分显示省略号 */ } .file-size { display: block; color: #7f8c8d; font-size: 24rpx; margin-top: 5rpx; } .delete-btn { width: 40rpx; height: 40rpx; border-radius: 50%; background-color: #e74c3c; display: flex; justify-content: center; align-items: center; margin-left: 10rpx; flex-shrink: 0; /* 确保按钮不被挤压 */ transition: all 0.2s ease; color: #ffffff; } .delete-btn:active { background-color: #c0392b; transform: scale(0.9); } .error-text { display: block; color: #e74c3c; font-size: 26rpx; margin-top: 10rpx; } input.error, textarea.error, .picker-content.error { border-color: #e74c3c; animation: shake 0.5s ease; } /* 错误字段高亮动画 */ .error-highlight { animation: highlight 1s ease; } @keyframes shake { 0%, 100% { transform: translateX(0); } 20%, 60% { transform: translateX(-5rpx); } 40%, 80% { transform: translateX(5rpx); } } @keyframes highlight { 0%, 100% { box-shadow: none; } 50% { box-shadow: 0 0 0 4rpx rgba(231, 76, 60, 0.3); } } .privacy-note { background-color: #f8f9fa; border-radius: 15rpx; padding: 25rpx; margin-top: 30rpx; font-size: 26rpx; color: #7f8c8d; text-align: center; border: 1rpx solid #e9ecef; line-height: 1.6; } .submit-btn { background: linear-gradient(to right, #3498db, #2980b9); color: white; border: none; padding: 25rpx 0; width: 100%; border-radius: 50rpx; font-size: 32rpx; font-weight: 600; margin-top: 30rpx; box-shadow: 0 5rpx 20rpx rgba(52, 152, 219, 0.4); transition: all 0.3s ease; } .submit-btn:disabled { background: #bdc3c7; box-shadow: none; opacity: 0.7; } .submit-btn:active:not(:disabled) { transform: translateY(-3rpx); box-shadow: 0 8rpx 25rpx rgba(52, 152, 219, 0.6); } /* 响应式设计 */ @media (min-width: 768px) { .container { max-width: 750px; margin: 0 auto; padding: 40rpx; } .welcome-image { height: 350rpx; } } .welcome-text.indent{ text-indent: 2em; } </style> 上传附件报错:Request URL: http://www.wyqg.top/api/file/upload Request Method: POST Status Code: 400 Bad Request Remote Address: 47.109.65.73:80 Referrer Policy: strict-origin-when-cross-origin Connection: keep-alive Content-Length: 0 Date: Mon, 01 Sep 2025 10:00:25 GMT Server: nginx/1.26.3 Accept: */* Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: keep-alive Content-Length: 10485948 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGFsvh0KKYAXIXI27 Host: www.wyqg.top Origin: http://www.wyqg.top Referer: http://www.wyqg.top/pages/OnlinComplaint/OnlinComplaint?openid=ohhFX6TzyGvbXFuIL0ZPjEIpsJOo User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1 wechatdevtools/1.06.2504030 MicroMessenger/8.0.5 Language/zh_CN webview/17566896873445375 webdebugger port/57256 token/84cac3393fe84eaa19bae7107a7c7659 file: (binary) 但是我用postman测试接口,用post方法 Body选择 form-data,键file是文件,值上传了一个MP4文件测试没问题
09-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值