FieldVerificationTrait.php 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. /**
  3. * 字段验证(线索、客户、联系人、商机、合同、回款、回访、产品、办公审批)
  4. */
  5. namespace app\admin\traits;
  6. trait FieldVerificationTrait
  7. {
  8. /**
  9. * 数据验证
  10. *
  11. * @param array $param 要验证的数据
  12. * @param int $userId 用户ID
  13. * @param string $types 自定义表栏目类型:crm_leads、crm_customer ...
  14. * @param int $dataId 编辑时,相应的模块数据的ID
  15. * @param int $typesId 自定义表栏目类型ID
  16. * @return string
  17. * @since 2021-05-18
  18. * @author fanqi
  19. */
  20. public function fieldDataValidate($param, $types, $userId, $dataId = 0, $typesId = 0)
  21. {
  22. $error = '';
  23. $grantData = getFieldGrantData($userId); # 字段授权
  24. $userLevel = isSuperAdministrators($userId); # 用户级别
  25. # 查询自定义字段表数据
  26. $fieldList = $this->getFieldList($types, $typesId);
  27. # 验证
  28. foreach ($fieldList as $key => $value) {
  29. # 字段授权,没有读写权限,跳过验证。
  30. if (!$userLevel && !empty($grantData[$types])) {
  31. $status = getFieldGrantStatus($value['field'], $grantData[$types]);
  32. if (empty($status['read']) || (empty($dataId) && empty($status['write']))) continue;
  33. }
  34. # 验证非明细表格字段数据
  35. if ($value['form_type'] != 'detail_table' && !empty($value['is_null']) && !in_array($value['form_type'], ['detail_table', 'boolean_value']) && (isset($param[$value['field']]) && empty($param[$value['field']]))) {
  36. $error = $value['name'] . '字段不能为空!';
  37. break;
  38. }
  39. # 验证字段长度
  40. if (!empty($value['max_length']) && $value['form_type'] != 'detail_table' && strlen($param[$value['field']]) > $value['max_length']) {
  41. $error = $value['name'] . '字段超过设定长度!';
  42. break;
  43. }
  44. # 验证百分数字段长度
  45. if ($value['form_type'] == 'percent' && strlen($param[$value['field']]) > 11) {
  46. $error = $value['name'] . "字段长度不能大于10位!";
  47. break;
  48. }
  49. # 验证数字字段长度
  50. if ($value['form_type'] == 'number' && strlen($param[$value['field']]) > 16) {
  51. $error = $value['name'] . "字段长度不能大于16位!";
  52. break;
  53. }
  54. # 验证明细表格不能为空
  55. if (!empty($value['is_null']) && $value['form_type'] == 'detail_table' && isset($param[$value['field']]) && empty($param[$value['field']])) {
  56. $error = $value['name'] . '数据不能为空!';
  57. }
  58. # 验证明细表格可以为空,明细表格里的字段不能为空的情况。
  59. if ($value['form_type'] == 'detail_table') {
  60. foreach ($param[$value['field']] as $val) {
  61. foreach ($val as $v) {
  62. if ($v['form_type']!='boolean_value' && !empty($v['is_null']) && empty($v['is_hidden']) && isset($v['value']) && empty($v['value'])) {
  63. $error = $value['name'] . '中的' . $v['name'] . '字段不能为空!';
  64. break;
  65. }
  66. }
  67. }
  68. }
  69. if (empty($value['is_unique'])) continue;
  70. // 人员、部门、文件、手写签名、描述文字、多选、明细表格跳过验证
  71. if (in_array($value['form_type'], ['file', 'handwriting_sign', 'desc_text', 'checkbox', 'detail_table'])) continue;
  72. $uniqueStatus = false;
  73. # 验证唯一性
  74. if ($value['form_type'] == 'date_interval' && !empty($param[$value['field']])) {
  75. // 日期区间
  76. $uniqueStatus = $this->checkDataUniqueForDateInterval($types, $value['field'], $param[$value['field']], $dataId);
  77. } elseif ($value['form_type'] == 'position' && !empty($param[$value['field']])) {
  78. // 地址
  79. $uniqueStatus = $this->checkDataUniqueForPosition($types, $value['field'], $param[$value['field']], $dataId);
  80. } elseif ($value['form_type'] == 'location' && !empty($param[$value['field']])) {
  81. // 定位
  82. $uniqueStatus = $this->checkDataUniqueForLocation($types, $value['field'], $param[$value['field']], $dataId);
  83. } elseif ($value['form_type'] == 'user' && !empty($param[$value['field']])) {
  84. // 人员
  85. $uniqueStatus = $this->checkDataUniqueForUser($types, $value['field'], $param[$value['field']], $dataId);
  86. } elseif ($value['form_type'] == 'structure' && !empty($param[$value['field']])) {
  87. // 部门
  88. $uniqueStatus = $this->checkDataUniqueForStructure($types, $value['field'], $param[$value['field']], $dataId);
  89. } else {
  90. if (!empty($param[$value['field']])) $uniqueStatus = $this->checkDataUniqueForCommon($types, $value['field'], $param[$value['field']], $dataId);
  91. }
  92. if (!empty($uniqueStatus)) {
  93. $error = $types == 'crm_customer' ? '(客户/公海)中的' . $value['name'] . "字段值重复!" : $value['name'] . "字段值重复!";
  94. break;
  95. }
  96. }
  97. return $error;
  98. }
  99. /**
  100. * 验证唯一性(通用)
  101. * 单行文本、多行文本、网址、布尔值、单选、数字
  102. * 手机、邮箱、日期、日期时间、货币、百分数
  103. *
  104. * @param string $types 栏目类型
  105. * @param string $field 字段名称
  106. * @param string $value 字段值
  107. * @param int $dataId 更新时,传来的数据ID
  108. * @return float|mixed|string
  109. * @since 2021-05-18
  110. * @author fanqi
  111. */
  112. private function checkDataUniqueForCommon($types, $field, $value, $dataId = 0)
  113. {
  114. if (empty($value)) return false;
  115. # 主键
  116. $primaryKey = getPrimaryKeyName($types);
  117. # 查询条件
  118. $where[$field] = $value;
  119. if (!empty($dataId)) $where[$primaryKey] = ['neq', $dataId];
  120. return db($types)->where($where)->value($primaryKey);
  121. }
  122. /**
  123. * 验证唯一性(日期区间)
  124. *
  125. * @param string $types 栏目类型
  126. * @param string $field 字段名称
  127. * @param array $value 字段值
  128. * @param int $dataId 更新时,传来的数据ID
  129. * @return float|mixed|string
  130. * @since 2021-05-18
  131. * @author fanqi
  132. */
  133. private function checkDataUniqueForDateInterval($types, $field, $value, $dataId = 0)
  134. {
  135. if (empty($value)) return false;
  136. # 主键
  137. $primaryKey = getPrimaryKeyName($types);
  138. # 查询条件
  139. $where[$field] = implode('_', $value);
  140. if (!empty($dataId)) $where[$primaryKey] = ['neq', $dataId];
  141. return db($types)->where($where)->value($primaryKey);
  142. }
  143. /**
  144. * 验证唯一性(地址)
  145. *
  146. * @param string $types 栏目类型
  147. * @param string $field 字段名称
  148. * @param array $value 字段值
  149. * @param int $dataId 更新时,传来的数据ID
  150. * @return float|mixed|string
  151. * @since 2021-05-18
  152. * @author fanqi
  153. */
  154. private function checkDataUniqueForPosition($types, $field, $value, $dataId = 0)
  155. {
  156. if (empty($value)) return false;
  157. # 主键
  158. $primaryKey = getPrimaryKeyName($types);
  159. # 查询条件
  160. $where[$field] = implode(',', array_column($value, 'name'));
  161. if (!empty($dataId)) $where[$primaryKey] = ['neq', $dataId];
  162. return db($types)->where($where)->value($primaryKey);
  163. }
  164. /**
  165. * 验证唯一性(定位)
  166. *
  167. * @param string $types 栏目类型
  168. * @param string $field 字段名称
  169. * @param array $value 字段值
  170. * @param int $dataId 更新时,传来的数据ID
  171. * @return float|mixed|string
  172. * @since 2021-05-18
  173. * @author fanqi
  174. */
  175. private function checkDataUniqueForLocation($types, $field, $value, $dataId = 0)
  176. {
  177. if (empty($value['address'])) return false;
  178. # 主键
  179. $primaryKey = getPrimaryKeyName($types);
  180. # 查询条件
  181. $where[$field] = $value['address'];
  182. if (!empty($dataId)) $where[$primaryKey] = ['neq', $dataId];
  183. return db($types)->where($where)->value($primaryKey);
  184. }
  185. /**
  186. * 验证唯一性(部门)
  187. *
  188. * @param string $types 栏目类型
  189. * @param string $field 字段名称
  190. * @param string $value 字段值
  191. * @param int $dataId 更新时,传来的数据ID
  192. * @return float|mixed|string
  193. * @since 2021-05-18
  194. * @author fanqi
  195. */
  196. private function checkDataUniqueForStructure($types, $field, $value, $dataId = 0)
  197. {
  198. if (empty($value)) return false;
  199. # 主键
  200. $primaryKey = getPrimaryKeyName($types);
  201. # 查询条件
  202. $where[$field] = ',' . $value . ',';
  203. if (!empty($dataId)) $where[$primaryKey] = ['neq', $dataId];
  204. return db($types)->where($where)->value($primaryKey);
  205. }
  206. /**
  207. * @param $types 栏目类型
  208. * @param $field 字段名称
  209. * @param $value 字段值
  210. * @param int $dataId 更新时,传来的数据ID
  211. * @return false|float|mixed|string|null
  212. * @since 2021-05-18
  213. * @author fanqi
  214. */
  215. private function checkDataUniqueForUser($types, $field, $value, $dataId = 0)
  216. {
  217. if (empty($value)) return false;
  218. # 主键
  219. $primaryKey = getPrimaryKeyName($types);
  220. # 查询条件
  221. $where[$field] = ',' . $value . ',';
  222. if (!empty($dataId)) $where[$primaryKey] = ['neq', $dataId];
  223. return db($types)->where($where)->value($primaryKey);
  224. }
  225. /**
  226. * 自定义字段列表
  227. *
  228. * @param string $types 自定义表栏目类型:crm_leads、crm_customer ...
  229. * @param int $typesId 自定义表栏目类型ID
  230. * @return bool|\PDOStatement|string|\think\Collection
  231. * @since 2021-05-18
  232. * @author fanqi
  233. */
  234. private function getFieldList($types, $typesId)
  235. {
  236. # 查询条件
  237. $where = [
  238. 'types' => $types,
  239. 'types_id' => $typesId,
  240. 'is_hidden' => 0,
  241. 'form_type' => ['neq', 'desc_text']
  242. ];
  243. # 查询字段
  244. $fields = ['field', 'name', 'form_type', 'is_unique', 'is_null', 'max_length'];
  245. return db('admin_field')->field($fields)->where($where)->select();
  246. }
  247. }