| | |
| | | 不可修改=Not Editable |
| | | 重要!一般用于后台登入=Important: usually used for admin login |
| | | 当前角色不可更改为其它角色=Current role cannot be changed |
| | | 手机号:=Phone: |
| | | 用户名:=Username: |
| | | 手机号\:=Phone: |
| | | 用户名\:=Username: |
| | | 输入手机号=Enter phone number |
| | | 输入用户名=Enter username |
| | | 重置密码=Reset Password |
| | |
| | | ConveyorCommand分段长度=Conveyor Command Segment Length |
| | | 站点点最大任务数量上限=Max Tasks Per Station |
| | | Stations点最大Task数量上限=Max Tasks Per Station |
| | | 冷却到: -=Cooldown Until: - |
| | | 最近错误: -=Latest Error: - |
| | | 冷却到\:-=Cooldown Until: - |
| | | 最近错误\:-=Latest Error: - |
| | | 故障切换开启=Failover Enabled |
| | | Failover开启=Failover Enabled |
| | | 额度切换开启=Quota Switch Enabled |
| | |
| | | Success 0 / Failed 0 / 连续Failed 0=Success 0 / Failed 0 / Consecutive Failures 0 |
| | | Success 7 / Failed 2 / 连续Failed 0=Success 7 / Failed 2 / Consecutive Failures 0 |
| | | Success 8 / Failed 0 / 连续Failed 0=Success 8 / Failed 0 / Consecutive Failures 0 |
| | | 必填,例如: https://dashscope.aliyuncs.com/compatible-mode/v1=Required, for example: https://dashscope.aliyuncs.com/compatible-mode/v1 |
| | | Required,例如: https://dashscope.aliyuncs.com/compatible-mode/v1=Required, for example: https://dashscope.aliyuncs.com/compatible-mode/v1 |
| | | 最近错误:=Latest Error: |
| | | 冷却到:=Cooldown Until: |
| | | 必填,例如\: https\://dashscope.aliyuncs.com/compatible-mode/v1=Required, for example: https://dashscope.aliyuncs.com/compatible-mode/v1 |
| | | Required,例如\: https\://dashscope.aliyuncs.com/compatible-mode/v1=Required, for example: https://dashscope.aliyuncs.com/compatible-mode/v1 |
| | | 最近错误\:=Latest Error: |
| | | 冷却到\:=Cooldown Until: |
| | | D.空桶/空栈板=D. Empty Tote/Pallet |
| | | E.出入专用轨道=E. Dedicated IO Rail |
| | | W.穿梭车母轨道=W. Shuttle Main Rail |
| | |
| | | 阿里百炼-kimi-k2.5=Alibaba Bailian - kimi-k2.5 |
| | | 阿里百炼-glm-5=Alibaba Bailian - glm-5 |
| | | 硅基流动=SiliconFlow |
| | | 提示=Prompt |
| | | 尝试=Attempt |
| | | 错误=Error |
| | | 空闲=Idle |
| | | 无物=Unloaded |
| | | 工作类型=Work Type |
| | | 能出=Outbound Enabled |
| | | 能入=Inbound Enabled |
| | | 文件数=File Count |
| | | 类型\:=Type: |
| | | 设备编号\:=Device No.: |
| | | 文件数\:=File Count: |
| | | 日志详情 -=Log Details - |
| | | 日志可视化 -=Device Logs - |
| | | 已删除=Deleted |
| | | 老项目仍可继续使用这份硬件信息 JSON 申请许可证。=Legacy projects can still use this hardware JSON to apply for a license. |
| | | 请求码中已包含项目名称,直接发给许可证服务端即可。=The request code already contains the project name and can be sent directly to the license service. |
| | | 暂无路由配置=No route configuration available |
| | | 点击右上角“新增路由”创建第一条配置=Click "Add Route" in the upper-right corner to create the first route. |
| | | 保存成功=Saved successfully |
| | | 保存失败=Save failed |
| | | 测试成功=Test succeeded |
| | | 测试失败=Test failed |
| | | 测试中...=Testing... |
| | | 导出成功=Export succeeded |
| | | 导出失败=Export failed |
| | | 导入确认=Import Confirmation |
| | | 导入失败=Import failed |
| | | 覆盖导入=Overwrite Import |
| | | 合并导入=Merge Import |
| | | 读取文件失败=Failed to read file |
| | | JSON 格式不正确=Invalid JSON format |
| | | 未找到可导入的 routes=No importable routes found |
| | | 请选择导入方式:覆盖导入会先清空现有路由;点击“合并导入”则按ID更新或新增。=Choose an import mode: overwrite import clears existing routes first; merge import updates by ID or adds new routes. |
| | | 当前是未保存配置,测试通过后仍需先保存才会生效=This configuration is not saved yet. It still needs to be saved after a successful test to take effect. |
| | | 复制失败,请手动复制=Copy failed. Please copy it manually. |
| | | 没有可复制内容=Nothing to copy |
| | | 已复制=Copied |
| | | API Key 为空=API key is empty |
| | | API Key 已复制=API key copied |
| | | 日志加载失败=Failed to load logs |
| | | 删除成功=Deleted successfully |
| | | 删除失败=Delete failed |
| | | 已清除冷却=Cooldown cleared |
| | | 已清空=Cleared |
| | | 清空日志=Clear Logs |
| | | 清空失败=Clear failed |
| | | 确定清空全部LLM调用日志吗?=Are you sure you want to clear all LLM call logs? |
| | | 确定删除该路由吗?=Are you sure you want to delete this route? |
| | | 确定删除该日志吗?=Are you sure you want to delete this log? |
| | | 导入完成:新增=Import completed: added |
| | | 导入异常明细(最多20条)=Import exception details (up to 20 items) |
| | | 状态码=Status Code |
| | | 场景=Scene |
| | | 模型=Model |
| | | 路由=Route |
| | | 结果=Result |
| | | 耗时(ms)=Latency (ms) |
| | | 耗时\:=Latency: |
| | | 结果\:=Result: |
| | | 模型\:=Model: |
| | | 路由\:=Route: |
| | | 场景\:=Scene: |
| | | 时间\:=Time: |
| | | 状态码\:=Status Code: |
| | | 请求\:=Request: |
| | | 响应\:=Response: |
| | | 返回片段\:=Response Snippet: |
| | | 最近错误\:=Latest Error: |
| | | 冷却到\:=Cooldown Until: |
| | | regex\:^成功\s*(\d+)\s*\/\s*失败\s*(\d+)\s*\/\s*连续失败\s*(\d+)$=Success $1 / Failed $2 / Consecutive Failures $3 |
| | | regex\:^时间\:\s*(.+)$=Time: $1 |
| | | regex\:^状态码\:\s*(.+)$=Status Code: $1 |
| | | regex\:^耗时\:\s*(.+)$=Latency: $1 |
| | | regex\:^结果\:\s*(.+)$=Result: $1 |
| | | regex\:^路由\:\s*(.+)$=Route: $1 |
| | | regex\:^模型\:\s*(.+)$=Model: $1 |
| | | regex\:^返回片段\:\s*(.+)$=Response Snippet: $1 |
| | | regex\:^请求\:\s*(.+)$=Request: $1 |
| | | regex\:^响应\:\s*(.+)$=Response: $1 |
| | | regex\:^最近错误\:\s*(.+)$=Latest Error: $1 |
| | | regex\:^冷却到\:\s*(.+)$=Cooldown Until: $1 |
| | | WCS AI 助手=WCS AI Assistant |
| | | AI 深度思考=AI Deep Thinking |
| | | 系统巡检、异常问答、历史会话=System inspection, anomaly Q&A, and session history |
| | | 连接中=Connecting |
| | | 一键巡检=One-click Inspection |
| | | 巡检当前系统=Inspect Current System |
| | | 新会话=New Session |
| | | 选择历史会话=Select Session History |
| | | 向 AI 助手提问=Ask the AI Assistant |
| | | 支持连续追问、历史会话切换,以及 AI 思考过程折叠展示。=Supports follow-up questions, session switching, and collapsible AI reasoning. |
| | | 未绑定历史会话=No history session bound |
| | | 新建会话,等待首条消息=Create a new session and wait for the first message |
| | | 输入问题,或先执行一次巡检=Enter a question, or run an inspection first |
| | | AI 正在生成回复...=AI is generating a response... |
| | | AI 助手=AI Assistant |
| | | 用户=User |
| | | WCS 诊断回复=WCS Diagnostic Reply |
| | | 问题输入=Question Input |
| | | 定位堆垛机异常=Locate Crane Anomalies |
| | | 分析堵塞与积压=Analyze Blockages and Backlogs |
| | | 追问最近告警=Ask About Recent Alarms |
| | | 让 AI 主动梳理设备、任务和日志,给出一轮完整巡检。=Let AI review devices, tasks, and logs proactively and provide a full inspection. |
| | | 让 AI 优先关注工位堵塞、任务堆积和节拍异常。=Let AI focus on station blockages, task backlogs, and rhythm anomalies first. |
| | | 把最近异常事件压缩成可执行排查建议。=Condense recent anomalies into actionable troubleshooting steps. |
| | | 帮我定位当前堆垛机相关的异常风险,按可能性从高到低列出。=Identify current crane-related risks and list them by likelihood. |
| | | 帮我总结最近最值得关注的异常,并给出下一步排查动作。=Summarize the most important recent anomalies and suggest next troubleshooting steps. |
| | | 结合近期日志与任务状态,判断是否存在堆垛机链路异常。=Determine whether there is any crane workflow anomaly based on recent logs and task status. |
| | | 例如:最近哪个设备最值得优先排查?异常是否和堆垛机任务、工位堵塞或日志波动有关?=For example: which device should be checked first? Are the anomalies related to crane tasks, station blockage, or log fluctuation? |
| | | 请重点分析当前是否存在工位堵塞、任务积压或节拍异常。=Please focus on whether there are station blockages, task backlogs, or rhythm anomalies. |
| | | 删除会话失败=Failed to delete session |
| | | 加载 AI 会话列表失败=Failed to load AI session list |
| | | 加载会话历史失败=Failed to load session history |
| | | 诊断中=Diagnosing |
| | | 未命名会话=Untitled Session |
| | | 最近更新=Updated Recently |
| | | 刚刚创建=Just created |
| | | 刚刚更新=Just updated |
| | | 会话已绑定=Session Bound |
| | | 临时会话=Temporary Session |
| | | Enter 发送,Shift+Enter 换行=Press Enter to send, Shift+Enter for a new line |
| | | regex\:^(\d+)\s*个会话$=$1 sessions |
| | | regex\:^(\d+)\s*分钟前$=$1 minute(s) ago |
| | | regex\:^(\d+)\s*小时前$=$1 hour(s) ago |
| | | 补发结果=Retry Result |
| | | 补发失败=Retry failed |
| | | 当前筛选条件下没有通知日志=No notification logs match the current filters |
| | | 获取通知队列失败=Failed to load notification queue |
| | | 获取通知概览失败=Failed to load notification overview |
| | | 获取通知日志失败=Failed to load notification logs |
| | | 请求失败=Request failed |
| | | 请选择要补发的队列通知=Please select queue notifications to retry |
| | | 请选择要补发的通知日志=Please select notification logs to retry |
| | | 确定按该日志重新补发通知吗?=Retry this notification based on the selected log? |
| | | 确定补发该队列通知吗?=Retry this queued notification? |
| | | 确定批量补发选中的队列通知吗?=Retry the selected queued notifications in batch? |
| | | 确定批量补发选中的通知日志吗?=Retry the selected notification logs in batch? |
| | | 确定执行手动补发吗?=Are you sure you want to retry manually? |
| | | 上级任务号=Parent Task No. |
| | | 接口响应=API Response |
| | | 通知报文=Notification Payload |
| | | 待发送=Pending |
| | | 发送日志=Send Logs |
| | | regex\:^已选\s*(\d+)\s*条$=Selected $1 item(s) |
| | | regex\:^当前页签:\s*(.+)$=Current Tab: $1 |
| | | 调色盘=Palette |
| | | 恢复默认=Restore Default |
| | | 保存后,新打开的监控地图会直接读取 Redis 配置;已打开页面刷新后即可生效。=After saving, newly opened monitoring maps will read the Redis configuration directly. Refresh already opened pages to apply it. |
| | | regex\:^默认值:\s*(.+)$=Default: $1 |
| | | 操作区域=Action Area |
| | | regex\:^层:\s*(.+)$=Level: $1 |
| | | regex\:^排:\s*(.+)$=Row: $1 |
| | | regex\:^列:\s*(.+)$=Bay: $1 |
| | | regex\:^库位号:\s*(.+)$=Location No.: $1 |
| | | regex\:^库位状态:\s*(.+)$=Location Status: $1 |
| | | regex\:^站点:\s*(.+)$=Station: $1 |
| | | regex\:^工作号:\s*(.+)$=Work No.: $1 |
| | | regex\:^工作类型:\s*(.+)$=Work Type: $1 |
| | | regex\:^工作状态:\s*(.+)$=Work Status: $1 |
| | | regex\:^源站:\s*(.+)$=Source Station: $1 |
| | | regex\:^目标站:\s*(.+)$=Target Station: $1 |
| | | regex\:^源库位:\s*(.+)$=Source Location: $1 |
| | | regex\:^目标库位:\s*(.+)$=Target Location: $1 |
| | | regex\:^自动:\s*(.+)$=Auto: $1 |
| | | regex\:^有物:\s*(.+)$=Loaded: $1 |
| | | regex\:^能入:\s*(.+)$=Inbound Enabled: $1 |
| | | regex\:^能出:\s*(.+)$=Outbound Enabled: $1 |
| | | 地图加载失败=Failed to load map |
| | | 楼层信息加载失败=Failed to load floor information |
| | | 站点详情加载失败=Failed to load station details |
| | | 双工位=Dual Station |
| | | regex\:^设备\s*(.+)$=Device $1 |
| | | regex\:^区域\s*(.+)$=Area $1 |
| | | regex\:^出库站点\s*\((\d+)\)$=Outbound Stations ($1) |
| | | 共=Total |
| | | 跳转时间=Jump Time |
| | | 选择时间=Select Time |
| | | 压缩生成进度=Compression Progress |
| | | 下载接收进度=Download Receive Progress |
| | | 日期选择=Date Selection |
| | | 选中日期=Selected Date |
| | | 设备类型=Device Type |
| | | 起始序号=Start Offset |
| | | 最大文件=Max Files |
| | | 设备列表=Device List |
| | | 暂无数据,请先选择日期=No data. Please select a date first. |
| | | 播放=Play |
| | | 暂停=Pause |
| | | 重置=Reset |
| | | 跳转=Jump |
| | | 倍速=Speed |
| | | regex\:^共\s*(\d+)\s*个设备$=Total $1 devices |
| | | regex\:^下载\((.+)\)$=Download ($1) |
| | | regex\:^可视化\((.+)\)$=Visualize ($1) |
| | | regex\:^未知设备类型\:\s*(.+)$=Unknown device type: $1 |
| | | 不在定位=Off Position |
| | | 在定位=At Position |
| | | 初始化失败=Initialization failed |
| | | 加载日期失败=Failed to load dates |
| | | 加载设备失败=Failed to load devices |
| | | 加载数据中...=Loading data... |
| | | 没有找到日志数据=No log data found |
| | | 目标时间超出日志范围,已跳转至结束时间=Target time exceeds the log range. Moved to the end time. |
| | | 请输入设备编号=Please enter the device number |
| | | 请选择设备类型=Please select a device type |
| | | 数据已全部加载=All data loaded |
| | | 无任务=No Task |
| | | 下载失败或未找到日志=Download failed or logs not found |
| | | 已到达日志末尾,无法到达目标时间=Reached the end of logs and cannot jump to the target time |
| | | 已跳转至目标时间=Jumped to the target time |
| | | 正在跳转至目标时间 (加载中)...=Jumping to the target time (loading)... |
| | | 保存请求异常=Save request exception |
| | | 加载请求异常=Load request exception |
| | | regex\:^保存失败\:\s*(.+)$=Save failed: $1 |
| | | regex\:^加载数据失败\:\s*(.+)$=Failed to load data: $1 |
| | | 该关联已存在=This mapping already exists |
| | | 确定删除该关联吗?=Are you sure you want to delete this mapping? |
| | | regex\:^已建立关联\:\s*站点\s*(.+)$=Mapping created: Station $1 |
| | | 该绑定已存在=This binding already exists |
| | | 请输入区域编码和名称=Please enter the area code and name |
| | | 区域已存在=Area already exists |
| | | regex\:^已建立绑定\:\s*站点\s*(.+)$=Binding created: Station $1 |
| | | 保存站点颜色配置失败=Failed to save station color configuration |
| | | 加载站点颜色配置失败=Failed to load station color configuration |
| | | 颜色格式已自动修正为十六进制=Color format has been normalized to hexadecimal automatically |
| | | 已恢复默认颜色=Default colors restored |
| | | 站点颜色配置已保存=Station color configuration saved |
| | | 登录失败=Login failed |
| | | 确定执行一键激活吗?=Are you sure you want to activate now? |
| | | 系统登录=System Login |
| | | 系统配置信息=System Configuration |
| | | 对接WMS、设备与业务规则=Integrates WMS, devices, and business rules |
| | | 统一编排现场执行任务=Unified orchestration of on-site execution tasks |
| | | 请输入账号和密码进入系统。=Please enter your account and password to access the system. |
| | | 将许可证服务端返回的 license 字段完整粘贴到这里。=Paste the full license field returned by the license service here. |
| | | 许可证 Base64=License Base64 |
| | | 自动化立体仓库与智能物流系统解决方案=Automated AS/RS and intelligent logistics system solutions |
| | | 作业、设备、日志全链路留痕=End-to-end traceability across jobs, devices, and logs |
| | | WCS系统让设备调度、任务执行与现场监控保持在同一套业务链路中。=The WCS keeps device scheduling, task execution, and on-site monitoring within the same business workflow. |
| | | 角色管理=Role Management |
| | | 权限管理=Permission Management |
| | | 菜单列表=Menu List |
| | | 菜单等级=Menu Level |
| | | 父级菜单=Parent Menu |
| | | 请输入编码=Please enter code |
| | | 请输入名称=Please enter name |
| | | 请选择上级=Please select parent |
| | | 请输入菜单编码=Please enter menu code |
| | | 请输入菜单名称=Please enter menu name |
| | | 请输入排序=Please enter sort order |
| | | 请选择类型=Please select type |
| | | 请选择上级菜单=Please select parent menu |
| | | 请选择状态=Please select status |
| | | 请输入接口地址=Please enter API URL |
| | | 请输入权限名称=Please enter permission name |
| | | 请选择所属菜单=Please select menu |
| | | 菜单查询失败=Menu query failed |
| | | 菜单详情加载失败=Failed to load menu details |
| | | 权限加载失败=Failed to load permissions |
| | | 权限树加载失败=Failed to load permission tree |
| | | 权限回显失败=Failed to load assigned permissions |
| | | 权限保存失败=Failed to save permissions |
| | | 角色查询失败=Role query failed |
| | | 角色加载失败=Failed to load roles |
| | | 确定删除选中角色吗?=Delete selected roles? |
| | | 确定删除选中凭证吗?=Delete selected credentials? |
| | | # Playwright audit supplement |
| | | 列设置=Column Settings |
| | | 创建者=Creator |
| | | 主要=Primary |
| | | 编 号=ID |
| | | *编 号=*ID |
| | | 异 常 码=Error Code |
| | | 异 常=Error |
| | | 状 态=Status |
| | | 工 作 号=Work No. |
| | | 备 注=Remarks |
| | | 作 业=Operation |
| | | 命 令=Command |
| | | 目 标 站=Target Station |
| | | 源 站=Source Station |
| | | 源 站 点=Source Station |
| | | 源 库 位=Source Location |
| | | 条 码=Barcode |
| | | 基准排=Base Row |
| | | 基准排-code=Base Row Code |
| | | 基准列=Base Bay |
| | | 基准列-code=Base Bay Code |
| | | 实 现 类=Implementation Class |
| | | 日志ID=Log ID |
| | | 平台密钥=Platform Key |
| | | Time戳=Timestamp |
| | | Exception内容=Exception Content |
| | | Menu列表=Menu List |
| | | 展开All=Expand All |
| | | Permissions管理=Permission Management |
| | | 凭证记录=Credential Records |
| | | 标 识=Identifier |
| | | 字 典 值=Dictionary Value |
| | | 字典文本=Dictionary Text |
| | | 是否Delete=Deleted |
| | | 租 户=Tenant |
| | | 账 号=Account |
| | | 密 码=Password |
| | | 昵 称=Nickname |
| | | 头 像=Avatar |
| | | 工 号=Employee No. |
| | | 性 别=Gender |
| | | 手 机 号=Mobile No. |
| | | 邮 箱=Email |
| | | Email验证=Email Verified |
| | | 所属部门=Department |
| | | 真实姓名=Real Name |
| | | 身份证号=ID Card No. |
| | | 出生日期=Birth Date |
| | | 个人简介=Biography |
| | | 所属机构=Organization |
| | | *角 色=*Role |
| | | 已设置Password=Password Set |
| | | Virtual Device初始化Status=Virtual Device Initialization Status |
| | | Please enter电梯中转点=Please enter the elevator transfer point |
| | | Role管理=Role Management |
| | | 展开面板=Expand Panel |
| | | 收起Actions=Collapse Actions |
| | | 信息=Information |
| | | OKExportExcel吗=Export to Excel? |
| | | 全选=Select All |
| | | 至=to |
| | | regex\:^Success\\s*(\\d+)\\s*/\\s*Failed\\s*(\\d+)\\s*/\\s*连续Failed\\s*(\\d+)$=Success $1 / Failed $2 / Consecutive Failures $3 |
| | | regex\:^(\\d{1,2})日$=Day $1 |
| | | regex\:^\\*[\\s ]*编[\\s ]*号$=*ID |
| | | regex\:^编[\\s ]*号$=ID |
| | | regex\:^异[\\s ]*常$=Error |
| | | regex\:^状[\\s ]*态$=Status |
| | | regex\:^工[\\s ]*作[\\s ]*号$=Work No. |
| | | regex\:^备[\\s ]*注$=Remarks |
| | | regex\:^作[\\s ]*业$=Operation |
| | | regex\:^命[\\s ]*令$=Command |
| | | regex\:^目[\\s ]*标[\\s ]*站$=Target Station |
| | | regex\:^源[\\s ]*站[\\s ]*点$=Source Station |
| | | regex\:^源[\\s ]*站$=Source Station |
| | | regex\:^源[\\s ]*库[\\s ]*位$=Source Location |
| | | regex\:^条[\\s ]*码$=Barcode |
| | | regex\:^账[\\s ]*号$=Account |
| | | regex\:^密[\\s ]*码$=Password |
| | | regex\:^昵[\\s ]*称$=Nickname |
| | | regex\:^头[\\s ]*像$=Avatar |
| | | regex\:^工[\\s ]*号$=Employee No. |
| | | regex\:^性[\\s ]*别$=Gender |
| | | regex\:^邮[\\s ]*箱$=Email |
| | | regex\:^标[\\s ]*识$=Identifier |
| | | regex\:^租[\\s ]*户$=Tenant |
| | | regex\:^\\*[\\s ]*角[\\s ]*色$=*Role |
| | |
| | | return result; |
| | | } |
| | | |
| | | fieldMeta = [ |
| | | { |
| | | field: 'id', |
| | | columnName: 'id', |
| | | label: 'ID', |
| | | tableProp: 'id', |
| | | exportField: 'id', |
| | | kind: 'text', |
| | | valueType: 'number', |
| | | required: true, |
| | | primaryKey: true, |
| | | searchable: false, |
| | | sortable: true, |
| | | textarea: false, |
| | | minWidth: 90, |
| | | enumOptions: [], |
| | | foreignQuery: '', |
| | | checkboxActiveRaw: '1', |
| | | checkboxInactiveRaw: '0' |
| | | }, |
| | | { |
| | | field: 'name', |
| | | columnName: 'name', |
| | | label: '名称', |
| | | tableProp: 'name', |
| | | exportField: 'name', |
| | | kind: 'text', |
| | | valueType: 'string', |
| | | required: true, |
| | | primaryKey: false, |
| | | searchable: false, |
| | | sortable: false, |
| | | textarea: false, |
| | | minWidth: 180, |
| | | dialogSpan: 12, |
| | | enumOptions: [], |
| | | foreignQuery: '', |
| | | checkboxActiveRaw: 'Y', |
| | | checkboxInactiveRaw: 'N' |
| | | }, |
| | | { |
| | | field: 'code', |
| | | columnName: 'code', |
| | | label: '编码', |
| | | tableProp: 'code', |
| | | exportField: 'code', |
| | | kind: 'text', |
| | | valueType: 'string', |
| | | required: true, |
| | | primaryKey: false, |
| | | searchable: true, |
| | | sortable: false, |
| | | textarea: false, |
| | | minWidth: 180, |
| | | dialogSpan: 12, |
| | | enumOptions: [], |
| | | foreignQuery: '', |
| | | checkboxActiveRaw: 'Y', |
| | | checkboxInactiveRaw: 'N' |
| | | }, |
| | | { |
| | | field: 'value', |
| | | columnName: 'value', |
| | | label: '对应值', |
| | | tableProp: 'value', |
| | | exportField: 'value', |
| | | kind: 'text', |
| | | valueType: 'string', |
| | | required: true, |
| | | primaryKey: false, |
| | | searchable: false, |
| | | sortable: false, |
| | | textarea: false, |
| | | minWidth: 220, |
| | | dialogSpan: 24, |
| | | enumOptions: [], |
| | | foreignQuery: '', |
| | | checkboxActiveRaw: 'Y', |
| | | checkboxInactiveRaw: 'N' |
| | | }, |
| | | { |
| | | field: 'type', |
| | | columnName: 'type', |
| | | label: '类型', |
| | | tableProp: 'type$', |
| | | exportField: 'type$', |
| | | kind: 'enum', |
| | | valueType: 'number', |
| | | required: true, |
| | | primaryKey: false, |
| | | searchable: false, |
| | | sortable: false, |
| | | textarea: false, |
| | | minWidth: 120, |
| | | dialogSpan: 12, |
| | | enumOptions: [ |
| | | { rawValue: '1', label: 'String' }, |
| | | { rawValue: '2', label: 'JSON' } |
| | | ], |
| | | foreignQuery: '', |
| | | checkboxActiveRaw: '1', |
| | | checkboxInactiveRaw: '0' |
| | | }, |
| | | { |
| | | field: 'status', |
| | | columnName: 'status', |
| | | label: '状态', |
| | | tableProp: 'status$', |
| | | exportField: 'status$', |
| | | kind: 'enum', |
| | | valueType: 'number', |
| | | required: true, |
| | | primaryKey: false, |
| | | searchable: false, |
| | | sortable: false, |
| | | textarea: false, |
| | | minWidth: 120, |
| | | dialogSpan: 12, |
| | | enumOptions: [ |
| | | { rawValue: '1', label: '正常' }, |
| | | { rawValue: '0', label: '禁用' } |
| | | ], |
| | | foreignQuery: '', |
| | | checkboxActiveRaw: '1', |
| | | checkboxInactiveRaw: '0' |
| | | }, |
| | | { |
| | | field: 'selectType', |
| | | columnName: 'select_type', |
| | | label: '筛选类型', |
| | | tableProp: 'selectType', |
| | | exportField: 'selectType', |
| | | kind: 'text', |
| | | valueType: 'string', |
| | | required: false, |
| | | primaryKey: false, |
| | | searchable: true, |
| | | sortable: false, |
| | | textarea: false, |
| | | minWidth: 140, |
| | | dialogSpan: 24, |
| | | enumOptions: [], |
| | | foreignQuery: '', |
| | | checkboxActiveRaw: 'Y', |
| | | checkboxInactiveRaw: 'N' |
| | | } |
| | | ]; |
| | | |
| | | function isEmptyValue(value) { |
| | | return value === null || value === undefined || value === ''; |
| | | } |
| | |
| | | } |
| | | |
| | | function isSearchableField(field) { |
| | | return !!field && field.kind !== 'image' && !field.textarea; |
| | | return !!field && field.searchable !== false && field.kind !== 'image' && !field.textarea; |
| | | } |
| | | |
| | | function isSortableField(field) { |
| | | if (!field) { |
| | | return false; |
| | | } |
| | | if (field.sortable === true) { |
| | | return true; |
| | | } |
| | | if (field.sortable === false) { |
| | | return false; |
| | | } |
| | | if (field.primaryKey) { |
| | |
| | | mode: 'create', |
| | | submitting: false |
| | | }, |
| | | tableHeight: 420, |
| | | layoutTimer: null, |
| | | tableResizeHandler: null, |
| | | dialogForm: createFormDefaults(), |
| | |
| | | }; |
| | | }); |
| | | }, |
| | | tableHeight: function () { |
| | | return this.advancedFiltersVisible && this.hasAdvancedFilters |
| | | ? 'calc(100vh - 390px)' |
| | | : 'calc(100vh - 300px)'; |
| | | }, |
| | | formTarget: function () { |
| | | return this.dialogForm; |
| | | }, |
| | | displayTarget: function () { |
| | | return this.dialogDisplay; |
| | | }, |
| | | isDialogReadonly: function () { |
| | | return this.dialog.mode === 'detail'; |
| | | } |
| | | }, |
| | | created: function () { |
| | |
| | | } |
| | | }, |
| | | methods: $.extend({}, sharedMethods, { |
| | | calculateTableHeight: function () { |
| | | var viewportHeight = window.innerHeight || document.documentElement.clientHeight || 860; |
| | | var tableWrap = this.$refs.tableWrap; |
| | | var pagerBar = this.$refs.pagerBar; |
| | | if (!tableWrap) { |
| | | this.tableHeight = Math.max(360, viewportHeight - (this.advancedFiltersVisible ? 360 : 300)); |
| | | return; |
| | | } |
| | | var tableTop = tableWrap.getBoundingClientRect().top; |
| | | var pagerHeight = pagerBar ? pagerBar.offsetHeight : 56; |
| | | var bottomGap = 56; |
| | | this.tableHeight = Math.max(320, Math.floor(viewportHeight - tableTop - pagerHeight - bottomGap)); |
| | | }, |
| | | requestTableLayout: function (delay) { |
| | | var self = this; |
| | | if (self.layoutTimer) { |
| | | clearTimeout(self.layoutTimer); |
| | | } |
| | | self.$nextTick(function () { |
| | | self.calculateTableHeight(); |
| | | self.layoutTimer = setTimeout(function () { |
| | | var table = self.$refs.dataTable; |
| | | if (table && typeof table.doLayout === 'function') { |
| | |
| | | } |
| | | }); |
| | | }, |
| | | openDetailDialog: function (row) { |
| | | var self = this; |
| | | self.dialog.mode = 'detail'; |
| | | self.dialog.visible = true; |
| | | self.$nextTick(function () { |
| | | self.resetDialogState(); |
| | | fillFormFromRow(row, self.dialogForm, self.dialogDisplay); |
| | | if (self.$refs.dialogForm) { |
| | | self.$refs.dialogForm.clearValidate(); |
| | | } |
| | | }); |
| | | }, |
| | | submitDialog: function () { |
| | | var self = this; |
| | | if (self.dialog.mode === 'detail') { |
| | | return; |
| | | } |
| | | if (!self.$refs.dialogForm) { |
| | | return; |
| | | } |
| | |
| | | self.$message.error('导出失败'); |
| | | } |
| | | }); |
| | | }, |
| | | refreshCache: function () { |
| | | var self = this; |
| | | self.$confirm('确定刷新Redis缓存吗?', '提示', { type: 'warning' }).then(function () { |
| | | $.ajax({ |
| | | url: baseUrl + '/config/refreshCache', |
| | | method: 'POST', |
| | | headers: self.authHeaders(), |
| | | success: function (res) { |
| | | if (self.handleForbidden(res)) { |
| | | return; |
| | | } |
| | | if (!res || res.code !== 200) { |
| | | self.$message.error((res && res.msg) ? res.msg : '刷新缓存失败'); |
| | | return; |
| | | } |
| | | self.$message.success('刷新缓存成功'); |
| | | self.loadTable(); |
| | | }, |
| | | error: function () { |
| | | self.$message.error('刷新缓存失败'); |
| | | } |
| | | }); |
| | | }).catch(function () {}); |
| | | } |
| | | }) |
| | | }); |
| New file |
| | |
| | | (function () { |
| | | var COLUMN_STORAGE_KEY = "wrk-mast-visible-columns"; |
| | | |
| | | var DEFAULT_COLUMNS = [ |
| | | { key: "wrkNo", prop: "wrkNo", label: "工作号", width: 110, sortable: true, align: "center" }, |
| | | { key: "wmsWrkNo", prop: "wmsWrkNo", label: "WMS任务号", minWidth: 160, sortable: true }, |
| | | { key: "wrkSts$", prop: "wrkSts$", label: "工作状态", minWidth: 120, sortable: true }, |
| | | { key: "ioType$", prop: "ioType$", label: "任务类型", minWidth: 120, sortable: true }, |
| | | { key: "ioPri", prop: "ioPri", label: "优先级", width: 90, sortable: true, align: "center" }, |
| | | { key: "sourceStaNo", prop: "sourceStaNo", label: "源站", width: 90, sortable: true, align: "center" }, |
| | | { key: "staNo", prop: "staNo", label: "目标站", width: 90, sortable: true, align: "center" }, |
| | | { key: "sourceLocNo", prop: "sourceLocNo", label: "源库位", minWidth: 140, sortable: true }, |
| | | { key: "locNo", prop: "locNo", label: "目标库位", minWidth: 140, sortable: true }, |
| | | { key: "modiTime$", prop: "modiTime$", label: "修改时间", minWidth: 168, sortable: true }, |
| | | { key: "barcode", prop: "barcode", label: "托盘码", minWidth: 150, sortable: true }, |
| | | { key: "crnNo", prop: "crnNo", label: "堆垛机", width: 90, sortable: true, align: "center" }, |
| | | { key: "dualCrnNo", prop: "dualCrnNo", label: "双工位堆垛机", minWidth: 120, sortable: true, align: "center" }, |
| | | { key: "batch", prop: "batch", label: "批次", minWidth: 120, sortable: true }, |
| | | { key: "batchSeq", prop: "batchSeq", label: "批次序列", width: 100, sortable: true, align: "center" }, |
| | | { key: "systemMsg", prop: "systemMsg", label: "系统消息", minWidth: 220, sortable: false, showOverflow: false } |
| | | ]; |
| | | |
| | | function cloneSearchForm() { |
| | | return { |
| | | condition: "", |
| | | wrk_no: "", |
| | | wms_wrk_no: "", |
| | | loc_no: "", |
| | | source_loc_no: "", |
| | | crn_no: "", |
| | | dual_crn_no: "" |
| | | }; |
| | | } |
| | | |
| | | function loadStoredColumns() { |
| | | try { |
| | | var raw = localStorage.getItem(COLUMN_STORAGE_KEY); |
| | | var parsed = raw ? JSON.parse(raw) : null; |
| | | if (!parsed || !parsed.length) { |
| | | return DEFAULT_COLUMNS.map(function (column) { return column.key; }); |
| | | } |
| | | return DEFAULT_COLUMNS.map(function (column) { return column.key; }).filter(function (key) { |
| | | return parsed.indexOf(key) > -1; |
| | | }); |
| | | } catch (e) { |
| | | return DEFAULT_COLUMNS.map(function (column) { return column.key; }); |
| | | } |
| | | } |
| | | |
| | | function saveVisibleColumns(keys) { |
| | | localStorage.setItem(COLUMN_STORAGE_KEY, JSON.stringify(keys)); |
| | | } |
| | | |
| | | new Vue({ |
| | | el: "#app", |
| | | data: function () { |
| | | return { |
| | | loading: false, |
| | | advancedVisible: false, |
| | | columnPopoverVisible: false, |
| | | tableData: [], |
| | | currentPage: 1, |
| | | pageSize: 30, |
| | | pageSizes: [16, 30, 50, 100, 150, 200], |
| | | pageTotal: 0, |
| | | tableHeight: 520, |
| | | searchForm: cloneSearchForm(), |
| | | sortState: { |
| | | prop: "", |
| | | order: "" |
| | | }, |
| | | columnDefs: DEFAULT_COLUMNS, |
| | | visibleColumnKeys: loadStoredColumns(), |
| | | layoutTimer: null |
| | | }; |
| | | }, |
| | | computed: { |
| | | visibleColumns: function () { |
| | | var keys = this.visibleColumnKeys; |
| | | return this.columnDefs.filter(function (column) { |
| | | return keys.indexOf(column.key) > -1; |
| | | }); |
| | | }, |
| | | tableRenderKey: function () { |
| | | return this.visibleColumnKeys.join("|"); |
| | | } |
| | | }, |
| | | created: function () { |
| | | this.loadList(); |
| | | }, |
| | | mounted: function () { |
| | | this.updateTableHeight(); |
| | | window.addEventListener("resize", this.handleResize); |
| | | }, |
| | | beforeDestroy: function () { |
| | | window.removeEventListener("resize", this.handleResize); |
| | | if (this.layoutTimer) { |
| | | clearTimeout(this.layoutTimer); |
| | | this.layoutTimer = null; |
| | | } |
| | | }, |
| | | methods: { |
| | | buildQueryParams: function () { |
| | | var data = { |
| | | curr: this.currentPage, |
| | | limit: this.pageSize |
| | | }; |
| | | var key; |
| | | for (key in this.searchForm) { |
| | | if (Object.prototype.hasOwnProperty.call(this.searchForm, key) && this.searchForm[key] !== "" && this.searchForm[key] !== null) { |
| | | data[key] = this.searchForm[key]; |
| | | } |
| | | } |
| | | if (this.sortState.prop && this.sortState.order) { |
| | | data.orderByField = this.sortState.prop; |
| | | data.orderByType = this.sortState.order === "ascending" ? "asc" : "desc"; |
| | | } |
| | | return data; |
| | | }, |
| | | loadList: function () { |
| | | var vm = this; |
| | | vm.loading = true; |
| | | $.ajax({ |
| | | url: baseUrl + "/wrkMast/list/auth", |
| | | headers: { token: localStorage.getItem("token") }, |
| | | method: "GET", |
| | | data: vm.buildQueryParams(), |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | vm.tableData = (res.data && res.data.records) || []; |
| | | vm.pageTotal = (res.data && res.data.total) || 0; |
| | | vm.scheduleTableLayout(); |
| | | return; |
| | | } |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | return; |
| | | } |
| | | vm.$message.error(res.msg || "任务列表加载失败"); |
| | | }, |
| | | error: function () { |
| | | vm.$message.error("任务列表加载失败"); |
| | | }, |
| | | complete: function () { |
| | | vm.loading = false; |
| | | } |
| | | }); |
| | | }, |
| | | handleSearch: function () { |
| | | this.currentPage = 1; |
| | | this.loadList(); |
| | | }, |
| | | handleReset: function () { |
| | | this.searchForm = cloneSearchForm(); |
| | | this.currentPage = 1; |
| | | this.sortState = { |
| | | prop: "", |
| | | order: "" |
| | | }; |
| | | this.loadList(); |
| | | this.scheduleTableLayout(); |
| | | }, |
| | | toggleAdvanced: function () { |
| | | this.advancedVisible = !this.advancedVisible; |
| | | this.updateTableHeight(); |
| | | this.scheduleTableLayout(); |
| | | }, |
| | | handleSizeChange: function (size) { |
| | | this.pageSize = size; |
| | | this.currentPage = 1; |
| | | this.loadList(); |
| | | }, |
| | | handleCurrentChange: function (page) { |
| | | this.currentPage = page; |
| | | this.loadList(); |
| | | }, |
| | | handleSortChange: function (sort) { |
| | | this.sortState = { |
| | | prop: sort.prop || "", |
| | | order: sort.order || "" |
| | | }; |
| | | this.currentPage = 1; |
| | | this.loadList(); |
| | | }, |
| | | isColumnVisible: function (key) { |
| | | return this.visibleColumnKeys.indexOf(key) > -1; |
| | | }, |
| | | toggleColumn: function (key, checked) { |
| | | var next = this.visibleColumnKeys.slice(); |
| | | var index = next.indexOf(key); |
| | | |
| | | if (checked && index === -1) { |
| | | next.push(key); |
| | | } |
| | | if (!checked && index > -1) { |
| | | if (next.length === 1) { |
| | | this.$message.warning("至少保留一列"); |
| | | return; |
| | | } |
| | | next.splice(index, 1); |
| | | } |
| | | |
| | | this.visibleColumnKeys = this.columnDefs.map(function (column) { |
| | | return column.key; |
| | | }).filter(function (columnKey) { |
| | | return next.indexOf(columnKey) > -1; |
| | | }); |
| | | saveVisibleColumns(this.visibleColumnKeys); |
| | | this.scheduleTableLayout(); |
| | | }, |
| | | showAllColumns: function () { |
| | | this.visibleColumnKeys = this.columnDefs.map(function (column) { |
| | | return column.key; |
| | | }); |
| | | saveVisibleColumns(this.visibleColumnKeys); |
| | | this.scheduleTableLayout(); |
| | | }, |
| | | resetColumns: function () { |
| | | this.visibleColumnKeys = DEFAULT_COLUMNS.map(function (column) { |
| | | return column.key; |
| | | }); |
| | | saveVisibleColumns(this.visibleColumnKeys); |
| | | this.scheduleTableLayout(); |
| | | }, |
| | | handleRowCommand: function (command, row) { |
| | | if (command === "complete") { |
| | | this.completeTask(row); |
| | | return; |
| | | } |
| | | if (command === "cancel") { |
| | | this.cancelTask(row); |
| | | } |
| | | }, |
| | | completeTask: function (row) { |
| | | var vm = this; |
| | | vm.$confirm("确定完成该任务吗?", "提示", { |
| | | type: "warning", |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消" |
| | | }).then(function () { |
| | | $.ajax({ |
| | | url: baseUrl + "/openapi/completeTask", |
| | | contentType: "application/json", |
| | | headers: { token: localStorage.getItem("token") }, |
| | | data: JSON.stringify({ wrkNo: row.wrkNo }), |
| | | method: "POST", |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | vm.$message.success("完成成功"); |
| | | vm.loadList(); |
| | | return; |
| | | } |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | return; |
| | | } |
| | | vm.$message.error(res.msg || "完成失败"); |
| | | }, |
| | | error: function () { |
| | | vm.$message.error("完成失败"); |
| | | } |
| | | }); |
| | | }).catch(function () {}); |
| | | }, |
| | | cancelTask: function (row) { |
| | | var vm = this; |
| | | vm.$confirm("确定取消该任务吗?", "提示", { |
| | | type: "warning", |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消" |
| | | }).then(function () { |
| | | $.ajax({ |
| | | url: baseUrl + "/openapi/cancelTask", |
| | | contentType: "application/json", |
| | | headers: { token: localStorage.getItem("token") }, |
| | | data: JSON.stringify({ wrkNo: row.wrkNo }), |
| | | method: "POST", |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | vm.$message.success("取消成功"); |
| | | vm.loadList(); |
| | | return; |
| | | } |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | return; |
| | | } |
| | | vm.$message.error(res.msg || "取消失败"); |
| | | }, |
| | | error: function () { |
| | | vm.$message.error("取消失败"); |
| | | } |
| | | }); |
| | | }).catch(function () {}); |
| | | }, |
| | | updateTableHeight: function () { |
| | | var viewport = window.innerHeight || document.documentElement.clientHeight || 860; |
| | | this.tableHeight = Math.max(340, viewport - (this.advancedVisible ? 276 : 222)); |
| | | }, |
| | | scheduleTableLayout: function () { |
| | | var vm = this; |
| | | vm.updateTableHeight(); |
| | | vm.$nextTick(function () { |
| | | if (vm.layoutTimer) { |
| | | clearTimeout(vm.layoutTimer); |
| | | } |
| | | vm.layoutTimer = setTimeout(function () { |
| | | if (vm.$refs.dataTable && typeof vm.$refs.dataTable.doLayout === "function") { |
| | | vm.$refs.dataTable.doLayout(); |
| | | } |
| | | }, 50); |
| | | }); |
| | | }, |
| | | handleResize: function () { |
| | | this.scheduleTableLayout(); |
| | | } |
| | | } |
| | | }); |
| | | })(); |
| | |
| | | |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script src="../../static/js/marked.min.js"></script> |
| | | <script src="../../static/js/purify.min.js"></script> |
| | | <script> |
| | |
| | | |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script> |
| | | new Vue({ |
| | | el: '#app', |
| | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/basOutStationArea/basOutStationArea.js"></script> |
| | | </body> |
| | | </html> |
| | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/basStationDevice/basStationDevice.js"></script> |
| | | </body> |
| | | </html> |
| | |
| | | html, |
| | | body { |
| | | margin: 0; |
| | | height: 100%; |
| | | min-height: 100%; |
| | | color: var(--text-main); |
| | | font-family: "Avenir Next", "PingFang SC", "Microsoft YaHei", sans-serif; |
| | |
| | | .page-shell { |
| | | max-width: 1700px; |
| | | margin: 0 auto; |
| | | height: 100%; |
| | | padding: 14px; |
| | | box-sizing: border-box; |
| | | display: flex; |
| | | } |
| | | |
| | | .card-shell { |
| | | position: relative; |
| | | flex: 1 1 auto; |
| | | display: flex; |
| | | border-radius: 24px; |
| | | border: 1px solid var(--card-border); |
| | | background: |
| | |
| | | .card-body { |
| | | position: relative; |
| | | z-index: 1; |
| | | flex: 1 1 auto; |
| | | min-height: 0; |
| | | min-width: 0; |
| | | width: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .list-toolbar { |
| | |
| | | |
| | | .table-wrap { |
| | | padding: 10px 16px; |
| | | flex: 1 1 auto; |
| | | min-height: 0; |
| | | min-width: 0; |
| | | width: 100%; |
| | | display: flex; |
| | | } |
| | | |
| | | .table-shell { |
| | |
| | | overflow: hidden; |
| | | border: 1px solid rgba(217, 227, 238, 0.98); |
| | | background: rgba(255, 255, 255, 0.95); |
| | | flex: 1 1 auto; |
| | | min-height: 0; |
| | | min-width: 0; |
| | | width: 100%; |
| | | max-width: 100%; |
| | | } |
| | | |
| | | .table-shell .el-table { |
| | |
| | | <el-button slot="reference" size="small" plain icon="el-icon-setting">列设置</el-button> |
| | | </el-popover> |
| | | <el-button size="small" plain icon="el-icon-download" :loading="exporting" @click="exportRows">导出</el-button> |
| | | <el-button size="small" plain type="warning" icon="el-icon-refresh-right" @click="refreshCache">刷新缓存</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </div> |
| | | </el-collapse-transition> |
| | | |
| | | <div class="table-wrap"> |
| | | <div ref="tableWrap" class="table-wrap"> |
| | | <div class="table-shell"> |
| | | <el-table |
| | | ref="dataTable" |
| | |
| | | <span v-else>{{ valueOrDash(getTableValue(scope.row, field)) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="160" fixed="right" align="center"> |
| | | <el-table-column label="操作" width="190" fixed="right" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="openDetailDialog(scope.row)">详情</el-button> |
| | | <el-button type="text" @click="openEditDialog(scope.row)">修改</el-button> |
| | | <el-button type="text" style="color:#f56c6c;" @click="removeRows([scope.row[primaryKeyField]])">删除</el-button> |
| | | </template> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="pager-bar"> |
| | | <div ref="pagerBar" class="pager-bar"> |
| | | <el-pagination |
| | | small |
| | | background |
| | |
| | | |
| | | <el-dialog |
| | | class="dialog-panel" |
| | | :title="dialog.mode === 'create' ? '新增 Config' : '修改 Config'" |
| | | :title="dialog.mode === 'create' ? '新增 Config' : (dialog.mode === 'detail' ? '详情 Config' : '修改 Config')" |
| | | :visible.sync="dialog.visible" |
| | | width="760px" |
| | | :close-on-click-modal="false"> |
| | |
| | | <el-col |
| | | v-for="field in editableFields" |
| | | :key="'dialog-' + field.field" |
| | | :span="field.textarea || field.kind === 'image' ? 24 : 12"> |
| | | :span="field.dialogSpan || (field.textarea || field.kind === 'image' ? 24 : 12)"> |
| | | <el-form-item :label="field.label" :prop="field.field"> |
| | | <el-date-picker |
| | | v-if="field.kind === 'date'" |
| | |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | :placeholder="'请选择' + field.label" |
| | | :disabled="isDialogReadonly" |
| | | style="width: 100%;"> |
| | | </el-date-picker> |
| | | <el-select |
| | | v-else-if="field.kind === 'enum'" |
| | | v-model="dialogForm[field.field]" |
| | | clearable |
| | | :disabled="isDialogReadonly" |
| | | :placeholder="'请选择' + field.label" |
| | | style="width: 100%;"> |
| | | <el-option |
| | |
| | | v-model="dialogDisplay[field.field]" |
| | | :fetch-suggestions="getSuggestionFetcher(field)" |
| | | :placeholder="'请输入' + field.label" |
| | | :disabled="isDialogReadonly" |
| | | style="width: 100%;" |
| | | @select="handleForeignSelect(field, $event)" |
| | | @input="handleForeignInput(field)"> |
| | |
| | | <el-switch |
| | | v-else-if="field.kind === 'checkbox'" |
| | | v-model="dialogForm[field.field]" |
| | | :disabled="isDialogReadonly" |
| | | :active-value="normalizeOptionValue(field, field.checkboxActiveRaw)" |
| | | :inactive-value="normalizeOptionValue(field, field.checkboxInactiveRaw)" |
| | | active-color="#13ce66" |
| | |
| | | v-model.trim="dialogForm[field.field]" |
| | | type="textarea" |
| | | :rows="3" |
| | | :disabled="isDialogReadonly" |
| | | :placeholder="'请输入' + field.label"> |
| | | </el-input> |
| | | <el-input |
| | | v-else |
| | | v-model.trim="dialogForm[field.field]" |
| | | :disabled="isDialogReadonly" |
| | | :placeholder="'请输入' + field.label"> |
| | | </el-input> |
| | | </el-form-item> |
| | |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="dialog.visible = false">取消</el-button> |
| | | <el-button type="primary" :loading="dialog.submitting" @click="submitDialog">保存</el-button> |
| | | <el-button v-if="!isDialogReadonly" type="primary" :loading="dialog.submitting" @click="submitDialog">保存</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/config/config.js?v=20260310" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/config/config.js" charset="utf-8"></script> |
| | | </body> |
| | | </html> |
| | |
| | | <title>调试参数</title> |
| | | <link rel="stylesheet" href="../../static/vue/element/element.css"> |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <style> |
| | |
| | | </body> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/tools/md5.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../static/js/detail/detail.js?v=20260310_detail_vue3"></script> |
| | |
| | | </div> |
| | | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script src="../../static/vue/js/vue.min.js"></script> |
| | | <script src="../../static/vue/element/element.js"></script> |
| | | <script src="../../components/MonitorCardKit.js"></script> |
| | |
| | | </div> |
| | | |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/vue/element/element.js"></script> |
| | | <script> |
| | |
| | | PROFILE_TAB_CONFIG.title = profileConfig.title; |
| | | PROFILE_TAB_CONFIG.group = profileConfig.group; |
| | | for (i = 0; i < this.tabs.length; i++) { |
| | | if (this.isHomeTabUrl(this.tabs[i].url)) { |
| | | this.tabs[i].title = homeConfig.title; |
| | | this.tabs[i].group = homeConfig.group; |
| | | this.tabs[i].home = true; |
| | | } else if (this.resolveViewSrc(this.tabs[i].url) === this.resolveViewSrc(profileConfig.url)) { |
| | | this.tabs[i].title = profileConfig.title; |
| | | this.tabs[i].group = profileConfig.group; |
| | | } else { |
| | | this.tabs[i].title = this.translateTabTitle(this.tabs[i].title); |
| | | this.tabs[i].group = this.tl(this.tabs[i].group); |
| | | } |
| | | this.syncTabMeta(this.tabs[i], homeConfig, profileConfig); |
| | | } |
| | | this.updateDocumentTitle(this.activeTabTitle); |
| | | this.persistTabs(); |
| | |
| | | }, |
| | | translateTabTitle: function (title) { |
| | | return this.tl(title); |
| | | }, |
| | | findMenuMeta: function (tab) { |
| | | var normalizedUrl; |
| | | var i; |
| | | var j; |
| | | var group; |
| | | var item; |
| | | if (!tab) { |
| | | return null; |
| | | } |
| | | normalizedUrl = this.resolveViewSrc(tab.url); |
| | | for (i = 0; i < this.menus.length; i++) { |
| | | group = this.menus[i]; |
| | | for (j = 0; j < group.subMenu.length; j++) { |
| | | item = group.subMenu[j]; |
| | | if ((tab.menuKey && item.tabKey === tab.menuKey) || item.url === normalizedUrl) { |
| | | return { |
| | | group: group, |
| | | item: item |
| | | }; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | }, |
| | | syncTabMeta: function (tab, homeConfig, profileConfig) { |
| | | var menuMeta; |
| | | if (!tab) { |
| | | return; |
| | | } |
| | | if (this.isHomeTabUrl(tab.url)) { |
| | | tab.title = homeConfig.title; |
| | | tab.group = homeConfig.group; |
| | | tab.home = true; |
| | | return; |
| | | } |
| | | if (this.resolveViewSrc(tab.url) === this.resolveViewSrc(profileConfig.url)) { |
| | | tab.title = profileConfig.title; |
| | | tab.group = profileConfig.group; |
| | | return; |
| | | } |
| | | menuMeta = this.findMenuMeta(tab); |
| | | if (menuMeta) { |
| | | tab.title = menuMeta.item.name; |
| | | tab.group = menuMeta.group.menu; |
| | | tab.menuKey = menuMeta.item.tabKey || tab.menuKey; |
| | | return; |
| | | } |
| | | tab.title = this.translateTabTitle(tab.title); |
| | | tab.group = this.tl(tab.group); |
| | | }, |
| | | updateDocumentTitle: function (title) { |
| | | document.title = title + " - " + this.t("app.title"); |
| | |
| | | script = frameDocument.createElement("script"); |
| | | script.id = "wcs-i18n-bridge-script"; |
| | | script.type = "text/javascript"; |
| | | script.src = baseUrl + "/static/js/common.js?v=20260309_i18n_fix1"; |
| | | script.src = baseUrl + "/static/js/common.js"; |
| | | script.onload = applyFrameI18n; |
| | | frameDocument.head.appendChild(script); |
| | | }, |
| | |
| | | that.menuLoading = false; |
| | | if (res.code === 200) { |
| | | that.menus = that.normalizeMenuData(res.data || []); |
| | | that.refreshI18nState(); |
| | | that.syncMenuStateByUrl(that.activeTabUrl); |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/login"; |
| | |
| | | <title>库位地图</title> |
| | | <link rel="stylesheet" href="../../static/vue/element/element.css"> |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script src="../../static/js/gsap.min.js"></script> |
| | |
| | | </body> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/tools/md5.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../static/js/login/login.js?v=20260310_login_vue"></script> |
| | |
| | | |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script> |
| | | new Vue({ |
| | | el: '#app', |
| | |
| | | </body> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/tools/md5.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../static/js/password/password.js?v=20260310_password_vue"></script> |
| | |
| | | </body> |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../../static/js/role/rolePower.js" charset="utf-8"></script> |
| | | </html> |
| | |
| | | </style> |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/js/handlebars/handlebars-v4.5.3.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script src="../../static/js/gsap.min.js"></script> |
| | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/layui/layui.js"></script> |
| | | <script type="text/javascript" src="../../static/js/handlebars/handlebars-v4.5.3.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | </head> |
| | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/layui/layui.js"></script> |
| | | <script type="text/javascript" src="../../static/js/handlebars/handlebars-v4.5.3.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script src="../../static/js/gsap.min.js"></script> |
| | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/watch/stationColorConfig.js" charset="utf-8"></script> |
| | | </body> |
| | | </html> |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | |
| | | <html lang="zh-CN"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>任务管理</title> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
| | | <link rel="stylesheet" href="../../static/vue/element/element.css"> |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <link rel="stylesheet" href="../../static/css/cool.css"> |
| | | <style> |
| | | :root { |
| | | --card-bg: rgba(255, 255, 255, 0.94); |
| | | --card-border: rgba(216, 226, 238, 0.95); |
| | | --text-main: #243447; |
| | | } |
| | | |
| | | [v-cloak] { |
| | | display: none; |
| | | } |
| | | .el-table .success-row { |
| | | background: #b6ff8e; |
| | | |
| | | html, |
| | | body { |
| | | margin: 0; |
| | | min-height: 100%; |
| | | color: var(--text-main); |
| | | font-family: "Avenir Next", "PingFang SC", "Microsoft YaHei", sans-serif; |
| | | background: |
| | | radial-gradient(1000px 420px at 0% -10%, rgba(44, 107, 193, 0.12), transparent 56%), |
| | | radial-gradient(900px 400px at 100% 0%, rgba(28, 150, 126, 0.10), transparent 58%), |
| | | linear-gradient(180deg, #f2f6fb 0%, #f8fafc 100%); |
| | | } |
| | | |
| | | .page-shell { |
| | | max-width: 1800px; |
| | | margin: 0 auto; |
| | | padding: 14px; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .card-shell { |
| | | position: relative; |
| | | border-radius: 24px; |
| | | border: 1px solid var(--card-border); |
| | | background: |
| | | radial-gradient(760px 220px at -8% 0%, rgba(43, 117, 196, 0.05), transparent 55%), |
| | | radial-gradient(680px 200px at 108% 10%, rgba(24, 150, 129, 0.05), transparent 58%), |
| | | var(--card-bg); |
| | | box-shadow: 0 16px 32px rgba(44, 67, 96, 0.08); |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .list-toolbar { |
| | | padding: 12px 16px 10px; |
| | | border-bottom: 1px solid rgba(222, 230, 239, 0.92); |
| | | } |
| | | |
| | | .toolbar-main { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | justify-content: space-between; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-left { |
| | | flex: 1 1 980px; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-search { |
| | | flex: 1 1 auto; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-search-item { |
| | | flex: 0 0 148px; |
| | | min-width: 148px; |
| | | } |
| | | |
| | | .toolbar-search-item.keyword { |
| | | flex: 0 0 220px; |
| | | min-width: 220px; |
| | | } |
| | | |
| | | .toolbar-query-actions, |
| | | .toolbar-ops { |
| | | display: flex; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-ops { |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | .list-toolbar .el-input__inner, |
| | | .advanced-panel .el-input__inner { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .list-toolbar .el-input__icon, |
| | | .advanced-panel .el-input__icon { |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .list-toolbar .el-button, |
| | | .advanced-panel .el-button { |
| | | padding: 8px 12px; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .advanced-panel { |
| | | padding: 10px 16px 12px; |
| | | border-bottom: 1px solid rgba(222, 230, 239, 0.92); |
| | | background: rgba(248, 251, 254, 0.78); |
| | | } |
| | | |
| | | .advanced-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(4, minmax(0, 1fr)); |
| | | gap: 8px; |
| | | } |
| | | |
| | | .advanced-item { |
| | | min-width: 0; |
| | | } |
| | | |
| | | .table-wrap { |
| | | padding: 10px 16px; |
| | | } |
| | | |
| | | .table-shell { |
| | | border-radius: 20px; |
| | | overflow: hidden; |
| | | border: 1px solid rgba(217, 227, 238, 0.98); |
| | | background: rgba(255, 255, 255, 0.95); |
| | | } |
| | | |
| | | .table-shell .el-table { |
| | | border-radius: 20px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .table-shell .el-table th { |
| | | background: #f7fafc; |
| | | color: #53677d; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .table-shell .el-table .success-row > td { |
| | | background: rgba(101, 198, 141, 0.14); |
| | | } |
| | | |
| | | .payload-cell { |
| | | display: inline-block; |
| | | max-width: 280px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | .pager-bar { |
| | | padding: 0 16px 16px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | .column-popover { |
| | | max-width: 320px; |
| | | } |
| | | |
| | | .column-popover-head { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | gap: 12px; |
| | | margin-bottom: 10px; |
| | | font-size: 13px; |
| | | font-weight: 700; |
| | | color: var(--text-main); |
| | | } |
| | | |
| | | .column-list { |
| | | display: grid; |
| | | grid-template-columns: repeat(2, minmax(0, 1fr)); |
| | | gap: 8px 10px; |
| | | max-height: 280px; |
| | | overflow: auto; |
| | | padding-right: 4px; |
| | | } |
| | | |
| | | .row-action-trigger { |
| | | min-width: 72px; |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | @media (max-width: 1600px) { |
| | | .advanced-grid { |
| | | grid-template-columns: repeat(3, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 1280px) { |
| | | .advanced-grid { |
| | | grid-template-columns: repeat(2, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 900px) { |
| | | .page-shell { |
| | | padding: 10px; |
| | | } |
| | | |
| | | .list-toolbar, |
| | | .advanced-panel, |
| | | .table-wrap, |
| | | .pager-bar { |
| | | padding-left: 12px; |
| | | padding-right: 12px; |
| | | } |
| | | |
| | | .toolbar-search-item, |
| | | .toolbar-search-item.keyword { |
| | | flex: 1 1 100%; |
| | | min-width: 100%; |
| | | } |
| | | |
| | | .advanced-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | } |
| | | </style> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="app" v-cloak style="display: flex;justify-content: center;flex-wrap: wrap;"> |
| | | <div style="width: 100%;"> |
| | | <el-card class="box-card"> |
| | | <el-form :inline="true" :model="tableSearchParam" class="demo-form-inline"> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.wrk_no" placeholder="工作号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.wms_wrk_no" placeholder="WMS工作号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.source_loc_no" placeholder="源库位"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.loc_no" placeholder="目标库位"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.crn_no" placeholder="堆垛机"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.dual_crn_no" placeholder="双工位堆垛机"></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">查询</el-button> |
| | | <el-button type="primary" @click="resetParam">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-table ref="singleTable" :data="tableData" style="width: 100%;"> |
| | | <el-table-column property="wrkNo" label="工作号"> |
| | | <div id="app" class="page-shell" v-cloak> |
| | | <section class="card-shell"> |
| | | <div class="list-toolbar"> |
| | | <div class="toolbar-main"> |
| | | <div class="toolbar-left"> |
| | | <div class="toolbar-search"> |
| | | <div class="toolbar-search-item keyword"> |
| | | <el-input |
| | | v-model.trim="searchForm.condition" |
| | | clearable |
| | | size="small" |
| | | placeholder="请输入关键字" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-search-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.wrk_no" |
| | | clearable |
| | | size="small" |
| | | placeholder="工作号" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-search-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.wms_wrk_no" |
| | | clearable |
| | | size="small" |
| | | placeholder="WMS任务号" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-search-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.loc_no" |
| | | clearable |
| | | size="small" |
| | | placeholder="目标库位" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-query-actions"> |
| | | <el-button size="small" type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button> |
| | | <el-button size="small" plain icon="el-icon-refresh-left" @click="handleReset">重置</el-button> |
| | | <el-button size="small" plain :icon="advancedVisible ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" @click="toggleAdvanced"> |
| | | {{ advancedVisible ? '收起' : '筛选' }} |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="toolbar-ops"> |
| | | <el-popover |
| | | v-model="columnPopoverVisible" |
| | | placement="bottom-end" |
| | | width="320" |
| | | trigger="click" |
| | | popper-class="column-popover"> |
| | | <div class="column-popover-head"> |
| | | <span>列设置</span> |
| | | <div> |
| | | <el-button type="text" size="mini" @click="showAllColumns">全选</el-button> |
| | | <el-button type="text" size="mini" @click="resetColumns">重置</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="column-list"> |
| | | <el-checkbox |
| | | v-for="column in columnDefs" |
| | | :key="'column-' + column.key" |
| | | :value="isColumnVisible(column.key)" |
| | | @change="toggleColumn(column.key, $event)"> |
| | | {{ column.label }} |
| | | </el-checkbox> |
| | | </div> |
| | | <el-button slot="reference" size="small" plain icon="el-icon-setting">列设置</el-button> |
| | | </el-popover> |
| | | <el-button size="small" plain icon="el-icon-refresh" :loading="loading" @click="loadList">刷新</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-show="advancedVisible" class="advanced-panel"> |
| | | <div class="advanced-grid"> |
| | | <div class="advanced-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.source_loc_no" |
| | | clearable |
| | | size="small" |
| | | placeholder="源库位" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="advanced-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.crn_no" |
| | | clearable |
| | | size="small" |
| | | placeholder="堆垛机" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="advanced-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.dual_crn_no" |
| | | clearable |
| | | size="small" |
| | | placeholder="双工位堆垛机" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table-wrap"> |
| | | <div class="table-shell"> |
| | | <el-table |
| | | ref="dataTable" |
| | | :key="tableRenderKey" |
| | | v-loading="loading" |
| | | :data="tableData" |
| | | border |
| | | stripe |
| | | :height="tableHeight" |
| | | @sort-change="handleSortChange"> |
| | | <el-table-column |
| | | v-for="column in visibleColumns" |
| | | :key="column.key" |
| | | :prop="column.prop" |
| | | :label="column.label" |
| | | :width="column.width" |
| | | :min-width="column.minWidth" |
| | | :sortable="column.sortable ? 'custom' : false" |
| | | :show-overflow-tooltip="column.showOverflow !== false" |
| | | :align="column.align || 'left'"> |
| | | <template v-if="column.key === 'systemMsg'" slot-scope="scope"> |
| | | <span class="payload-cell">{{ scope.row.systemMsg || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column property="wmsWrkNo" label="WMS任务号"> |
| | | </el-table-column> |
| | | <el-table-column property="wrkSts$" label="工作状态"> |
| | | </el-table-column> |
| | | <el-table-column property="ioType$" label="任务类型"> |
| | | </el-table-column> |
| | | <el-table-column property="ioPri" label="优先级"> |
| | | </el-table-column> |
| | | <el-table-column property="sourceStaNo" label="源站"> |
| | | </el-table-column> |
| | | <el-table-column property="staNo" label="目标站"> |
| | | </el-table-column> |
| | | <el-table-column property="sourceLocNo" label="源库位"> |
| | | </el-table-column> |
| | | <el-table-column property="locNo" label="目标库位"> |
| | | </el-table-column> |
| | | <el-table-column property="modiTime$" label="时间"> |
| | | </el-table-column> |
| | | <el-table-column property="barcode" label="托盘码"> |
| | | </el-table-column> |
| | | <el-table-column property="crnNo" label="堆垛机"> |
| | | </el-table-column> |
| | | <el-table-column property="dualCrnNo" label="双工位堆垛机"> |
| | | </el-table-column> |
| | | <el-table-column property="batch" label="批次"> |
| | | </el-table-column> |
| | | <el-table-column property="batchSeq" label="批次序列"> |
| | | </el-table-column> |
| | | <el-table-column property="systemMsg" label="系统消息"> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="100"> |
| | | <el-table-column label="操作" fixed="right" width="100" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-dropdown @command="(command)=>{handleCommand(command, scope.row)}"> |
| | | <el-button icon="el-icon-more" size="mini" type="primary"></el-button> |
| | | <el-dropdown trigger="click" @command="handleRowCommand($event, scope.row)"> |
| | | <el-button size="mini" plain class="row-action-trigger"> |
| | | 操作<i class="el-icon-arrow-down el-icon--right"></i> |
| | | </el-button> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <!-- <el-dropdown-item command="change">修改</el-dropdown-item>--> |
| | | <el-dropdown-item command="complete">完成</el-dropdown-item> |
| | | <el-dropdown-item command="cancel">取消</el-dropdown-item> |
| | | <!-- <el-dropdown-item command="shuttleCommand">穿梭车指令</el-dropdown-item>--> |
| | | <el-dropdown-item command="complete">完成任务</el-dropdown-item> |
| | | <el-dropdown-item command="cancel" divided>取消任务</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | |
| | | <div style="margin-top: 10px;"> |
| | | <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" |
| | | :current-page="currentPage" :page-sizes="pageSizes" :page-size="pageSize" |
| | | layout="total, sizes, prev, pager, next, jumper" :total="pageTotal"> |
| | | <div class="pager-bar"> |
| | | <el-pagination |
| | | background |
| | | :current-page="currentPage" |
| | | :page-size="pageSize" |
| | | :page-sizes="pageSizes" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="pageTotal" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange"> |
| | | </el-pagination> |
| | | </div> |
| | | </el-card> |
| | | </section> |
| | | </div> |
| | | |
| | | <el-dialog :title="shuttleCommandTitle" :visible.sync="shuttleCommandVisible"> |
| | | <el-table ref="singleTable" :data="shuttleCommandData.commands" style="width: 100%;" :row-class-name="tableRowClassName"> |
| | | <el-table-column property="mode$" label="命令类型"> |
| | | </el-table-column> |
| | | <el-table-column property="start" label="起点"> |
| | | <template slot-scope="scope"> |
| | | <div v-if="scope.row.nodes"> |
| | | x:{{ scope.row.nodes[0].x }} |
| | | y:{{ scope.row.nodes[0].y }} |
| | | z:{{ scope.row.nodes[0].z }} |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column property="target" label="终点"> |
| | | <template slot-scope="scope"> |
| | | <div v-if="scope.row.nodes"> |
| | | x:{{ scope.row.nodes[scope.row.nodes.length-1].x }} |
| | | y:{{ scope.row.nodes[scope.row.nodes.length-1].y }} |
| | | z:{{ scope.row.nodes[scope.row.nodes.length-1].z }} |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column property="taskNo" label="任务号"> |
| | | </el-table-column> |
| | | <el-table-column property="shuttleNo" label="穿梭车"> |
| | | </el-table-column> |
| | | <el-table-column property="complete" label="是否完成"> |
| | | <template slot-scope="scope"> |
| | | <el-switch |
| | | v-model="scope.row.complete" |
| | | active-color="#13ce66" |
| | | @change="changeComplete(scope)"> |
| | | </el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-button @click="shuttleCommandRollback(scope)" size="mini">回退指令</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="shuttleCommandVisible = false">关闭</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | </div> |
| | | <script> |
| | | var app = new Vue({ |
| | | el: '#app', |
| | | data: { |
| | | tableData: [], |
| | | currentPage: 1, |
| | | pageSizes: [16, 30, 50, 100, 150, 200], |
| | | pageSize: 30, |
| | | pageTotal: 0, |
| | | tableSearchParam: { |
| | | wrk_no: null, |
| | | wms_wrk_no: null, |
| | | }, |
| | | shuttleCommandVisible: false, |
| | | shuttleCommandData: { |
| | | assignCommand: { |
| | | commands: [] |
| | | }, |
| | | commandStep: 0 |
| | | }, |
| | | shuttleCommandWrkNo: null, |
| | | shuttleCommandLabelWidth: '80px', |
| | | shuttleCommandTitle: '' |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.getTableData() |
| | | }, |
| | | getTableData() { |
| | | let that = this; |
| | | let data = JSON.parse(JSON.stringify(this.tableSearchParam)) |
| | | data.curr = this.currentPage |
| | | data.limit = this.pageSize |
| | | if (this.tableSearchParam.datetime != null) { |
| | | data.datetime = null |
| | | data.create_time = this.tableSearchParam.datetime[0] + " - " + this.tableSearchParam.datetime[1] |
| | | } |
| | | $.ajax({ |
| | | url: baseUrl + "/wrkMast/list/auth", |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: data, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | that.tableData = res.data.records |
| | | that.pageTotal = res.data.total |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | handleSizeChange(val) { |
| | | console.log(`每页 ${val} 条`); |
| | | this.pageSize = val |
| | | this.getTableData() |
| | | }, |
| | | handleCurrentChange(val) { |
| | | console.log(`当前页: ${val}`); |
| | | this.currentPage = val |
| | | this.getTableData() |
| | | }, |
| | | resetParam() { |
| | | this.tableSearchParam = { |
| | | task_no: null, |
| | | status: null, |
| | | wrk_no: null |
| | | } |
| | | this.getTableData() |
| | | }, |
| | | handleCommand(command, row) { |
| | | switch (command) { |
| | | case "complete": |
| | | this.completeTask(row) |
| | | break; |
| | | case "cancel": |
| | | this.cancelTask(row) |
| | | break; |
| | | case "shuttleCommand": |
| | | this.showShuttleCommand(row.wrkNo) |
| | | break; |
| | | } |
| | | }, |
| | | showShuttleCommand(wrkNo){ |
| | | let that = this; |
| | | $.ajax({ |
| | | url: baseUrl + "/shuttle/command/query", |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: { |
| | | wrkNo: wrkNo |
| | | }, |
| | | method: 'GET', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | console.log(res) |
| | | that.shuttleCommandVisible = true; |
| | | that.shuttleCommandData = res.data; |
| | | that.shuttleCommandWrkNo = wrkNo; |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | completeTask(row) { |
| | | let that = this |
| | | this.$confirm('确定完成该任务吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | $.ajax({ |
| | | url: baseUrl + "/openapi/completeTask", |
| | | contentType: 'application/json', |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: JSON.stringify({ |
| | | wrkNo: row.wrkNo, |
| | | }), |
| | | method: 'POST', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: "完成成功", |
| | | type: 'success' |
| | | }); |
| | | that.getTableData() |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }).catch(() => { |
| | | // this.$message({ |
| | | // type: 'info', |
| | | // message: '已取消删除' |
| | | // }); |
| | | }); |
| | | }, |
| | | cancelTask(row) { |
| | | let that = this |
| | | this.$confirm('确定取消该任务吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | $.ajax({ |
| | | url: baseUrl + "/openapi/cancelTask", |
| | | contentType: 'application/json', |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: JSON.stringify({ |
| | | wrkNo: row.wrkNo, |
| | | }), |
| | | method: 'POST', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: "取消成功", |
| | | type: 'success' |
| | | }); |
| | | that.getTableData() |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }).catch(() => { |
| | | // this.$message({ |
| | | // type: 'info', |
| | | // message: '已取消删除' |
| | | // }); |
| | | }); |
| | | }, |
| | | tableRowClassName({row, rowIndex}) { |
| | | if (rowIndex === this.shuttleCommandData.commandStep) { |
| | | return 'success-row'; |
| | | } |
| | | return ''; |
| | | }, |
| | | shuttleCommandRollback(scope) { |
| | | let that = this; |
| | | let idx = scope.$index; |
| | | $.ajax({ |
| | | url: baseUrl + "/shuttle/command/rollback", |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: { |
| | | wrkNo: that.shuttleCommandWrkNo, |
| | | commandStep: idx |
| | | }, |
| | | method: 'GET', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | that.showShuttleCommand(that.shuttleCommandWrkNo) |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | changeComplete(scope) { |
| | | let that = this; |
| | | let idx = scope.$index; |
| | | $.ajax({ |
| | | url: baseUrl + "/shuttle/command/completeSwitch", |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: { |
| | | wrkNo: that.shuttleCommandWrkNo, |
| | | commandStep: idx, |
| | | complete: scope.row.complete ? 1 : 0 |
| | | }, |
| | | method: 'GET', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | that.showShuttleCommand(that.shuttleCommandWrkNo) |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | }) |
| | | </script> |
| | | </body> |
| | | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/wrkMast/wrkMast.js?v=20260311_wrk_mast_vue"></script> |
| | | </html> |