fastadmin work使用type_id做为status分类项选择

本文介绍了一种优化Work列表展示的方法,通过在Work的index中添加特定的HTML结构,实现了一个带有选项卡的导航栏,方便用户按类型筛选列表项。此外,还详细介绍了如何在控制器中增加对类型ID的支持,并在模型中实现获取类型ID列表的功能。

在work的index中添加

 <div class="panel-heading">
        {:build_heading(null,FALSE)}
        <ul class="nav nav-tabs" data-field="type_id">
            <li class="active"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
            {foreach name="typeIdList" item="vo"}
            <li><a href="#t-{$key}" data-value="{$key}"  data-toggle="tab">{$vo}</a></li>
            {/foreach}
        </ul>
    </div>

在work的controll的_initialize方法最后一行添加

$this->view->assign("typeIdList", $this->model->getTypeIdList());

在work的model中添加

 public function getTypeIdList()
    {
        $list = TypeModel::select();
        $temp = [];
        foreach($list as $k=>$vo){
            $a1=array($vo['id']=>$vo['name']);
            $temp = $temp+$a1;
        }
        return $temp;
    }

最后,还要在work的js中,添加type_id的operate: 'LIKE'

 {field: 'type_id', title: __('Type_id'),operate: 'LIKE',},

如果需要在work列表中,显示_id的中文

在work的controll中添加type类,重写index方法

use app\admin\model\Type as TypeModel;

 public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags']);
        if ($this->request->isAjax())
        {

            //如果发送的来源是Selectpage,则转发到Selectpage
            if ($this->request->request('keyField'))
            {
                return $this->selectpage();
            }

            $typeName = TypeModel::column('id,name');

            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $this->model
                ->where($where)
                ->order($sort, $order)
                ->count();

            $list = $this->model
                ->where($where)
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();

            $list = collection($list)->toArray();

            foreach ($list as $k => &$v)
            {
                $v['type_text'] = isset($typeName[$v['type_id']]) ? $typeName[$v['type_id']] : "";
        
            }
            unset($v);
            $result = array("total" => $total, "rows" => $list);

            return json($result);
        }
        return $this->view->fetch();
    }

然后在对应的js中

{field: 'type_text', title: __('type_id'),operate: false,formatter: Table.api.formatter.label},

帮我用pyqt写一个程序,功能是发订单以及交互,适配底层agv系统;具体需求 1.初始化的时候,加载一下pg数据库的layer1_agv.agv表,根据字段agv_dispatch_type分车型,得到每个车型有几个车,agv表的结构是CREATE TABLE IF NOT EXISTS layer1_agv.agv ( id integer NOT NULL DEFAULT nextval('agv_id_seq'::regclass), agv_type_id integer NOT NULL, agv_name character varying(20) COLLATE pg_catalog."default" NOT NULL, mac_address macaddr, ip_address inet, agv_shell_port integer, agv_control_port integer, created_user character varying(200) COLLATE pg_catalog."default", created_timestamp timestamp with time zone DEFAULT now(), last_updated_user character varying(200) COLLATE pg_catalog."default", last_updated_timestamp timestamp with time zone DEFAULT now(), agv_layout_id integer, agv_simulation_flg integer, jess_port integer, max_traffic_distance double precision, vehicle_report_port integer, agv_dispatch_type integer, CONSTRAINT agv_pk PRIMARY KEY (id), CONSTRAINT agv_uk01 UNIQUE (agv_name), CONSTRAINT agv_uk02 UNIQUE (mac_address), CONSTRAINT agv_fk01 FOREIGN KEY (agv_type_id) REFERENCES layer1_agv.agv_type (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION ); 2.加载layer2_pallet.location表,根据agv_type字段分类,得到每个agv_type下面的location内容,location表的字段如下CREATE TABLE IF NOT EXISTS layer2_pallet.location ( id integer NOT NULL DEFAULT nextval('location_id_seq'::regclass), location_type_id integer, location_name character varying(200) COLLATE pg_catalog."default" NOT NULL, layout_dock_id integer, shelf_layer integer, active boolean NOT NULL DEFAULT true, physical_label character varying(200) COLLATE pg_catalog."default", posture_type_id integer, created_user character varying(200) COLLATE pg_catalog."default", created_timestamp timestamp with time zone DEFAULT now(), last_updated_user character varying(200) COLLATE pg_catalog."default", last_updated_timestamp timestamp with time zone DEFAULT now(), operation_parameter_fetch integer, operation_parameter_put integer, center_pos_x double precision, center_pos_y double precision, length double precision, width double precision, height double precision, is_leaf boolean, priority double precision, exit_dock_id integer, can_put boolean DEFAULT true, is_booked boolean DEFAULT false, parameter_json jsonb, rest_active boolean NOT NULL DEFAULT true, agv_type character varying(200) COLLATE pg_catalog."default", angle double precision, CONSTRAINT location_pk PRIMARY KEY (id), CONSTRAINT location_uk UNIQUE (location_name), CONSTRAINT location_fk01 FOREIGN KEY (location_type_id) REFERENCES layer2_pallet.location_type (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT location_fk02 FOREIGN KEY (posture_type_id) REFERENCES layer2_pallet.posture_type (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION ) 3.获取到内容后,有一个map来匹配agv表的agv_dispatch_type和location表的agv_type,这个预留,我来写就可以了 4.发单程序逻辑,每个车型一个携程去发单,比如说1车型,他下面有几个正常状态的车,就确保该车型的订单数量是否达到车数,没达到就创建,达到就不创建,查询正常状态的车是从layer1_agv.agv_state表里查询,判断agv_management_status_id是7或者9代表正常,这个正常的车数是动态更新的;查询当前活跃订单是从数据库layer4_1_om."order"表里面查询,判断status字段是在waiting/active的情况下是活跃订单 5.现在开始分任务的参数,其中A8车和Fork车都很简单,是点到点,就是一个起点location到终点location,所以要从location表里面分类成起点和终点即可,但是尽量一次循环内,把所有的站台都跑到 6.现在开始下发A8车和Fork车的任务,这个比较简单,是点到点,就是一个起点location到终点location,按照第5点的分类来下发,下发的url是http://127.0.0.1/api/om/order/,post请求,参数可以参考如下{ "order_name": "No101", "priority": 1, "dead_line": "2024-1-30 15:15:30", "ts_name": "p2p", "parameters": "{\"src\":\"Work16\",\"dst\":\"Work28\",\"carrier_type_id\":-99,\"agv_type\":"1,2,3,4,"}", "created_user": "WCS" },其中src填起点,dst填终点location,其余参数固定就可以了,返回的参数是{ "app_name": "Guozi client", "version": "1.0.0", "code": 0, "msg": "success", "data": [ { "in_order_id": 1 //订单id,唯一,创建任务时反馈给用户 } ] },其中的in_order_id作为这个订单的状态反馈的标识字段; 7.新增接口用于任务状态反馈,url是当前程序的ip端口加上/orderStatusReport/,判断返回的orderStatus是finish代表orderID这个订单完成啦。收到信息的参数参考如下是{ "orderID": 2, "orderName": "order_name", "orderStatus": "source_finish", "agvIDList": "1", "priority": 2, "currentDes": "work1", "currentCmd": "poll_task_finished 190", "errorCode": 0, "extraInfo1": "", "extraInfo2": "", "deadLine": "2023-12-28 13: 46: 22", "createdTime": "2024-01-07 10: 03: 41", "createdUser": "admin", "StatusChangeTime": "2024-01-07 10: 08: 16" } 8.现在开始做辊道车的任务,这个比较复杂,因为辊道车是两层,每层两个口,所以就有多种动作类型,比如我们以车头朝向为例上层的位置是2A,2B,下层的位置是1A,1B,A是车头侧,下发订单的url和上面的一样,但是下发的内容不一样,示例1:请求示例body 去库位Work8取一个货物到上层2B储位,参数是{ "order_name": "No101", "priority": 1, "dead_line": "2024-1-30 15:15:30", "ts_name": "roller_ts_ly", "parameters": "{\"dst\": \"Work8\",\"posture\": \"tail\",\"agv_id\": \"1\",\"is_lock\": \"false\",\"is_large_size\":\"true\",\"actions\": \"[{\\\"cell_name\\\": \\\"2B\\\",\\\"type\\\": \\\"fetch\\\",\\\"seq\\\": 1}]\"}", "created_user": "WCS" };示例2:请求示例body 先后取两个货物上层2B、2A储位,参数是{   "order_name": "No101",   "priority": 1,   "dead_line": "2024-1-30 15:15:30",   "ts_name": "roller_ts_ly",   "parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":\"[{\\\"cell_name\\\":\\\"2B\\\",\\\"type\\\":\\\"fetch\\\",\\\"seq\\\":1},{\\\"cell_name\\\":\\\"2A\\\",\\\"type\\\":\\\"fetch\\\",\\\"seq\\\":2}]\" }",   "created_user": "WCS" };示例3:请求示例body 下层1A储位卸一个货物,参数是{   "order_name": "No101",   "priority": 1,   "dead_line": "2024-1-30 15:15:30",   "ts_name": "roller_ts_ly",   "parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":\"[{\\\"cell_name\\\":\\\"1A\\\",\\\"type\\\":\\\"put\\\",\\\"seq\\\":1}]\" }",   "created_user": "WCS" };示例4:请求示例body 下层1A、1B储位先后卸两个货物,参数是{   "order_name": "No101",   "priority": 1,   "dead_line": "2024-1-30 15:15:30",   "ts_name": "roller_p",   "parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":[{\"cell_name\":\"1A\",\"type\":\"put\",\"seq\":1},{\"cell_name\":\"1B\",\"type\":\"put\",\"seq\":2}] }",   "created_user": "WCS" },示例5:请求示例body 上层2A卸一个货物,同时下层1B取一个货物,参数是{   "order_name": "No101",   "priority": 1,   "dead_line": "2024-1-30 15:15:30",   "ts_name": "roller_p",   "parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1,2,3\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":\"[{\\\"cell_name\\\":\\\"2A\\\",\\\"type\\\":\\\"put\\\",\\\"seq\\\":1},{\\\"cell_name\\\":\\\"1B\\\",\\\"type\\\":\\\"fetch\\\",\\\"seq\\\":1}]\" }",   "created_user": "WCS" }。示例如上,返回的参数和A8的一致; 9.辊道车第一个特殊点是,这个车可以先取一个货,再取一个货,最终一次性卸两个,也可以去一个站台取货+卸货同时做; 10.辊道车第二个特殊点是,is_lock字段和agv_id字段,is_lock字段,是比如我从work1取货到1A,这个车卸货之前,下发的订单不管是取货,还是卸货is_lock都是True,车号通过订单状态推送的agvIDList字段来获取,只会有一个车,所以我们辊道车的任务应该是第一个任务不指定车,第二个开始指定车(指定的是第一个车去接着取货/卸货) 11.辊道车要考虑到车头和车尾以及位置,不要出现1A取货后,卸货从2B来这样离谱的场景,以及车头1A取货后,又从车头取货到1B这样离谱的情况,考虑实际位置是否被阻挡 12.整体框架用fastapi,需要有pyqt界面,记录下发了哪些库位,当前完成的订单,每个订单从发出到完成的耗时 13.完整日志写到界面上,保证代码的茁壮和优雅 相信你,csdn,一次性帮我搞定!
10-28
你提供了一个包含多个字段的表结构,其中 `id` 是主键。我们基于这个信息生成 **批量插入或更新(Upsert)语句**,适用于常见的数据库系统。 我们将以 **MySQL** 为例(使用 `ON DUPLICATE KEY UPDATE`),并附上 PostgreSQL 和 SQLite 的等价写法。 --- ### ✅ 假设 - 表名为:`ics_declared_work`(你可以根据实际名称修改) - 所有字段均可更新(除 `id` 外) - 使用 `id` 作为唯一主键进行判断是否已存在 - 提供的数据是多条记录 --- ## ✅ 1. MySQL 批量插入或更新(推荐) ```sql INSERT INTO ics_declared_work ( id, area_name, work_num, work_name, team_id, area_id, cnpec_user, create_by, non_work_time_flag, work_level, work_status, create_date, management_user, work_first_time, h_point_id, work_code, company_id, department_id, department_name, work_type, end_time, three_new_flag, team_name, update_date, start_time, safety_user, great_danger, company_name, name, secluded_flag, full_name, date_name ) VALUES (1, '区域A', 'W001', '焊接作业', 'T001', 101, '张三', 'admin', 0, '高风险', 'IN_PROGRESS', '2025-04-01 08:00:00', '李四', '2025-04-01 07:30:00', NULL, 'WC001', 1, 10, '工程部', '动火作业', '2025-04-01 18:00:00', 1, '焊工一组', '2025-04-01 19:00:00', '2025-04-01 08:00:00', '王五', '重大危险源', 'XX建设公司', '焊接任务1', 1, '焊接作业-焊工一组-20250401', '白天'), (2, '区域B', 'W002', '高空作业', 'T002', 102, '李四', 'user1', 1, '中风险', 'END', '2025-04-02 08:00:00', '赵六', '2025-04-02 07:45:00', 1001, 'WC002', 1, 11, '安全部', '高处作业', '2025-04-02 17:00:00', 0, '高空组', '2025-04-02 17:30:00', '2025-04-02 08:00:00', '钱七', NULL, 'XX建设公司', '高空任务1', 0, '高空作业-高空组-20250402', '白天') -- 可继续添加更多行... ON DUPLICATE KEY UPDATE area_name = VALUES(area_name), work_num = VALUES(work_num), work_name = VALUES(work_name), team_id = VALUES(team_id), area_id = VALUES(area_id), cnpec_user = VALUES(cnpec_user), create_by = VALUES(create_by), non_work_time_flag = VALUES(non_work_time_flag), work_level = VALUES(work_level), work_status = VALUES(work_status), create_date = VALUES(create_date), management_user = VALUES(management_user), work_first_time = VALUES(work_first_time), h_point_id = VALUES(h_point_id), work_code = VALUES(work_code), company_id = VALUES(company_id), department_id = VALUES(department_id), department_name = VALUES(department_name), work_type = VALUES(work_type), end_time = VALUES(end_time), three_new_flag = VALUES(three_new_flag), team_name = VALUES(team_name), update_date = VALUES(update_date), start_time = VALUES(start_time), safety_user = VALUES(safety_user), great_danger = VALUES(great_danger), company_name = VALUES(company_name), name = VALUES(name), secluded_flag = VALUES(secluded_flag), full_name = VALUES(full_name), date_name = VALUES(date_name); ``` > 🔍 **说明:** > - `VALUES(col)` 表示本次插入的值 > - 如果某条记录的 `id` 已存在,则执行后面的 `UPDATE` > - 要求 `id` 字段上有主键或唯一索引 --- ## ✅ 2. PostgreSQL 批量 Upsert(使用 `ON CONFLICT`) ```sql INSERT INTO ics_declared_work ( id, area_name, work_num, work_name, team_id, area_id, cnpec_user, create_by, non_work_time_flag, work_level, work_status, create_date, management_user, work_first_time, h_point_id, work_code, company_id, department_id, department_name, work_type, end_time, three_new_flag, team_name, update_date, start_time, safety_user, great_danger, company_name, name, secluded_flag, full_name, date_name ) VALUES (1, '区域A', 'W001', '焊接作业', 'T001', 101, '张三', 'admin', 0, '高风险', 'IN_PROGRESS', '2025-04-01 08:00:00', '李四', '2025-04-01 07:30:00', NULL, 'WC001', 1, 10, '工程部', '动火作业', '2025-04-01 18:00:00', 1, '焊工一组', '2025-04-01 19:00:00', '2025-04-01 08:00:00', '王五', '重大危险源', 'XX建设公司', '焊接任务1', 1, '焊接作业-焊工一组-20250401', '白天'), (2, '区域B', 'W002', '高空作业', 'T002', 102, '李四', 'user1', 1, '中风险', 'END', '2025-04-02 08:00:00', '赵六', '2025-04-02 07:45:00', 1001, 'WC002', 1, 11, '安全部', '高处作业', '2025-04-02 17:00:00', 0, '高空组', '2025-04-02 17:30:00', '2025-04-02 08:00:00', '钱七', NULL, 'XX建设公司', '高空任务1', 0, '高空作业-高空组-20250402', '白天') ON CONFLICT (id) DO UPDATE SET area_name = EXCLUDED.area_name, work_num = EXCLUDED.work_num, work_name = EXCLUDED.work_name, team_id = EXCLUDED.team_id, area_id = EXCLUDED.area_id, cnpec_user = EXCLUDED.cnpec_user, create_by = EXCLUDED.create_by, non_work_time_flag = EXCLUDED.non_work_time_flag, work_level = EXCLUDED.work_level, work_status = EXCLUDED.work_status, create_date = EXCLUDED.create_date, management_user = EXCLUDED.management_user, work_first_time = EXCLUDED.work_first_time, h_point_id = EXCLUDED.h_point_id, work_code = EXCLUDED.work_code, company_id = EXCLUDED.company_id, department_id = EXCLUDED.department_id, department_name = EXCLUDED.department_name, work_type = EXCLUDED.work_type, end_time = EXCLUDED.end_time, three_new_flag = EXCLUDED.three_new_flag, team_name = EXCLUDED.team_name, update_date = EXCLUDED.update_date, start_time = EXCLUDED.start_time, safety_user = EXCLUDED.safety_user, great_danger = EXCLUDED.great_danger, company_name = EXCLUDED.company_name, name = EXCLUDED.name, secluded_flag = EXCLUDED.secluded_flag, full_name = EXCLUDED.full_name, date_name = EXCLUDED.date_name; ``` > ⚠️ 注意:PostgreSQL 使用 `EXCLUDED` 代表新插入的行 --- ## ✅ 3. SQLite 批量 Upsert(使用 `REPLACE INTO` 或 `INSERT OR REPLACE`) 如果你的数据完全由 `id` 决定唯一性,可以用: ```sql INSERT OR REPLACE INTO ics_declared_work ( id, area_name, work_num, work_name, team_id, area_id, cnpec_user, create_by, non_work_time_flag, work_level, work_status, create_date, management_user, work_first_time, h_point_id, work_code, company_id, department_id, department_name, work_type, end_time, three_new_flag, team_name, update_date, start_time, safety_user, great_danger, company_name, name, secluded_flag, full_name, date_name ) VALUES (1, '区域A', 'W001', '焊接作业', 'T001', 101, '张三', 'admin', 0, '高风险', 'IN_PROGRESS', '2025-04-01 08:00:00', '李四', '2025-04-01 07:30:00', NULL, 'WC001', 1, 10, '工程部', '动火作业', '2025-04-01 18:00:00', 1, '焊工一组', '2025-04-01 19:00:00', '2025-04-01 08:00:00', '王五', '重大危险源', 'XX建设公司', '焊接任务1', 1, '焊接作业-焊工一组-20250401', '白天'), (2, '区域B', 'W002', '高空作业', 'T002', 102, '李四', 'user1', 1, '中风险', 'END', '2025-04-02 08:00:00', '赵六', '2025-04-02 07:45:00', 1001, 'WC002', 1, 11, '安全部', '高处作业', '2025-04-02 17:00:00', 0, '高空组', '2025-04-02 17:30:00', '2025-04-02 08:00:00', '钱七', NULL, 'XX建设公司', '高空任务1', 0, '高空作业-高空组-20250402', '白天'); ``` > ❗注意:`INSERT OR REPLACE` 会先删除再插入,如果有关联外键需谨慎。 --- ## ✅ 动态生成工具建议(用于程序中) 如果你是在 Java / Python 中动态生成这类 SQL,可以这样做: ### Python 示例(构建 VALUES 部分) ```python fields = [ "id", "area_name", "work_num", "work_name", "team_id", "area_id", "cnpec_user", "create_by", "non_work_time_flag", "work_level", "work_status", "create_date", "management_user", "work_first_time", "h_point_id", "work_code", "company_id", "department_id", "department_name", "work_type", "end_time", "three_new_flag", "team_name", "update_date", "start_time", "safety_user", "great_danger", "company_name", "name", "secluded_flag", "full_name", "date_name" ] def gen_value_placeholders(data_list): placeholders = [] for row in data_list: ph = "(" + ", ".join(f"'{v}'" if v is not None else "NULL" for v in row) + ")" placeholders.append(ph) return ",\n".join(placeholders) # 示例数据 data = [ (1, '区域A', 'W001', ...), (2, '区域B', 'W002', ...) ] values_sql = gen_value_placeholders(data) ``` 然后拼接到完整 SQL 中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值