首页
关于
友链
推荐
肥啾解析
百度一下
肥啾GPT
Search
1
宝塔面板登录 phpMyAdmin 提示服务器和客户端上指示的HTTPS之间不匹配
274 阅读
2
Customer complaints evolve with in-car tech
188 阅读
3
JavaScript解析
153 阅读
4
内连接,左连接,右连接作用及区别
112 阅读
5
所谓关系
109 阅读
默认分类
网游架设
手机游戏
python
PHP
Mysql
VBA
C++
JAVASCRIPT
javascript基础
Oracle
生产管理
计划控制
ERP系统开发
APS排产
MES研究
考勤系统
CPA
财管
实务
经济法
战略
审计
税法
藏书架
古典名著
世界名著
编程秘籍
攻防渗透
经管书籍
大佬传经
风雅读物
考试相关
心情格言
拾玉良言
外文报刊
外刊随选
Facebook
Twitter
China Daily
软考
登录
Search
标签搜索
期刊读物
古文
何瑜明
累计撰写
178
篇文章
累计收到
154
条评论
首页
栏目
默认分类
网游架设
手机游戏
python
PHP
Mysql
VBA
C++
JAVASCRIPT
javascript基础
Oracle
生产管理
计划控制
ERP系统开发
APS排产
MES研究
考勤系统
CPA
财管
实务
经济法
战略
审计
税法
藏书架
古典名著
世界名著
编程秘籍
攻防渗透
经管书籍
大佬传经
风雅读物
考试相关
心情格言
拾玉良言
外文报刊
外刊随选
Facebook
Twitter
China Daily
软考
页面
关于
友链
推荐
肥啾解析
百度一下
肥啾GPT
搜索到
23
篇与
的结果
2025-07-23
Oracle和MySQL语法区别
最近需要迁移项目,将数据库由Oracle改为MySQL。由于两者的语法有部分不一样,所以需要把Oracle中能用但MySQL中不能用的函数/类型等改为MySQL中能用的,以下是总结出的部分语法区别:一、数据类型Number类型MySQL中是没有Number类型的,但有int/decimal 类型,Oracle中的Number(5,1)对应MySQL中的decimal(5,1),Number(5) 对应 int(5)。MySQL中的数字型类型比较多,分的也比较细,还有tinyint、smallint、mediumint、bigint等类型Varchar2(n)类型MySQL中对应Oracle Varchar2(n)类型的替代类型是varchar(n)类型。Date 类型MySQL 中的日期时间类型有Date、Time、Datetime等类型,MySQL中Date类型仅表示日期(年-月-日),Time类型仅表示时间(时:分:秒),而Datetime类型表示日期时间(年-月-日 时:分:秒),Oracle中的Date类型和MySQL中的Datetime类型一致。二、函数length(str)函数Oracle中的length(str)是获取字符串长度的函数,MySQL 中对应的函数为char_length(str)。sys_guid()函数Oracle中可通过sys_guid()函数是生成随机序列,MySQL通过UUID()生成随机序列。时间格式化函数将时间转换为字符串型时间 MySQL date_format(NOW(),'%Y-%m-%d') 对应Oracle的 Oracle中的 to_char(sysdate, 'YYYY-MM-DD');将字符串型时间转换为时间类型 MySQL str_to_date('2019-01-01','%Y-%m-%d') 对应Oracle中的 to_date('2019-01-01', 'YYYY-MM-DD');包括时分秒的函数转换:DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s'),str_to_date('2019-01-01','%Y-%m-%d %H:%i:%s')。条件函数(nvl()、nvl2()、decode())nvl(tab.columnName, 0):如果tab.columnName值为空,则返回值取0,否则取tab.columnName;对应的MySQL函数为:ifnull(tab.columnName, 0)。nvl2(expr1,expr2,expr3):如果expr1不为null,则返回expr2,否则返回expr3;对应的MySQL函数为:if(expr1,expr2,expr3)。DECODE(value, val1, val2, val3):如果value等于val1,则返回val2,否则返回val3;MySQL可用IF函数表示:if(value=val1, val2, val3);DECODE(value, if1, val1, if2,val2,...,ifn, valn, val):如果value等于if1,则返回val1,如果value等于if2,则返回value2...如果value等于ifn,则返回valn,否则返回val;MySQL对于这种判断可以通过case when then else end;l来判断,即:case when value=if1 then val1 when value=if2 then val2,,,when value=ifn then valn else val end;trunc()函数TRUNC(12.123):返回整数(12);MySQL对应的函数:truncate(12.123, 0);TRUNC(12.123, 2):返回值保留2为小数(12.12);MySQL对应的函数:truncate(12.123, 2);TRUNC(SYSDATE):返回值为(2019-07-26 00:00:00);MySQL对应的为cast(now() as datetime):返回值为(2019-07-26 14:11:38);MySQL的cast函数语法为:CAST(xxx AS 类型) (可用类型为:二进制,同带binary前缀的效果:BINARY;字符型,可带参数:CHAR();日期:DATE;时间:TIME;日期时间型: DATETIME;浮点数: DECIMAL;整数:SIGNED;无符号整数:UNSIGNED)to_char() to_number()to_char(123):将数字123转换为字符串123;MySQL对应的函数为CAST(123 AS CHAR(3));to_number('123'):将字符串数字123转换为数字类型;MySQL对应的函数为cast('123' as SIGNED);sysdate 当前时间sysdate:返回当前日期+时间; MySQL对应的函数为 now();三、其他引号MySQL可识别双引号和单引号,Oracle只能识别单引号。字符串连接符 ||Oracle 可用'||'来连接字符串,但MySQL不支持'||'连接,MySQL可通过concat()函数链接字符串。Oracle的 a.studentname||'【'||a.studentno||'】' 相当于 MySQL的 concat(a.studentname, '【', a.studentno, '】')ROWNUMOracle可通过rownum获取前n条记录,MySQL通过limit来获取前n条记录,但二者的写法略有不同,在Oracle中rownum作为where条件的一部分,而MySQL中limit不是where条件的一部分。-- rownum语法如下:SELECT * FROM XJ_STUDENT WHERE ROWNUM = 1; -- 查询第一条数据SELECT * FROM XJ_STUDENT WHERE ROWNUM <= 10; -- 获取前10条数据-- 但rownum不支持查询后几条或第n(n>1)条数据,例如以下sql是不支持的SELECT * FROM XJ_STUDENT WHERE ROWNUM > 2;SELECT * FROM XJ_STUDENT WHERE ROWNUM = 3;-- limit 语法如下:SELECT * from fw_department limit 3; -- 查询前3条数据SELECT * from fw_department limit 2, 4; -- 从第2(序号从0开始)条开始,查4条记录空数据排序(nulls first 和nulls last)-- null值排在最前SELECT * FROM FW_DEPARTMENT A ORDER BY A.REMARK DESC NULLS FIRST-- null值排在最后SELECT * FROM FW_DEPARTMENT A ORDER BY A.REMARK DESC NULLS LAST-- MySQL 可通过IF和ISNULL函数达到相同的效果-- null值排在最后select * from FW_DEPARTMENT A order by IF(ISNULL(A.REMARK),1,0),A.REMARK desc-- null值排在最前select * from FW_DEPARTMENT A order by IF(ISNULL(A.REMARK),0,1),A.REMARK desc表(左/右)关联(+)Oracle左连接,右连接可以使用(+)来实现. MySQL只能使用left join ,right join等关键字。-- Oracle 左关联select * from taba, tabb where taba.id = tabb.id(+);-- Oracle 右关联select * from taba, tabb where taba.id(+) = tabb.id;-- MySQL 左关联select * from taba left join tabb on taba.id=tabb.id;-- MySQL 右关联select * from taba right join tabb on taba.id=tabb.id;删除语法MySQL的删除语法没有Oracle那么随意,例如下面的sql在Oracle中可以执行,但在MySQL中就不可以。-- Oracle 可执行,但MySQL中不能执行DELETE FROM FW_DEPARTMENT A WHERE A.DEPID = '111';DELETE FW_DEPARTMENT WHERE DEPID = '111';-- MySQL中删除语句格式如下:DELETE FROM FW_DEPARTMENT WHERE DEPID = '111';递归查询(start with connect by prior)MySQL不支持(start with connect by prior)的这种递归查询,但可以通过自定义函数来实现。-- Oracle 递归查询 查询部门ID为‘1111’的所有子部门(包含自身)SELECT *FROM FW_DEPARTMENTSTART WITH DEPID='1111'CONNECT BY PRIOR DEPID = PARENTDEPID;-- Oracle 递归查询 查询部门ID为‘1111’的所有父部门(包含自身)SELECT *FROM FW_DEPARTMENTSTART WITH DEPID='1111'CONNECT BY PRIOR PARENTDEPID = DEPID;-- MySQL 先创建fun_getDepIDList函数,用于查询部门ID字符串CREATE FUNCTION fun_getDepIDList(rootId VARCHAR(32))RETURNS VARCHAR(6000)BEGINDECLARE pTemp VARCHAR(6000);DECLARE cTemp VARCHAR(6000);SET pTemp='$';SET cTemp=rootId;WHILE cTemp is not null DOset pTemp=CONCAT(pTemp,',',cTemp);SELECT GROUP_CONCAT(depid) INTO cTemp from fw_departmentWHERE FIND_IN_SET(PARENTDEPID,cTemp)>0;END WHILE;RETURN pTemp;END;-- 查询部门ID为‘1111’的所有子部门(包含自己)select * from fw_departmentwhere FIND_IN_SET(DEPID, fun_getDepIDList('1111'));-- 查询部门ID为‘1111’的所有父部门(包含自己)select * from fw_departmentwhere FIND_IN_SET('1111', fun_getDepIDList(DEPID));merge intoMySQL不支持(merge into),但提供的replace into 和on duplicate key update可实现相似的功能。-- Oracle merge into (有则修改,无则新增)MERGE INTO TMPDEPTAB AUSING (SELECT '1111' DEPID, '哈哈' DEPNAME FROM DUAL) BON (A.DEPID = B.DEPID)WHEN MATCHED THENUPDATE SET A.DEPNAME = B.DEPNAMEWHEN NOT MATCHED THENINSERT(DEPID, DEPNAME) VALUES(B.DEPID, B.DEPNAME);-- MySQL replace into (特点:1、先删后增; 2、插入/更新的表必须有主键或唯一索引;-- 3、未修改/新增的数据项,如果必填,则必须有默认值)-- 1、由于是先删后增,所以需要满足以下2个条件之一:-- 1.要么必填项有默认值;-- 2.要么插入/更新时为没有默认值的必填项赋值, 否则新增时会报错。-- 2、表中需要有主键或唯一索引,否则下面语句如果执行多次,表中会出现重复数据。replace into fw_department(DEPID,PARENTDEPID,DEPNO,DEPNAME)values('1111111', '1234','123', '哈哈');-- MySQL on duplicate key update (特点:1、插入/更新的表必须有主键或唯一索引;-- 2、未修改/新增的数据项,如果必填,则必须有默认值)insert into fw_department(depid,parentdepid,depno,depname)select '1111111' depid, '123' parentdepid, 'e12' depno, '哈哈哈哈' depnamefrom fw_departmenton duplicate keyupdate parentdepid = values(parentdepid),depno=values(depno),depname=values(depname);withOracle 中可用with来构建一个临时表,但MySQL不支持with,对应临时表,MySQL可通过小括号的方式来处理,但构建的临时表必须设置临时表名。-- Oracle with使用WITH TMPTAB AS (SELECT A.DEPID FROM FW_DEPARTMENT A)SELECT DEPIDFROM TMPTAB-- MySQL 构建临时表使用(此处必须给括号中的临时表设置表名)select b.depidfrom (select depidfrom fw_department) bhttps://blog.csdn.net/weixin_63021300/article/details/132267190?ops_request_misc=%257B%2522request%255Fid%2522%253A%252274a5a63189f4ae0093201ba847814e67%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=74a5a63189f4ae0093201ba847814e67&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-132267190-null-null.142^v102^pc_search_result_base1&utm_term=oracle&spm=1018.2226.3001.4187
2025年07月23日
3 阅读
0 评论
0 点赞
2025-07-03
此内容被密码保护
加密文章,请前往内页查看详情
2025年07月03日
1 阅读
0 评论
0 点赞
2025-06-23
抠图功能
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>智能抠图工具 - 一键去除背景</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); min-height: 100vh; padding: 20px; display: flex; flex-direction: column; align-items: center; color: white; } .container { width: 100%; max-width: 1200px; padding: 20px; } header { text-align: center; margin-bottom: 30px; padding: 20px; animation: fadeIn 1s ease; } h1 { font-size: 2.5rem; margin-bottom: 10px; text-shadow: 0 2px 4px rgba(0,0,0,0.2); } .subtitle { font-size: 1.2rem; opacity: 0.9; max-width: 600px; margin: 0 auto; } .app-container { display: flex; flex-wrap: wrap; gap: 30px; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border-radius: 20px; padding: 30px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); } .upload-section { flex: 1; min-width: 300px; display: flex; flex-direction: column; gap: 20px; } .preview-section { flex: 1; min-width: 300px; display: flex; flex-direction: column; gap: 20px; } .section-title { font-size: 1.3rem; margin-bottom: 10px; display: flex; align-items: center; gap: 10px; } .section-title i { font-size: 1.5rem; } .drop-area { border: 3px dashed rgba(255, 255, 255, 0.5); border-radius: 15px; padding: 40px 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; cursor: pointer; transition: all 0.3s ease; background: rgba(255, 255, 255, 0.05); } .drop-area:hover, .drop-area.active { border-color: #fff; background: rgba(255, 255, 255, 0.1); } .drop-area i { font-size: 3rem; margin-bottom: 15px; color: rgba(255, 255, 255, 0.7); } .drop-area p { margin: 10px 0; } .file-input { display: none; } .btn { background: linear-gradient(45deg, #ff8a00, #ff2070); color: white; border: none; padding: 12px 25px; font-size: 1rem; border-radius: 50px; cursor: pointer; transition: all 0.3s ease; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 8px; box-shadow: 0 4px 15px rgba(255, 138, 0, 0.3); } .btn:hover { transform: translateY(-3px); box-shadow: 0 7px 20px rgba(255, 138, 0, 0.4); } .btn:active { transform: translateY(0); } .btn-outline { background: transparent; border: 2px solid rgba(255, 255, 255, 0.5); box-shadow: none; } .btn-outline:hover { background: rgba(255, 255, 255, 0.1); } .preview-container { display: flex; flex-direction: column; gap: 20px; } .preview-box { position: relative; width: 100%; height: 250px; border-radius: 15px; overflow: hidden; background: rgba(0, 0, 0, 0.2); display: flex; align-items: center; justify-content: center; border: 2px solid rgba(255, 255, 255, 0.1); } .preview-box img, .preview-box canvas { max-width: 100%; max-height: 100%; display: none; } .preview-placeholder { text-align: center; color: rgba(255, 255, 255, 0.5); } .controls { display: flex; gap: 15px; flex-wrap: wrap; } .tolerance-control { flex: 1; min-width: 200px; } .tolerance-label { display: flex; justify-content: space-between; margin-bottom: 8px; } .slider { width: 100%; height: 10px; -webkit-appearance: none; background: rgba(255, 255, 255, 0.1); border-radius: 5px; outline: none; } .slider::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%; background: #ff8a00; cursor: pointer; } .tolerance-value { background: rgba(255, 255, 255, 0.1); padding: 2px 10px; border-radius: 10px; min-width: 40px; text-align: center; } .result-actions { display: flex; gap: 15px; margin-top: 10px; } .info-box { background: rgba(0, 0, 0, 0.2); border-radius: 15px; padding: 20px; margin-top: 30px; font-size: 0.9rem; } .info-box h3 { margin-bottom: 15px; display: flex; align-items: center; gap: 10px; } .info-content { display: flex; flex-wrap: wrap; gap: 20px; } .info-item { flex: 1; min-width: 250px; } .info-item ul { padding-left: 20px; margin-top: 10px; } .info-item li { margin-bottom: 8px; } footer { text-align: center; margin-top: 40px; padding: 20px; color: rgba(255, 255, 255, 0.7); font-size: 0.9rem; } .loading { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); flex-direction: column; align-items: center; justify-content: center; z-index: 10; border-radius: 15px; } .spinner { width: 50px; height: 50px; border: 5px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top: 5px solid #ff8a00; animation: spin 1s linear infinite; margin-bottom: 15px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes fadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } .featured-examples { display: flex; gap: 20px; margin-top: 15px; justify-content: center; flex-wrap: wrap; } .example-item { width: 80px; height: 80px; border-radius: 10px; overflow: hidden; cursor: pointer; border: 2px solid rgba(255, 255, 255, 0.3); transition: all 0.3s ease; } .example-item:hover { transform: scale(1.05); border-color: white; } .example-item img { width: 100%; height: 100%; object-fit: cover; } @media (max-width: 768px) { .app-container { flex-direction: column; } .controls { flex-direction: column; } h1 { font-size: 2rem; } } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> </head> <body> <div class="container"> <header> <h1><i class="fas fa-magic"></i> 智能抠图工具</h1> <p class="subtitle">上传图片,一键自动去除背景 - 无需复杂操作,快速获得透明背景PNG图片</p> </header> <div class="app-container"> <div class="upload-section"> <h2 class="section-title"><i class="fas fa-upload"></i> 上传图片</h2> <div class="drop-area" id="dropArea"> <i class="fas fa-cloud-upload-alt"></i> <p>拖放图片到此处或</p> <button class="btn" id="browseBtn"><i class="fas fa-folder-open"></i> 选择图片</button> <p class="small">支持 JPG, PNG 格式,最大 5MB</p> </div> <input type="file" id="fileInput" class="file-input" accept="image/*"> <div class="featured-examples"> <div class="example-item" data-example="1"> <img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例1"> </div> <div class="example-item" data-example="2"> <img src="https://images.unsplash.com/photo-1543852786-1cf6624b9987?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例2"> </div> <div class="example-item" data-example="3"> <img src="https://images.unsplash.com/photo-1533738363-b7f9aef128ce?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例3"> </div> <div class="example-item" data-example="4"> <img src="https://images.unsplash.com/photo-1526336024174-e58f5cdd8e13?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例4"> </div> </div> </div> <div class="preview-section"> <h2 class="section-title"><i class="fas fa-image"></i> 预览结果</h2> <div class="preview-container"> <div class="preview-box"> <div class="preview-placeholder"> <i class="fas fa-image" style="font-size: 3rem; margin-bottom: 15px;"></i> <p>处理后的图像将显示在这里</p> </div> <canvas id="originalCanvas"></canvas> <canvas id="resultCanvas"></canvas> <div class="loading" id="loading"> <div class="spinner"></div> <p>正在处理图像...</p> </div> </div> <div class="controls"> <div class="tolerance-control"> <div class="tolerance-label"> <span>抠图精度调节:</span> <span class="tolerance-value" id="toleranceValue">30</span> </div> <input type="range" min="1" max="100" value="30" class="slider" id="toleranceSlider"> <p style="font-size: 0.8rem; margin-top: 5px; opacity: 0.7;">值越小,抠图越精细(处理时间越长)</p> </div> <button class="btn" id="processBtn"><i class="fas fa-cogs"></i> 开始抠图</button> </div> <div class="result-actions"> <button class="btn" id="downloadBtn" disabled><i class="fas fa-download"></i> 下载结果</button> <button class="btn btn-outline" id="resetBtn"><i class="fas fa-redo"></i> 重置</button> </div> </div> </div> </div> <div class="info-box"> <h3><i class="fas fa-info-circle"></i> 使用说明</h3> <div class="info-content"> <div class="info-item"> <h4>如何获得最佳效果:</h4> <ul> <li>选择主体与背景对比度高的图片</li> <li>避免复杂背景或毛发等细节丰富的图像</li> <li>如果效果不理想,尝试调整抠图精度</li> <li>对于人像照片效果最佳</li> </ul> </div> <div class="info-item"> <h4>技术说明:</h4> <ul> <li>使用HTML5 Canvas实现纯前端处理</li> <li>基于智能颜色识别算法</li> <li>处理时间取决于图像大小和复杂度</li> <li>完全在浏览器中运行 - 不上传服务器</li> </ul> </div> </div> </div> </div> <footer> <p>© 2023 智能抠图工具 | 纯前端实现 | 无需上传服务器 | 保护您的隐私</p> </footer> <script> document.addEventListener('DOMContentLoaded', function() { // 获取DOM元素 const dropArea = document.getElementById('dropArea'); const fileInput = document.getElementById('fileInput'); const browseBtn = document.getElementById('browseBtn'); const processBtn = document.getElementById('processBtn'); const downloadBtn = document.getElementById('downloadBtn'); const resetBtn = document.getElementById('resetBtn'); const toleranceSlider = document.getElementById('toleranceSlider'); const toleranceValue = document.getElementById('toleranceValue'); const originalCanvas = document.getElementById('originalCanvas'); const resultCanvas = document.getElementById('resultCanvas'); const loading = document.getElementById('loading'); const previewPlaceholder = document.querySelector('.preview-placeholder'); let originalImage = null; let processedImage = null; // 设置事件监听器 browseBtn.addEventListener('click', () => fileInput.click()); fileInput.addEventListener('change', handleFileSelect); dropArea.addEventListener('dragover', handleDragOver); dropArea.addEventListener('dragleave', handleDragLeave); dropArea.addEventListener('drop', handleDrop); processBtn.addEventListener('click', processImage); downloadBtn.addEventListener('click', downloadResult); resetBtn.addEventListener('click', resetApp); toleranceSlider.addEventListener('input', updateTolerance); // 示例图片点击事件 document.querySelectorAll('.example-item').forEach(item => { item.addEventListener('click', function() { const exampleNum = this.getAttribute('data-example'); loadExample(exampleNum); }); }); // 更新容差值显示 function updateTolerance() { toleranceValue.textContent = toleranceSlider.value; } // 处理文件选择 function handleFileSelect(e) { const file = e.target.files[0]; if (file && file.type.match('image.*')) { loadImage(file); } } // 处理拖放 function handleDragOver(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.add('active'); } function handleDragLeave(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.remove('active'); } function handleDrop(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.remove('active'); const file = e.dataTransfer.files[0]; if (file && file.type.match('image.*')) { loadImage(file); } } // 加载图片 function loadImage(file) { const reader = new FileReader(); reader.onload = function(e) { originalImage = new Image(); originalImage.onload = function() { // 显示原始图片 displayOriginalImage(); processBtn.disabled = false; }; originalImage.src = e.target.result; }; reader.readAsDataURL(file); } // 加载示例图片 function loadExample(num) { const examples = { '1': 'https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80', '2': 'https://images.unsplash.com/photo-1543852786-1cf6624b9987?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80', '3': 'https://images.unsplash.com/photo-1533738363-b7f9aef128ce?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80', '4': 'https://images.unsplash.com/photo-1526336024174-e58f5cdd8e13?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80' }; originalImage = new Image(); originalImage.crossOrigin = "Anonymous"; originalImage.onload = function() { displayOriginalImage(); processBtn.disabled = false; }; originalImage.src = examples[num]; } // 显示原始图片 function displayOriginalImage() { const previewBox = document.querySelector('.preview-box'); previewPlaceholder.style.display = 'none'; // 设置canvas尺寸 const maxWidth = previewBox.clientWidth - 20; const maxHeight = previewBox.clientHeight - 20; let width = originalImage.width; let height = originalImage.height; if (width > maxWidth) { height = (maxWidth / width) * height; width = maxWidth; } if (height > maxHeight) { width = (maxHeight / height) * width; height = maxHeight; } originalCanvas.width = width; originalCanvas.height = height; resultCanvas.width = width; resultCanvas.height = height; const ctx = originalCanvas.getContext('2d'); ctx.clearRect(0, 0, width, height); ctx.drawImage(originalImage, 0, 0, width, height); originalCanvas.style.display = 'block'; } // 处理图像(抠图) function processImage() { if (!originalImage) return; // 显示加载状态 loading.style.display = 'flex'; downloadBtn.disabled = true; // 使用setTimeout让UI有机会更新 setTimeout(() => { try { const tolerance = parseInt(toleranceSlider.value); removeBackground(tolerance); // 显示结果 originalCanvas.style.display = 'none'; resultCanvas.style.display = 'block'; downloadBtn.disabled = false; } catch (error) { console.error('Error processing image:', error); alert('处理图像时出错: ' + error.message); } finally { loading.style.display = 'none'; } }, 100); } // 移除背景的核心算法 function removeBackground(tolerance) { const ctx = originalCanvas.getContext('2d'); const resultCtx = resultCanvas.getContext('2d'); // 获取图像数据 const imageData = ctx.getImageData(0, 0, originalCanvas.width, originalCanvas.height); const data = imageData.data; // 创建新图像数据(带透明通道) const newData = new ImageData(originalCanvas.width, originalCanvas.height); const newPixels = newData.data; // 假设图片中心点属于前景 const centerX = Math.floor(originalCanvas.width / 2); const centerY = Math.floor(originalCanvas.height / 2); const centerIndex = (centerY * originalCanvas.width + centerX) * 4; // 获取中心点颜色作为前景参考 const centerR = data[centerIndex]; const centerG = data[centerIndex + 1]; const centerB = data[centerIndex + 2]; // 处理每个像素 for (let i = 0; i < data.length; i += 4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; // 计算与中心点的颜色差异 const diff = Math.sqrt( Math.pow(r - centerR, 2) + Math.pow(g - centerG, 2) + Math.pow(b - centerB, 2) ); // 如果颜色差异在容差范围内,保留像素,否则设为透明 if (diff < tolerance) { newPixels[i] = r; newPixels[i + 1] = g; newPixels[i + 2] = b; newPixels[i + 3] = 255; // 不透明 } else { newPixels[i] = 0; newPixels[i + 1] = 0; newPixels[i + 2] = 0; newPixels[i + 3] = 0; // 完全透明 } } // 将新图像数据绘制到结果canvas resultCtx.putImageData(newData, 0, 0); } // 下载结果 function downloadResult() { if (!resultCanvas) return; const link = document.createElement('a'); link.download = '抠图结果.png'; link.href = resultCanvas.toDataURL('image/png'); link.click(); } // 重置应用 function resetApp() { // 重置所有状态 originalImage = null; processedImage = null; // 隐藏canvas originalCanvas.style.display = 'none'; resultCanvas.style.display = 'none'; // 显示占位符 previewPlaceholder.style.display = 'flex'; // 重置按钮状态 processBtn.disabled = true; downloadBtn.disabled = true; // 重置文件输入 fileInput.value = ''; } // 初始化 updateTolerance(); }); </script> </body> </html>
2025年06月23日
3 阅读
0 评论
0 点赞
2025-04-26
PDF搜索优化
<body> <div class="container"> <h1>PDF搜索</h1> <div class="control-panel"> <input type="text" id="searchInput" placeholder="输入关键词搜索..."> </div> <div class="progress-container"> <div class="progress-bar" id="progressBar"></div> </div> <div class="status-area" id="status"> 准备就绪,请输入关键词搜索PDF文件 </div> <div id="results"> <div class="no-results">没有找到PDF文件</div> </div> <div id="pdfPreview"> <div class="preview-header"> <h3 id="previewTitle"></h3> <button id="closePreview">×</button> </div> <iframe id="pdfViewer"></iframe> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const searchInput = document.getElementById('searchInput'); const resultsDiv = document.getElementById('results'); const statusDiv = document.getElementById('status'); const progressBar = document.getElementById('progressBar'); const pdfPreview = document.getElementById('pdfPreview'); const previewTitle = document.getElementById('previewTitle'); const pdfViewer = document.getElementById('pdfViewer'); const closePreview = document.getElementById('closePreview'); // 输入框事件 searchInput.addEventListener('input', filterFiles); // 关闭预览 closePreview.addEventListener('click', () => { pdfPreview.style.display = 'none'; }); // 从后端获取PDF文件列表 async function fetchFiles() { try { const response = await fetch('get-pdf-files.php'); // 后端API const data = await response.json(); if (data.success) { updateUI(data.files); } else { statusDiv.textContent = '获取文件失败,请重试'; } } catch (error) { statusDiv.textContent = '发生错误,请稍后再试'; console.error(error); } } // 过滤文件 function filterFiles() { const searchTerm = searchInput.value.trim().toLowerCase(); if (searchTerm === '') { statusDiv.textContent = '请输入关键词搜索'; return; } fetchFiles(); } function updateUI(files) { const filteredFiles = files.filter(file => file.name.toLowerCase().includes(searchInput.value.trim().toLowerCase())); if (filteredFiles.length === 0) { resultsDiv.innerHTML = '<div class="no-results">没有找到匹配的PDF文件</div>'; return; } const fileList = document.createElement('ul'); fileList.className = 'file-list'; filteredFiles.forEach(file => { const fileItem = document.createElement('li'); fileItem.className = 'file-item'; fileItem.innerHTML = ` <div class="file-info"> <div class="file-name">${file.name}</div> <div class="file-path">${file.path}</div> </div> <div class="file-size">${formatFileSize(file.size)}</div> `; fileItem.addEventListener('click', () => previewPDF(file)); fileList.appendChild(fileItem); }); resultsDiv.innerHTML = ''; resultsDiv.appendChild(fileList); } // 预览PDF文件 function previewPDF(file) { previewTitle.textContent = file.name; pdfViewer.src = file.url; // 预览链接 pdfPreview.style.display = 'block'; } // 格式化文件大小 function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const units = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return `${parseFloat((bytes / Math.pow(1024, i)).toFixed(2))} ${units[i]}`; } // 启动时获取文件 fetchFiles(); }); </script> </body><body> <div class="container"> <h1>PDF搜索</h1> <div class="control-panel"> <button id="selectFolderBtn" class="btn">选择文件夹</button> <input type="file" id="folderInput" webkitdirectory directory multiple hidden> <button id="importJsonBtn" class="btn">导入JSON</button> <button id="exportJsonBtn" class="btn">导出为JSON</button> <input type="file" id="jsonInput" accept=".json" hidden> <input type="text" id="searchInput" placeholder="输入至少3个字符搜索..." disabled> </div> <div class="status-area" id="status"> 准备就绪,请选择包含PDF的文件夹或导入JSON </div> <div id="results"> <div class="no-results">没有找到PDF文件</div> </div> <div id="pdfPreview"> <div class="preview-header"> <h3 id="previewTitle"></h3> <button id="closePreview">×</button> </div> <iframe id="pdfViewer"></iframe> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const selectFolderBtn = document.getElementById('selectFolderBtn'); const folderInput = document.getElementById('folderInput'); const searchInput = document.getElementById('searchInput'); const resultsDiv = document.getElementById('results'); const statusDiv = document.getElementById('status'); const pdfPreview = document.getElementById('pdfPreview'); const previewTitle = document.getElementById('previewTitle'); const pdfViewer = document.getElementById('pdfViewer'); const closePreview = document.getElementById('closePreview'); let currentPDFFiles = []; let searchTimeout = null; // 新增JSON文件input const jsonInput = document.getElementById('jsonInput'); // 尝试加载同路径的pdf_data.json fetch('pdf_data.json') .then(response => response.json()) .then(data => { currentPDFFiles = data; statusDiv.textContent = `已从JSON加载 ${data.length} 个PDF记录`; searchInput.disabled = false; displayFiles(data); }) .catch(() => { statusDiv.textContent = '本地未找到pdf_data.json,请选择文件夹或导入JSON'; }); // 导出为JSON function exportToJSON() { if (currentPDFFiles.length === 0) { statusDiv.textContent = '没有数据可以导出'; return; } const exportData = currentPDFFiles.map(file => ({ name: file.name, path: file.path, object: file.object, })); const dataStr = JSON.stringify(exportData, null, 2); const blob = new Blob([dataStr], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'pdf_export.json'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // 导入JSON处理 function handleJsonImport(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { try { const data = JSON.parse(e.target.result); currentPDFFiles = data; statusDiv.textContent = `已从JSON导入 ${data.length} 个PDF记录`; searchInput.disabled = false; displayFiles(data); } catch (error) { statusDiv.textContent = 'JSON文件格式错误'; } }; reader.readAsText(file); } // 修改预览函数处理缺少文件对象的情况 function previewPDF(file) { if (!file.fileObject) { statusDiv.textContent = '请重新选择文件夹以激活预览功能'; return; } previewTitle.textContent = file.name; pdfViewer.src = createObjectURL(file.fileObject); pdfPreview.style.display = 'block'; } // 显示文件列表(最多显示10条) function displayFiles(files) { if (files.length === 0) { resultsDiv.innerHTML = '<div class="no-results">没有找到匹配的PDF文件</div>'; return; } const displayCount = Math.min(files.length, 10); // 最多显示10条 statusDiv.textContent = `找到 ${files.length} 个PDF,显示前 ${displayCount} 个`; const fileList = document.createElement('ul'); fileList.className = 'file-list'; files.slice(0, 10).forEach(file => { const fileItem = document.createElement('li'); fileItem.className = 'file-item'; fileItem.innerHTML = ` <div class="file-info"> <div class="file-name">${file.name}</div> <div class="file-path">${file.path}</div> </div> `; fileItem.addEventListener('click', () => previewPDF(file)); fileList.appendChild(fileItem); }); resultsDiv.innerHTML = ''; resultsDiv.appendChild(fileList); } // 预览PDF文件 function previewPDF(file) { previewTitle.textContent = file.name; pdfViewer.src = URL.createObjectURL(file.fileObject); pdfPreview.style.display = 'block'; console.log('路径',pdfViewer.src); } // 重置状态 function resetState() { currentPDFFiles = []; searchInput.value = ''; searchInput.disabled = true; resultsDiv.innerHTML = '<div class="no-results">没有找到PDF文件</div>'; statusDiv.textContent = '准备就绪,请选择包含PDF的文件夹'; } // 处理文件夹选择 function handleFolderSelection(event) { const files = Array.from(event.target.files) .filter(file => file.name.toLowerCase().endsWith('.pdf')) .map(file => ({ name: file.name, path: file.webkitRelativePath || file.name, fileObject: file })); currentPDFFiles = files; if (files.length > 0) { statusDiv.textContent = `已加载 ${files.length} 个PDF文件`; searchInput.disabled = false; displayFiles(files); } else { statusDiv.textContent = '选择的文件夹中没有PDF文件'; searchInput.disabled = true; } } // 处理搜索输入(至少3个字符才搜索) function handleSearchInput() { clearTimeout(searchTimeout); const query = searchInput.value.trim().toLowerCase(); if (query.length < 3) { displayFiles(currentPDFFiles); return; } searchTimeout = setTimeout(() => { const filtered = currentPDFFiles.filter(file => file.name.toLowerCase().includes(query) || file.path.toLowerCase().includes(query) ); displayFiles(filtered); }, 300); } // 事件监听 document.getElementById('exportJsonBtn').addEventListener('click', exportToJSON); document.getElementById('importJsonBtn').addEventListener('click', () => jsonInput.click()); jsonInput.addEventListener('change', handleJsonImport); selectFolderBtn.addEventListener('click', () => folderInput.click()); folderInput.addEventListener('change', handleFolderSelection); searchInput.addEventListener('input', handleSearchInput); closePreview.addEventListener('click', () => { pdfPreview.style.display = 'none'; URL.revokeObjectURL(pdfViewer.src); // 释放内存 }); // 初始化 resetState(); }); </script> </body><body> <div class="container"> <h1>质量文件记录</h1> <div class="control-panel"> <button id="uploadExcelBtn" class="btn">上传Excel文件</button> <input type="file" id="excelInput" accept=".xlsx,.xls" hidden> <input type="text" id="searchInput" placeholder="输入至少3个字符搜索..."> </div> <div class="status-area" id="status"> 正在加载up文件夹中的文件... </div> <div id="results"> <div class="no-results">没有找到文件</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const uploadExcelBtn = document.getElementById('uploadExcelBtn'); const excelInput = document.getElementById('excelInput'); const searchInput = document.getElementById('searchInput'); const resultsDiv = document.getElementById('results'); const statusDiv = document.getElementById('status'); let currentFiles = []; let searchTimeout = null; // 从up文件夹加载文件 function loadFilesFromUpFolder() { fetch('up/') .then(response => response.text()) .then(text => { // 解析HTML获取文件列表 const parser = new DOMParser(); const htmlDoc = parser.parseFromString(text, 'text/html'); const links = htmlDoc.querySelectorAll('a[href]'); currentFiles = Array.from(links) .filter(link => !link.href.endsWith('/')) .map(link => ({ name: link.href.split('/').pop(), url: link.href })); if (currentFiles.length > 0) { statusDiv.textContent = `找到 ${currentFiles.length} 个文件`; displayFiles(currentFiles); } else { statusDiv.textContent = 'up文件夹中没有文件'; resultsDiv.innerHTML = '<div class="no-results">up文件夹中没有文件</div>'; } }) .catch(error => { statusDiv.textContent = '无法访问up文件夹: ' + error.message; resultsDiv.innerHTML = '<div class="no-results">无法访问up文件夹</div>'; }); } // 处理Excel上传 function handleExcelUpload(event) { const file = event.target.files[0]; if (!file) return; // 1. 文件类型校验 if (!['.xlsx', '.xls'].some(ext => file.name.endsWith(ext))) { statusDiv.textContent = '仅支持.xlsx/.xls格式文件'; return; } // 2. 添加加载状态 statusDiv.textContent = '解析中...'; // 3. 使用FileReader读取文件内容 const reader = new FileReader(); reader.onload = (e) => { try { // 4. 解析Excel数据(需安装xlsx库) const data = new Uint8Array(e.target.result); const workbook = XLSX.read(data, { type: 'array' }); const firstSheet = workbook.Sheets[workbook.SheetNames[0]]; const jsonData = XLSX.utils.sheet_to_json(firstSheet); // 5. 触发回调传递解析结果 if (typeof this.onExcelParsed === 'function') { this.onExcelParsed({ raw: file, parsedData: jsonData, fileName: file.name }); } // 6. 更新界面状态 statusDiv.textContent = `解析完成: ${file.name}`; currentFiles.push({ name: file.name, url: URL.createObjectURL(file), data: jsonData // 存储解析结果 }); displayFiles(currentFiles); } catch (error) { statusDiv.textContent = `解析失败: ${error.message}`; } }; // 7. 错误处理 reader.onerror = () => { statusDiv.textContent = '文件读取失败'; }; reader.readAsArrayBuffer(file); } // 显示文件列表 function displayFiles(files) { if (files.length === 0) { resultsDiv.innerHTML = '<div class="no-results">没有找到匹配的文件</div>'; return; } const fileList = document.createElement('ul'); fileList.className = 'file-list'; files.forEach(file => { const fileItem = document.createElement('li'); fileItem.className = 'file-item'; fileItem.innerHTML = ` <div class="file-info"> <div class="file-name">${file.name}</div> 下载 </div> `; fileList.appendChild(fileItem); }); resultsDiv.innerHTML = ''; resultsDiv.appendChild(fileList); } // 处理搜索输入 function handleSearchInput() { clearTimeout(searchTimeout); const query = searchInput.value.trim().toLowerCase(); if (query.length < 3) { displayFiles(currentFiles); return; } searchTimeout = setTimeout(() => { const filtered = currentFiles.filter(file => file.name.toLowerCase().includes(query) ); displayFiles(filtered); }, 300); } // 事件监听 uploadExcelBtn.addEventListener('click', () => excelInput.click()); excelInput.addEventListener('change', handleExcelUpload); searchInput.addEventListener('input', handleSearchInput); // 初始化 - 自动加载up文件夹 loadFilesFromUpFolder(); }); </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script> </body>
2025年04月26日
6 阅读
0 评论
0 点赞
2025-04-23
javascript运算问题
在js里 "+"是拼接字符串的,而不是逻辑运算符; 数据类型问题: 如果变量是字符串类型,+操作会变成字符串拼接而非数值相加4 建议使用Number()或parseFloat()进行显式转换: javascript Copy Code const planRate = (Number(completedQuantity) / (Number(row.total_quantity) + Number(row.urgent_order_quantity))) * 100 除零错误防护: 当分母为0时会导致Infinity结果46 应增加防护逻辑: javascript Copy Code const denominator = Number(row.total_quantity) + Number(row.urgent_order_quantity); const planRate = denominator !== 0 ? (completedQuantity / denominator) * 100 : 0; 精度处理建议: 使用toFixed()控制小数位数6 javascript Copy Code const planRate = denominator !== 0 ? ((completedQuantity / denominator) * 100).toFixed(2) : 0; 特殊值处理: 建议增加null/undefined检测4 javascript Copy Code const safeValue = (val) => isNaN(Number(val)) ? 0 : Number(val); const denominator = safeValue(row.total_quantity) + safeValue(row.urgent_order_quantity); 公式优化建议: 可参考完成率的标准计算公式:(已完成量/计划总量)×100%6 紧急订单量是否应计入分母需根据业务逻辑确认16 建议使用Chrome开发者工具的Console面板或Node.js环境进行分步调试,使用console.log输出中间变量值检查问题根源4。
2025年04月23日
4 阅读
0 评论
0 点赞
1
...
3
4
5
0:00