Accept Merge Request #13: (feature/hant -> develop)

Merge Request: 派单

Created By: @todayswind
Accepted By: @todayswind
URL: https://g-bcrc3009.coding.net/p/allocatr/d/allocatr/git/merge/13?initial=true
This commit is contained in:
todayswind 2025-03-14 22:32:41 +08:00 committed by Coding
commit e73065e9c6
11 changed files with 380 additions and 91 deletions

View File

@ -100,19 +100,31 @@ class Dispatch extends Backend
if (!$order) {
$this->error(__('No results were found'));
}
$code = $this->getSelectAreaCode(substr_replace($order->area_id, '00', -2));
$workers = model('worker')
->where('area_id','like', $code.'%')
->where('status',1)
->field(['id','name','tel','area_id','lng','lat'])
->select();
$items = Db::name('item')
->where('status',1)
->field(['id','title','key_word','pid'])
->order('pid','asc')
->order('sort','desc')
->select();
$filtered = array_filter($items, function($item) {
return $item['pid'] == 0;
});
$pid_map = array_column($filtered,null,'id');
$res_items = [];
foreach ($items as $item){
if ($item['pid'] != 0 && isset($pid_map[$item['pid']])){
$res_items [] = [
...$item,'ptitle' => $pid_map[$item['pid']]['title']
];
}
}
$area_name = model('area')->getNameByCode($order->area_id);
$order->area_name = str_replace(',','/',$area_name);
$workers = $this->getWorkers($workers);
$this->view->assign('workers', $workers);
$this->view->assign('items', $res_items);
$this->view->assign('row', $order);
return $this->view->fetch();

View File

@ -79,14 +79,28 @@ class Worker extends Backend
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$area_code = request()->get('area_code');
$area_code = request()->get('area_id');
$item_id = request()->get('item_id');
$keyword = request()->get('keyword');
$build = $this->model
->with(['area'])
->where($where)
->field('worker.id,name,tel,area_id,create_time,deposit_amount,update_time,status,star')
->order($sort, $order);
if ($keyword){
$build->where(function ($q) use ($keyword) {
$q->where('name','like','%'.$keyword.'%')->whereOr('tel','like','%'.$keyword.'%');
});
}
if ($item_id){
$build->join('worker_item','worker_item.worker_id = worker.id','left');
$build->where('worker_item.item_id',$item_id);
}
if ($area_code){
$build->where('area_id','like',$this->getSelectAreaCode($area_code).'%');
}
$list = $build
->paginate($limit);
@ -94,6 +108,27 @@ class Worker extends Backend
return json($result);
}
$items = Db::name('item')
->where('status',1)
->field(['id','title','key_word','pid'])
->order('pid','asc')
->order('sort','desc')
->select();
$filtered = array_filter($items, function($item) {
return $item['pid'] == 0;
});
$pid_map = array_column($filtered,null,'id');
$res_items = [];
foreach ($items as $item){
if ($item['pid'] != 0 && isset($pid_map[$item['pid']])){
$res_items [] = [
...$item,'ptitle' => $pid_map[$item['pid']]['title']
];
}
}
$this->view->assign('items', $res_items);
return $this->view->fetch();
}
@ -190,7 +225,7 @@ class Worker extends Backend
];
}
model('WorkerItem')->where('worker_id',$ids)->delete();
model('WorkerItem')->batchInsert($insert);
model('WorkerItem')->insertAll($insert);
}
}
unset($params['rules']);
@ -220,4 +255,27 @@ class Worker extends Backend
return $this->fetch();
}
public function dispatchList(){
$area_id = request()->get('area_id');
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$build = model('worker')
->where('status',1)
->with(['area'])
->field(['id','name','tel','area_id','lng','lat']);
if ($area_id){
$code = $this->getSelectAreaCode(substr_replace($area_id, '00', -2));
$build->where('area_id','like', $code.'%');
}
$list = $build
->paginate($limit);
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
}

View File

@ -2,6 +2,7 @@
namespace app\admin\model;
use think\Db;
use think\Model;
@ -50,6 +51,31 @@ class Item extends Model
}
public function getList(){
$items = $this
->where('status',1)
->field(['id','title','key_word','pid'])
->order('pid','asc')
->order('sort','desc')
->select();
$this->items = $items;
$filtered = array_filter($items, function($item) {
return $item['pid'] == 0;
});
$pid_map = array_column($filtered,null,'id');
$res_items = [];
foreach ($items as $item){
if ($item['pid'] != 0 && isset($pid_map[$item['pid']])){
$res_items [] = [
...$item,'ptitle' => $pid_map[$item['pid']]['title']
];
}
}
return $res_items;
}
}

View File

@ -1,77 +1,145 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="row">
<div class="col-md-4">
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Customer')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-customer" data-rule="required" disabled class="form-control" type="text" value="{$row.customer}">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Customer')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-customer" data-rule="required" disabled class="form-control" type="text" value="{$row.customer}">
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Tel')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-tel" data-rule="required" disabled class="form-control" type="number" value="{$row.tel}">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Tel')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-tel" data-rule="required" disabled class="form-control" type="number" value="{$row.tel}">
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Area_id')}:</label>
<div class='col-xs-12 col-sm-8'>
<input id="c-city" data-rule="required" class="form-control" value="{$row.area_name}" disabled type="text" />
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Area_id')}:</label>
<div class='col-xs-12 col-sm-8'>
<input id="c-city" data-rule="required" class="form-control" value="{$row.area_name}" disabled type="text" />
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Address')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-address" data-rule="required" disabled class="form-control" name="row[address]" type="text">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Address')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-address" data-rule="required" disabled value="{$row.address}" class="form-control" name="row[address]" type="text">
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Detail')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-detail" disabled rows="4" style="width: 100%;resize: vertical" class="form-control">{$row.detail}</textarea>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">服务类型</label>
<div class="col-xs-12 col-sm-8">
<input id="c-item_title" data-rule="required" value="{$row.item_title}" disabled class="form-control" name="row[item_title]" type="text">
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Remark')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-remark" disabled rows="4" style="width: 100%;resize: vertical" class="form-control" >{$row.remark}</textarea>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Detail')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-detail" disabled rows="4" style="width: 100%;resize: vertical" class="form-control">{$row.detail}</textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Remark')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-remark" disabled rows="4" style="width: 100%;resize: vertical" class="form-control" >{$row.remark}</textarea>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Order_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-order_id" data-rule="required" data-field="order_no" disabled class="form-control" name="row[order_id]" type="text" value="{$row->order_no}">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Order_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-order_id" data-rule="required" data-field="order_no" disabled class="form-control" name="row[order_no]" type="text" value="{$row->order_no}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">师傅名称:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-worker_name" disabled data-rule="required" class="form-control" name="row[worker_name]" type="text">
<input id="c-worker_id" class="form-control" style="display: none" name="row[worker_id]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-3">{:__('Plan_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-update_time" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[plan_time]" type="text" value="{:date('Y-m-d H:i:s')}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-3"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
<input style="display: none" class="form-control" name="row[order_id]" type="text" value="{$row->id}">
</form>
</div>
<div class="col-md-8">
<div class="panel panel-default panel-intro">
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<h3>师傅选择</h3>
<!-- <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>-->
<form id="select-form" role="form" class="form-horizontal" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="col-xs-12 col-sm-2" style="padding-left: 0px;text-align: left">区域:</label>
<div style="display: inline-block;width: 300px;position: absolute">
<input id="c-city-search" data-rule="required" class="form-control" data-toggle="city-picker" value="{$row.area_name}" type="text" />
<input id="area_id" style="display: none" class="form-control" name="area_id" hidden type="text" value="{$row.area_id}" />
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-2" style="text-align: left;padding-left: 0px;">工种:</label>
<div style="width: 300px;display: inline-block;">
<select id="citem" data-live-search="true" title="请选择" value = "{$row.item_id}" name="item_id" class="form-control selectpicker show-tick">
<option value="0">不过滤</option>
{foreach $items as $item}
<option {if $item['id'] == $row.item_id} selected {/if} data-subtext="{$item['key_word']}" value="{$item['id']}">{$item['title']}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-2" style="padding-left: 0px;text-align: left">关键字:</label>
<div style="display: inline-block;width: 300px;position: absolute">
<input id="keyword" class="form-control" style="width: 100%;height: 32px" placeholder="名称或电话号码搜索" name="keyword" type="text" value="" />
</div>
</div>
<p id="search_btn" class="btn btn-primary">搜索</p>
<p id="reset_btn" class="btn btn-primary">清空</p>
</form>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Worker_id')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-source" data-live-search="true" title="请选择" data-rule="required" name="row[worker_id]" class="form-control selectpicker">
<!-- <option value="0">无可用工人</option>-->
{foreach $workers as $item}
<option data-subtext="电话:{$item['tel'].'-'.$item['dist'] }" value="{$item['id']}">{$item['name']}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Plan_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-update_time" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[plan_time]" type="text" value="{:date('Y-m-d H:i:s')}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
<input style="display: none" class="form-control" name="row[order_id]" type="text" value="{$row->id}">
</form>
</div>
<style>
.dropdown-menu {
position: absolute;
z-index: 1000;
width: 100%;
max-height: 300px;
overflow-y: auto;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
margin: 6px 12px;
}
#select-form .form-group{
margin-left: 0;
margin-right: 0;
}
</style>

View File

@ -32,16 +32,36 @@
<a class="btn btn-success btn-recyclebin btn-dialog {:$auth->check('workers/worker/recyclebin')?'':'hide'}" href="workers/worker/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>
<form id="select-form" class="form-inline" role="form" style="margin-top: 5px">
<div class='form-group'>
<label style="padding-left: 0px;text-align: left">{:__('Area_id')}:</label>
<div style="display: inline-block;width: 300px;margin-left: 5px">
<input id="c-city" style="width: 100%;height: 32px" data-toggle="city-picker" name="row[address]" type="text" value="" />
<form id="select-form" style="padding-left: 15px;margin-top: 10px" role="form" class="form-horizontal" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="col-xs-12 col-sm-2" style="padding-left: 0px;text-align: left">区域:</label>
<div style="display: inline-block;width: 300px;position: absolute">
<input id="c-city-search" data-rule="required" class="form-control" data-toggle="city-picker" type="text" />
<input id="area_id" style="display: none" class="form-control" name="area_id" hidden type="text" />
</div>
<p id="reset" style="display: inline-block;margin-bottom: 2px;" class="btn btn-default">重置</p>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-2" style="text-align: left;padding-left: 0px;">工种:</label>
<div style="width: 300px;display: inline-block;">
<select id="citem" data-live-search="true" title="请选择" name="item_id" class="form-control selectpicker show-tick">
<option value="0">不过滤</option>
{foreach $items as $item}
<option value="{$item['id']}">{$item['title']}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-2" style="padding-left: 0px;text-align: left">关键字:</label>
<div style="display: inline-block;width: 300px;position: absolute">
<input id="keyword" class="form-control" style="width: 100%;height: 32px" placeholder="名称或电话号码搜索" name="keyword" type="text" value="" />
</div>
</div>
<p id="search_btn" class="btn btn-primary">搜索</p>
<p id="reset_btn" class="btn btn-primary">清空</p>
</form>
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="{:$auth->check('workers/worker/edit')}"

View File

@ -164,6 +164,80 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form','layer'], function ($,
Table.api.bindevent(table);
},
add: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'workers/worker/dispatchList',
table: 'worker',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url +'?' + getQueryData(),
pk: 'id',
sortName: 'id',
fixedColumns: true,
fixedRightNumber: 1,
columns: [
[
// {checkbox: true},
{field: 'id', title: __('Id')},
{field: 'name', title: __('Name'), operate: 'LIKE'},
{field: 'tel', title: __('Tel'), operate: 'LIKE'},
// {field: 'status', title: __('Status'), searchList: {"1":__('Status 1'),"0":__('Status 0')}, formatter: Table.api.formatter.status},
//{field: 'area_id', title: __('Area_id')},
//{field: 'lng', title: __('Lng'), operate:'BETWEEN'},
//{field: 'lat', title: __('Lat'), operate:'BETWEEN'},
{field: 'area.short_merge_name', title: __('Area.short_merge_name'), operate: 'LIKE'},
// {field: 'deposit_amount', title: __('Deposit_amount'), operate:'BETWEEN'},
{field: 'id', title: '操作',formatter:function (id) {
return `<p class="btn btn-primary tab_chose" data-id="${id}">选择</p>`;
}},
]
],
search:false,
commonSearch:false,
});
function getQueryData(){
return $('#select-form').serialize();
}
$("#c-city-search").on("cp:updated", function() {
var citypicker = $(this).data("citypicker");
var code = citypicker.getCode("district") || citypicker.getCode("city") || citypicker.getCode("province");
// table.bootstrapTable('refresh',{query: {area_code: code}});
$('#area_id').val(code);
});
$("#search_btn").on("click", function() {
table.bootstrapTable('refresh',{
url:$.fn.bootstrapTable.defaults.extend.index_url +'?' + getQueryData(),
});
});
$("#reset_btn").on("click", function() {
$("#c-city-search").citypicker('reset');
$("#area_id").val('');
$("#citem").val('').selectpicker('refresh');
$("#keyword").val('');
console.log(1);
table.bootstrapTable('refresh',{
url:$.fn.bootstrapTable.defaults.extend.index_url +'?' + getQueryData(),
});
});
Form.events.citypicker($("#select-form"));
$(document).on('click', '.tab_chose', function() {
var dataId = $(this).data('id'); // 获取 data-id 的值
const worker = Table.api.getrowbyid(table ,dataId);
$('#c-worker_name').val(worker.name + '--' + worker.tel).trigger('input').trigger('change');
$('#c-worker_id').val(worker.id).trigger('input').trigger('change');
});
// 为表格绑定事件
Table.api.bindevent(table);
Controller.api.bindevent();
},
edit: function () {
@ -171,7 +245,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form','layer'], function ($,
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
Form.api.bindevent($("#add-form"),null,null,function (data) {
// Form.api.submit($("#add-form"));
// return false;
});
Form.api.bindevent($("#select-form"));
}
}
};

View File

@ -57,15 +57,31 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form','jstree'], function ($
]
]
});
$("#c-city").on("cp:updated", function() {
$("#c-city-search").on("cp:updated", function() {
var citypicker = $(this).data("citypicker");
var code = citypicker.getCode("district") || citypicker.getCode("city") || citypicker.getCode("province");
table.bootstrapTable('refresh',{query: {area_code: code}});
// table.bootstrapTable('refresh',{query: {area_code: code}});
$('#area_id').val(code);
});
$("#reset").on("click", function() {
$("#c-city").citypicker('reset');
table.bootstrapTable('refresh');
$("#search_btn").on("click", function() {
table.bootstrapTable('refresh',{
url:$.fn.bootstrapTable.defaults.extend.index_url +'&' + getQueryData(),
});
});
function getQueryData(){
return $('#select-form').serialize();
}
$("#reset_btn").on("click", function() {
$("#c-city-search").citypicker('reset');
$("#area_id").val('');
$("#citem").val('').selectpicker('refresh');
$("#keyword").val('');
table.bootstrapTable('refresh',{
url:$.fn.bootstrapTable.defaults.extend.index_url +'?' + getQueryData(),
});
});
Form.events.citypicker($("#select-form"));
// 为表格绑定事件
Table.api.bindevent(table);

View File

@ -1068,7 +1068,8 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
getrowbyid: function (table, id) {
var row = {};
var options = table.bootstrapTable("getOptions");
$.each(Table.api.selecteddata(table), function (i, j) {
var data = table.bootstrapTable('getData');
$.each(data, function (i, j) {
if (j[options.pk] == id) {
row = j;
return false;

View File

@ -30,6 +30,16 @@
background: url(../images/drop-arrow.png) -10px -25px no-repeat;
}
.city-picker-span > .close {
position: absolute;
top: 50%;
right: 24px;
width: 10px;
margin-top: -12px;
font-size: 20px;
height: 5px;
}
.city-picker-span.focus,
.city-picker-span.open {
border-bottom-color: #46A4FF;

View File

@ -73,7 +73,7 @@
this.getWidthStyle(p.width) + 'height:' +
p.height + 'px;line-height:' + (p.height - 1) + 'px;">' +
(placeholder ? '<span class="placeholder">' + placeholder + '</span>' : '') +
'<span class="title"></span><div class="arrow"></div>' + '</span>',
'<span class="title"></span><div class="arrow"></div> <div class="close">X</div>' + '</span>',
dropdown = '<div class="city-picker-dropdown" style="left:0px;top:100%;' +
this.getWidthStyle(p.width, true) + '">' +

View File

@ -73,7 +73,7 @@
this.getWidthStyle(p.width) + 'height:' +
p.height + 'px;line-height:' + (p.height - 1) + 'px;">' +
(placeholder ? '<span class="placeholder">' + placeholder + '</span>' : '') +
'<span class="title"></span><div class="arrow"></div>' + '</span>',
'<span class="title"></span><div class="arrow"></div><div class="close">X</div>' + '</span>',
dropdown = '<div class="city-picker-dropdown" style="left:0px;top:100%;' +
this.getWidthStyle(p.width, true) + '">' +