Browse Source

fix:验货端

super-yimizi 1 week ago
parent
commit
3b3490fe53

+ 49 - 1
application/admin/controller/inspection/Application.php

@@ -45,7 +45,7 @@ class Application extends Backend
 
             foreach ($list as $item) {
                 $item->append(['audit_status_text', 'apply_time_text', 'audit_time_text']);
-                $item->user->visible(['id', 'username', 'nickname', 'mobile']);
+                $item->user->visible(['id', 'username','avatar','nickname', 'mobile']);
                 if ($item->supplier) {
                     $item->supplier->visible(['id', 'name', 'contact', 'mobile']);
                 }
@@ -74,6 +74,54 @@ class Application extends Backend
     }
 
     /**
+     * 编辑申请
+     */
+    public function edit($ids = null)
+    {
+        $row = $this->model->get($ids);
+        if (!$row) {
+            $this->error(__('No Results were found'));
+        }
+
+        // 只有审核中的申请才可以编辑
+        if ($row->audit_status != InspectionApplication::AUDIT_STATUS_PENDING) {
+            $this->error('只有审核中的申请才可以编辑');
+        }
+
+        if ($this->request->isPost()) {
+            $params = $this->request->post("row/a");
+            if ($params) {
+                // 验证必填字段
+                if (empty($params['name']) || empty($params['phone']) || empty($params['address'])) {
+                    $this->error('姓名、手机号、详细地址不能为空');
+                }
+
+                // 检查手机号是否被其他申请使用
+                if (InspectionApplication::isPhoneApplied($params['phone'], $ids)) {
+                    $this->error('该手机号已被其他用户申请');
+                }
+
+                $params = $this->preExcludeFields($params);
+                
+                // 过滤不允许编辑的字段
+                $allowedFields = ['name', 'phone', 'province_adcode', 'city_adcode', 'district_adcode', 'address', 'id_card', 'id_card_front', 'id_card_back'];
+                $params = array_intersect_key($params, array_flip($allowedFields));
+                
+                if ($row->allowField($allowedFields)->save($params) !== false) {
+                    $this->success();
+                } else {
+                    $this->error(__('No rows were updated'));
+                }
+            }
+            $this->error(__('Parameter %s can not be empty', ''));
+        }
+
+        $row->append(['audit_status_text', 'apply_time_text']);
+        $this->view->assign("row", $row);
+        return $this->view->fetch();
+    }
+
+    /**
      * 审核申请
      */
     public function audit($ids = null)

+ 1 - 1
application/admin/view/inspection/application/detail.html

@@ -17,7 +17,7 @@
                             <td>{$row.name}</td>
                         </tr>
                         <tr>
-                            <td>联系电话</td>
+                            <td>申请手机号</td>
                             <td>{$row.phone}</td>
                         </tr>
                         <tr>

+ 1 - 0
application/admin/view/inspection/application/index.html

@@ -33,6 +33,7 @@
                            data-operate-detail="{:$auth->check('inspection/application/detail')}"
                            data-operate-audit="{:$auth->check('inspection/application/audit')}"
                            data-operate-del="{:$auth->check('inspection/application/del')}"
+                           data-operate-multi="{:$auth->check('inspection/application/multi')}"
                            width="100%">
                     </table>
                 </div>

+ 2 - 41
application/api/controller/inspection/Base.php

@@ -2,13 +2,8 @@
 
 namespace app\api\controller\inspection;
 
-use app\common\controller\Api;
-use app\common\library\Auth;
-use think\Config;
-use think\Lang;
-use app\common\Service\InspectionService;
-use app\common\model\inspection\InspectionApplication;
-class Base extends Api
+use app\common\controller\InspectionApi;
+class Base extends InspectionApi
 {
     protected $noNeedLogin = [];
     protected $noNeedRight = ['*'];
@@ -19,41 +14,7 @@ class Base extends Api
 
     public function _initialize()
     {
-
-        if (isset($_SERVER['HTTP_ORIGIN'])) {
-            header('Access-Control-Expose-Headers: __token__');//跨域让客户端获取到
-        }
-        //跨域检测
-        check_cors_request();
-
-        if (!isset($_COOKIE['PHPSESSID'])) {
-            Config::set('session.id', $this->request->server("HTTP_SID"));
-        }
         parent::_initialize();
-        Auth::instance()->setAllowFields($this->allowFields);
-        // 查询是否是审核员
-        $user = Auth::instance()->getUser();
-        $isInspection = null;
-        if ($user) {
-            $isInspection = InspectionService::getUserApplication($user->id);
-            if (!$isInspection) {
-              $this->error('您不是审核员');
-            }       
-            //  验证是否 通过
-            if ($isInspection->audit_status !== InspectionApplication::AUDIT_STATUS_PASSED) {
-              $this->error('您的验货员申请未通过');
-            }
-        }    
-       
-       $this->application = $isInspection;
-        //这里手动载入语言包
-        Lang::load(ROOT_PATH . '/addons/shop/lang/zh-cn.php');
-        Lang::load(APP_PATH . '/index/lang/zh-cn/user.php');
-        //加载当前控制器的语言包
-        $controllername = strtolower($this->request->controller());
-        $lang = $this->request->langset();
-        $lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
-        Lang::load(ADDON_PATH . 'shop/lang/' . $lang . '/' . str_replace('.', '/', $controllername) . '.php');
     }
 
 }

+ 28 - 32
application/api/controller/inspection/User.php

@@ -10,7 +10,6 @@ use app\common\Enum\StatusEnum;
 use app\common\Service\InspectionService;
 use app\common\model\inspection\InspectionApplication;
 use app\common\Service\SupplierService;
-use app\common\model\User as UserModel;
 /**
  * 会员
  */
@@ -47,32 +46,32 @@ class User extends Base
                 $this->error(__('Captcha is incorrect'));
             }
         }
-        $user = UserModel::getByMobile($mobile);
-        if(!$user){
-            $this->error(__('Account does not exist'));
+        $inspection = InspectionApplication::getByPhone($mobile);
+        if(!$inspection){
+            $this->error(__('验货员不存在'));
         }
-        if ($user) {
-            if ($user->status != StatusEnum::ENABLED) {
-                $this->error(__('Account is locked'));
-            }
-            $isInspection = InspectionService::getUserApplication($user->id);
-            if (!$isInspection) {
-            $this->error('您不是审核员');
+        if ($inspection) {
+            if ($inspection->status != StatusEnum::ENABLED) {
+                $this->error(__('验货员账号已锁定'));
             }
+            // $isInspection = InspectionService::getUserApplication($user->id);
+            // if (!$isInspection) {
+            // $this->error('您不是审核员');
+            // }
             //  验证是否 通过
-            if ($isInspection->audit_status !== InspectionApplication::AUDIT_STATUS_PASSED) {
+            if ($inspection->audit_status != InspectionApplication::AUDIT_STATUS_PASSED) {
             $this->error('您的验货员申请未通过');
             } 
             // 验证是否 绑定供应商
-            if (!$isInspection->supplier_id) {
+            if (!$inspection->supplier_id) {
                 $this->error('您未绑定供应商');
             }
             //如果已经有账号则直接登录
-            $ret = $this->auth->direct($user->id);
+            $ret = $this->auth->direct($inspection->id);
         }   
         if ($ret) {
             Sms::flush($mobile, 'mobilelogin');
-            $user = $this->auth->getUserinfo();
+            $user = $this->auth->getInspectorInfo();
             $user['avatar'] = cdnurl($user['avatar'], true);
             $data = ['token' => $this->auth->getToken(), 'user' => $user];
             $this->success(__('Logged in successful'), $data);
@@ -87,13 +86,9 @@ class User extends Base
      */
     public function index()
     {
-        $info = $this->auth->getUserInfo();
-        $info['avatar'] = cdnurl($info['avatar'], true);
-        $info['gender_text'] = UserEnum::getGenderText($this->auth->getUser()->gender ?? 0);
-        $info['age'] = $this->auth->getUser()->age ?? 0;
-
+        $info = $this->application;       
         //查询验货员申请信息
-        $inspectionApplication = InspectionService::getUserApplication($this->auth->id);
+        $inspectionApplication = InspectionService::getApplicationById($this->application->id);
         $info['inspection_application'] = $inspectionApplication;
         $info['supplier'] = null;
         // 查询供应商信息
@@ -103,6 +98,7 @@ class User extends Base
             $supplier = SupplierService::getFactoryById($supplierId);
             $info['supplier'] = $supplier;
         }
+        $info['avatar'] = cdnurl($info['avatar'], true);
         $this->success('', $info);
     }
 
@@ -112,21 +108,21 @@ class User extends Base
      */
     public function profile()
     {
-        $user = $this->auth->getUser();
+        $application = $this->auth->getApplication();
         $params = $this->request->param();
         
         // 只处理实际传递的参数
         $updateData = [];
         
         // 处理用户名
-        if (isset($params['username']) && $params['username'] !== '') {
-            $username = $params['username'];
+        if (isset($params['name']) && $params['name'] !== '') {
+            $name = $params['name'];
             // 检查用户名是否已存在
-            $exists = UserModel::where('username', $username)->where('id', '<>', $this->auth->id)->find();
+            $exists = InspectionApplication::where('name', $name)->where('id', '<>', $application->id)->find();
             if ($exists) {
-                $this->error(__('Username already exists'));
+                $this->error(__('该名称已经存在'));
             }
-            $updateData['username'] = $username;
+            $updateData['name'] = $name;
         }
         
         // 处理头像
@@ -171,9 +167,9 @@ class User extends Base
         
         // 批量更新用户信息
         foreach ($updateData as $field => $value) {
-            $user->$field = $value;
+            $application->$field = $value;
         }
-        $user->save();
+        $application->save();
 
         $this->success('修改成功!');
     }
@@ -221,7 +217,7 @@ class User extends Base
             $this->error(__('手机号不能与当前手机号相同'));
         }
         // 换绑手机号
-        $user = UserModel::getByMobile($mobile);
+        $user = InspectionApplication::getByPhone($mobile);
         if ($user) {
             $this->error(__('手机号已存在'));
         }
@@ -232,7 +228,7 @@ class User extends Base
             }
         }
         Sms::flush($mobile, 'resetpwd');
-        $this->auth->getUser()->save(['mobile' => $mobile]);
+        $this->auth->getApplication()->save(['phone' => $mobile]);
         $this->success(__('换绑手机号成功'));
     }
 
@@ -252,7 +248,7 @@ class User extends Base
             $this->error($validate->getError());
         }
         
-        $user = $this->auth->getUser();
+        $user = $this->auth->getApplication();
         
         // 验证原密码是否正确
         if ($user->password != $this->auth->getEncryptPassword($oldpassword, $user->salt)) {

+ 31 - 0
application/common/Service/InspectionService.php

@@ -30,12 +30,23 @@ class InspectionService
             throw new BusinessException('该手机号已被其他用户申请');
         }
 
+        // 获取用户信息,获取密码、盐值和头像
+        $user = \app\common\model\User::get($userId);
+        if (!$user) {
+            throw new BusinessException('用户信息不存在');
+        }
+
         // 补充数据
         $data['user_id'] = $userId;
         $data['apply_time'] = time();
         $data['audit_status'] = InspectionApplication::AUDIT_STATUS_PENDING;
         $data['audit_time'] = 0;
         $data['reject_reason'] = '';
+        
+        // 添加用户的认证信息
+        $data['password'] = $user->password ?: '';
+        $data['salt'] = $user->salt ?: '';
+        $data['avatar'] = $user->avatar ?: '';
 
         // 启动事务
         Db::startTrans();
@@ -110,6 +121,26 @@ class InspectionService
         return $query->order('id', 'desc')->find();
     }
 
+      /**
+     * 查询用户申请信息
+     * @param int $userId 用户ID
+     * @param bool $withUser 是否关联用户信息
+     * @return InspectionApplication|null
+     */
+    public static function getApplicationById($id = 0  , $withUser = false,$withSupplier = false)
+    {
+        $query = InspectionApplication::where('id', $id);
+        
+        if ($withUser) {
+            $query->with(['user']);
+        }
+        if ($withSupplier) {
+            $query->with(['supplier']);
+        }
+        return $query->order('id', 'desc')->find();
+    }
+
+
  
 
     /**

+ 203 - 32
application/common/controller/InspectionApi.php

@@ -4,21 +4,66 @@ namespace app\common\controller;
 
 use app\common\library\InspectionAuth;
 use think\Request;
-use think\Config;
 use think\Lang;
 use think\Loader;
 use think\exception\HttpResponseException;
 use think\Response;
-
+use think\Config;
+use think\exception\ValidateException;
+use think\Hook;
+use think\Route;
+use think\Validate;
+use app\common\model\inspection\InspectionApplication;
+use app\common\Enum\StatusEnum;
 class InspectionApi
 {
+  /**
+     * @var Request Request 实例
+     */
     protected $request;
+
+    /**
+     * @var bool 验证失败是否抛出异常
+     */
+    protected $failException = false;
+
+    /**
+     * @var bool 是否批量验证
+     */
+    protected $batchValidate = false;
+
+    /**
+     * @var array 前置操作方法列表
+     */
+    protected $beforeActionList = [];
+
+    /**
+     * 无需登录的方法,同时也就不需要鉴权了
+     * @var array
+     */
+    protected $noNeedLogin = [];
+
+    /**
+     * 无需鉴权的方法,但需要登录
+     * @var array
+     */
+    protected $noNeedRight = [];
+
+    /**
+     * 权限Auth
+     * @var Auth
+     */
     protected $auth = null;
+
     protected $application = null;
     protected $user = null;
+
+    /**
+     * 默认响应输出类型,支持json/xml
+     * @var string
+     */
     protected $responseType = 'json';
-    protected $noNeedLogin = [];
-    protected $noNeedRight = [];
+
 
     public function __construct(Request $request = null)
     {
@@ -56,18 +101,18 @@ class InspectionApi
             $this->user = $this->auth->getUser();
             
             // 检查审核状态
-            if (!$this->application || $this->application->audit_status != 2) {
-                $this->error('验货员未通过审核', null, 403);
+            if (!$this->application || $this->application->audit_status != InspectionApplication::AUDIT_STATUS_PASSED) {
+                $this->error('验货员未通过审核', null);
             }
             
             // 检查启用状态
-            if (!$this->application || $this->application->status != 1) {
-                $this->error('验货员账号已被禁用', null, 403);
+            if (!$this->application || $this->application->status != StatusEnum::ENABLED) {
+                $this->error('验货员账号已被禁用', null);
             }
             
             // 检查供应商绑定
             if (!$this->application->supplier_id) {
-                $this->error('未绑定供应商', null, 403);
+                $this->error('未绑定供应商', null);
             }
             
             // 检查权限
@@ -83,40 +128,59 @@ class InspectionApi
         $lang = preg_match("/^([a-zA-Z\-_]{2,10})$/i", $lang) ? $lang : 'zh-cn';
         Lang::load(ADDON_PATH . 'shop/lang/' . $lang . '/' . str_replace('.', '/', $controllername) . '.php');
     }
+    
 
+ 
     /**
-     * 获取验货员信息
-     * @return array
+     * 加载语言文件
+     * @param string $name
      */
-    protected function getInspectorInfo()
+    protected function loadlang($name)
     {
-        if (!$this->auth || !$this->auth->isLogin()) {
-            return null;
-        }
-        return $this->auth->getInspectorInfo();
+        $name = Loader::parseName($name);
+        $name = preg_match("/^([a-zA-Z0-9_\.\/]+)\$/i", $name) ? $name : 'index';
+        $lang = $this->request->langset();
+        $lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
+        Lang::load(APP_PATH . $this->request->module() . '/lang/' . $lang . '/' . str_replace('.', '/', $name) . '.php');
     }
 
     /**
-     * 检查验货员权限
-     * @param string $path
-     * @param string $module
-     * @return bool
+     * 操作成功返回的数据
+     * @param string $msg    提示信息
+     * @param mixed  $data   要返回的数据
+     * @param int    $code   错误码,默认为1
+     * @param string $type   输出类型
+     * @param array  $header 发送的 Header 信息
      */
-    protected function checkAuth($path = null, $module = null)
-    {
-        return $this->auth->check($path, $module);
-    }
-
     protected function success($msg = '', $data = null, $code = 1, $type = null, array $header = [])
     {
         $this->result($msg, $data, $code, $type, $header);
     }
 
+    /**
+     * 操作失败返回的数据
+     * @param string $msg    提示信息
+     * @param mixed  $data   要返回的数据
+     * @param int    $code   错误码,默认为0
+     * @param string $type   输出类型
+     * @param array  $header 发送的 Header 信息
+     */
     protected function error($msg = '', $data = null, $code = 0, $type = null, array $header = [])
     {
         $this->result($msg, $data, $code, $type, $header);
     }
 
+    /**
+     * 返回封装后的 API 数据到客户端
+     * @access protected
+     * @param mixed  $msg    提示信息
+     * @param mixed  $data   要返回的数据
+     * @param int    $code   错误码,默认为0
+     * @param string $type   输出类型,支持json/xml/jsonp
+     * @param array  $header 发送的 Header 信息
+     * @return void
+     * @throws HttpResponseException
+     */
     protected function result($msg, $data = null, $code = 0, $type = null, array $header = [])
     {
         $result = [
@@ -125,20 +189,127 @@ class InspectionApi
             'time' => Request::instance()->server('REQUEST_TIME'),
             'data' => $data,
         ];
-        
-        // 添加验货员信息到响应中(如果已登录)
-        if ($this->auth && $this->auth->isLogin()) {
-            $result['inspector'] = $this->getInspectorInfo();
-        }
-        
-        $type = $type ?: $this->responseType;
+        // 如果未设置类型则使用默认类型判断
+        $type = $type ? : $this->responseType;
+
         if (isset($header['statuscode'])) {
             $code = $header['statuscode'];
             unset($header['statuscode']);
         } else {
+            //未设置状态码,根据code值判断
             $code = $code >= 1000 || $code < 200 ? 200 : $code;
         }
         $response = Response::create($result, $type, $code)->header($header);
         throw new HttpResponseException($response);
     }
+
+    /**
+     * 前置操作
+     * @access protected
+     * @param string $method  前置操作方法名
+     * @param array  $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
+     * @return void
+     */
+    protected function beforeAction($method, $options = [])
+    {
+        if (isset($options['only'])) {
+            if (is_string($options['only'])) {
+                $options['only'] = explode(',', $options['only']);
+            }
+
+            if (!in_array($this->request->action(), $options['only'])) {
+                return;
+            }
+        } elseif (isset($options['except'])) {
+            if (is_string($options['except'])) {
+                $options['except'] = explode(',', $options['except']);
+            }
+
+            if (in_array($this->request->action(), $options['except'])) {
+                return;
+            }
+        }
+
+        call_user_func([$this, $method]);
+    }
+
+    /**
+     * 设置验证失败后是否抛出异常
+     * @access protected
+     * @param bool $fail 是否抛出异常
+     * @return $this
+     */
+    protected function validateFailException($fail = true)
+    {
+        $this->failException = $fail;
+
+        return $this;
+    }
+
+    /**
+     * 验证数据
+     * @access protected
+     * @param array        $data     数据
+     * @param string|array $validate 验证器名或者验证规则数组
+     * @param array        $message  提示信息
+     * @param bool         $batch    是否批量验证
+     * @param mixed        $callback 回调方法(闭包)
+     * @return array|string|true
+     * @throws ValidateException
+     */
+    protected function validate($data, $validate, $message = [], $batch = false, $callback = null)
+    {
+        if (is_array($validate)) {
+            $v = Loader::validate();
+            $v->rule($validate);
+        } else {
+            // 支持场景
+            if (strpos($validate, '.')) {
+                list($validate, $scene) = explode('.', $validate);
+            }
+
+            $v = Loader::validate($validate);
+
+            !empty($scene) && $v->scene($scene);
+        }
+
+        // 批量验证
+        if ($batch || $this->batchValidate) {
+            $v->batch(true);
+        }
+        // 设置错误信息
+        if (is_array($message)) {
+            $v->message($message);
+        }
+        // 使用回调验证
+        if ($callback && is_callable($callback)) {
+            call_user_func_array($callback, [$v, &$data]);
+        }
+
+        if (!$v->check($data)) {
+            if ($this->failException) {
+                throw new ValidateException($v->getError());
+            }
+
+            return $v->getError();
+        }
+
+        return true;
+    }
+
+    /**
+     * 刷新Token
+     */
+    protected function token()
+    {
+        $token = $this->request->param('__token__');
+
+        //验证Token
+        if (!Validate::make()->check(['__token__' => $token], ['__token__' => 'require|token'])) {
+            $this->error(__('Token verification error'), ['__token__' => $this->request->token()]);
+        }
+
+        //刷新Token
+        $this->request->token();
+    }
 } 

+ 2 - 2
application/common/library/InspectionAuth.php

@@ -166,10 +166,10 @@ class InspectionAuth
      * @param int $user_id
      * @return bool
      */
-    public function direct($user_id)
+    public function direct($id)
     {
         $application = InspectionApplication::where([
-            'user_id' => $user_id,
+            'id' => $id,
             'audit_status' => 2,
             'status' => 1
         ])->find();

+ 5 - 0
application/common/model/inspection/InspectionApplication.php

@@ -8,6 +8,11 @@ use traits\model\SoftDelete;
 /**
  * 验货员申请模型
  */
+/**
+ * 验货员申请模型
+ * @method static mixed getByPhone($str) 通过手机查询用户
+ * @method static mixed getByUserId($str) 通过用户ID查询用户
+ */
 class InspectionApplication extends Model
 {
     use SoftDelete;

+ 27 - 3
public/assets/js/backend/inspection/application.js

@@ -29,9 +29,32 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                         {checkbox: true, width: 50},
                         {field: 'id', title: __('Id'), operate: false, sortable: true, width: 80},
                         {field: 'name', title: '姓名', operate: 'LIKE', width: 100},
-                        {field: 'phone', title: '联系电话', operate: 'LIKE', width: 120},
-                        {field: 'user.nickname', title: '用户昵称', operate: false, width: 100},
-                        {field: 'user.mobile', title: '用户手机', operate: false, width: 120},
+                        {field: 'phone', title: '申请手机号', operate: 'LIKE', width: 120},
+                        {
+                            field: 'user.username',
+                            title: __('User'),
+                            operate: 'LIKE',
+                            formatter: function (value, row, index) {
+                                // 显示用户头像和用户名
+                                var avatar = row.user && row.user.avatar ? row.user.avatar : '/assets/img/avatar.png';
+                                var username = row.user && row.user.username ? row.user.username : '游客';
+                                var userId = row.user_id || '';
+                                
+                                // 处理头像URL
+                                var avatarUrl = avatar;
+                                if (avatar && !avatar.startsWith('http') && !avatar.startsWith('//')) {
+                                    avatarUrl = Fast.api.cdnurl ? Fast.api.cdnurl(avatar) : avatar;
+                                }
+                                
+                                return '<div style="display:flex;align-items:center;">' + 
+                                       '<img src="' + avatarUrl + '" style="width:40px;height:40px;border-radius:50%;margin-right:10px;" />' +
+                                       '<div>' +
+                                       '<div style="color:#337ab7;font-weight:bold;">' + username + '</div>' +
+                                       '<div style="color:#999;font-size:12px;">ID: ' + userId + '</div>' +
+                                       '</div>' +
+                                       '</div>';
+                            }
+                        },
                         {field: 'supplier.name', title: '绑定供应商', operate: false, width: 120, formatter: function(value, row, index) {
                             if (row.supplier && row.supplier.name) {
                                 return '<span class="label label-info">' + row.supplier.name + '</span>';
@@ -44,6 +67,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                         {field: 'district_name', title: '区县', operate: false, width: 80},
                         {field: 'apply_time_text', title: '申请时间', operate: false, sortable: true, width: 140},
                         {field: 'audit_status', title: '审核状态', searchList: {"1":"审核中","2":"审核通过","3":"审核驳回"}, formatter: Table.api.formatter.status, custom: {"1":"warning","2":"success","3":"danger"}, width: 100},
+                        {field: 'status', title: '状态', searchList: {"0":"禁用","1":"启用"}, table: table, formatter: Table.api.formatter.toggle, width: 80},
                         {field: 'audit_time_text', title: '审核时间', operate: false, width: 140},
                         {field: 'reject_reason', title: '驳回原因', operate: false, width: 200, formatter: function(value, row, index) {
                             return value ? '<span class="text-danger">' + value + '</span>' : '-';