UserFieldsRepository.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <?php
  2. namespace app\common\repositories\user;
  3. use app\common\dao\user\UserFieldsDao;
  4. use app\common\repositories\BaseRepository;
  5. use app\validate\admin\UserValidate;
  6. use FormBuilder\Factory\Elm;
  7. use think\db\exception\DataNotFoundException;
  8. use think\db\exception\DbException;
  9. use think\db\exception\ModelNotFoundException;
  10. use think\exception\ValidateException;
  11. use think\facade\Db;
  12. use think\facade\Route;
  13. use think\facade\Validate;
  14. /**
  15. * @mixin UserFieldsDao
  16. */
  17. class UserFieldsRepository extends BaseRepository
  18. {
  19. /**
  20. * @var UserFieldsDao
  21. */
  22. protected $dao;
  23. /**
  24. * UserSignRepository constructor.
  25. * @param UserFieldsDao $dao
  26. */
  27. public function __construct(UserFieldsDao $dao)
  28. {
  29. $this->dao = $dao;
  30. }
  31. /**
  32. * 验证特殊类型字段
  33. * @param string $type
  34. * @param string $field
  35. * @param string $title
  36. * @param array $data
  37. * @return bool
  38. *
  39. * @date 2023/09/26
  40. * @author yyw
  41. */
  42. public function validateFieldFormat(string $type, string $field, string $title, array $data, $content = [])
  43. {
  44. $name = $field . '|' . $title;
  45. $rule = '';
  46. switch ($type) {
  47. case 'radio':
  48. if (!empty($content) && is_array($content)) {
  49. $range = '|in:';
  50. // 拼接范围
  51. foreach ($content as $key => $item) {
  52. $range .= $key . ',';
  53. }
  54. $rule = 'integer' . rtrim($range, ',');
  55. }
  56. break;
  57. case 'int':
  58. $rule = 'integer';
  59. break;
  60. case 'phone':
  61. $rule = 'mobile';
  62. break;
  63. case 'date':
  64. $rule = 'date';
  65. break;
  66. case 'id_card':
  67. $rule = 'idCard';
  68. break;
  69. case 'email':
  70. $rule = 'email';
  71. break;
  72. }
  73. if (!empty($rule)) {
  74. $validate = Validate::rule($name, $rule);
  75. if (!$validate->check($data)) {
  76. throw new ValidateException($validate->getError());
  77. }
  78. }
  79. return true;
  80. }
  81. /**
  82. * 获取用户表单字段详情
  83. * @param int $uid
  84. * @param bool $is_user 是否用户端使用
  85. * @return array
  86. * @throws DataNotFoundException
  87. * @throws DbException
  88. * @throws ModelNotFoundException
  89. */
  90. public function info(int $uid, bool $is_user = true)
  91. {
  92. $userRepository = app()->make(UserRepository::class);
  93. $userInfo = $userRepository->get($uid);
  94. if (empty($userInfo)) {
  95. throw new ValidateException('用户数据异常');
  96. }
  97. $fields_where = ['is_used' => 1];
  98. if ($is_user) { // 用户端判断字段是否展示
  99. $fields_where['is_show'] = 1;
  100. }
  101. $info = $this->dao->getWhere(['uid' => $uid]);
  102. //获取标段字段信息
  103. $infoRepository = app()->make(UserInfoRepository::class);
  104. $fields = $infoRepository->getSearch($fields_where)->order(['sort', 'create_time' => 'ASC'])->select()->toArray();
  105. foreach ($fields as &$field) {
  106. if ($field['is_default']) { // 默认字段在用户表获取数据
  107. $field['value'] = $userInfo[$field['field']] ?? '';
  108. } else {
  109. $field['value'] = $info[$field['field']] ?? '';
  110. }
  111. }
  112. return [
  113. 'avatar' => $userInfo['avatar'],
  114. 'nickname' => $userInfo['nickname'],
  115. 'phone' => $userInfo['phone'],
  116. 'uid' => $userInfo['uid'],
  117. 'extend_info' => $fields,
  118. ];
  119. }
  120. /**
  121. * 获取用户扩展信息表单
  122. * 该方法用于根据用户ID生成用户的扩展信息表单,表单包含各种类型的字段,如整数、日期、单选按钮等。
  123. * @param int $uid 用户ID,用于获取特定用户的扩展信息。
  124. * @return mixed 返回包含表单元素的数组,用于前端展示和数据提交。
  125. * @throws ValidateException 当用户数据异常或表单类型异常时,抛出验证异常。
  126. */
  127. public function extendInfoForm(int $uid = 0)
  128. {
  129. $userRepository = app()->make(UserRepository::class);
  130. $userInfo = $userRepository->get($uid);
  131. if (empty($userInfo)) {
  132. throw new ValidateException('用户数据异常');
  133. }
  134. $userField = $this->dao->getSearch(['uid' => $uid])->find();
  135. if (!empty($userField)) {
  136. $userField = $userField->toArray();
  137. }
  138. // 获取表单数据
  139. $userInfoRepository = app()->make(UserInfoRepository::class);
  140. $extendInfos = $userInfoRepository->getSearch(['is_used' => 1])->order(['sort', 'create_time' => 'ASC'])->select()->toArray();
  141. $form = [];
  142. foreach ($extendInfos as $extendInfo) {
  143. $field = $extendInfo['field'];
  144. $placeholder = $extendInfo['title'];
  145. $title = $extendInfo['title'] . ':';
  146. // 是默认字段重新赋值
  147. if ($extendInfo['is_default']) {
  148. $userField[$field] = $userInfo[$field];
  149. }
  150. switch ($extendInfo['type']) {
  151. case 'int':
  152. $form_item = Elm::number($field, $title);
  153. break;
  154. case 'date':
  155. $form_item = Elm::date($field, $title);
  156. break;
  157. case 'radio':
  158. $options = [];
  159. foreach ($extendInfo['content'] as $value => $label) {
  160. $options[] = ['label' => $label, 'value' => (int)$value];
  161. }
  162. $form_item = Elm::radio($field, $title, 0)->options($options);
  163. break;
  164. case 'email':
  165. $form_item = Elm::email($field, $title);
  166. break;
  167. case 'phone':
  168. case 'input':
  169. case 'address':
  170. case 'id_card':
  171. $form_item = Elm::input($field, $title)->placeholder('请输入' . $placeholder);
  172. break;
  173. default:
  174. throw new ValidateException('表单类型异常');
  175. }
  176. if ($extendInfo['is_require'] && $extendInfo['type'] != 'radio' && $extendInfo['type'] != 'date') {
  177. $form[] = $form_item->required($extendInfo['msg'] ?: '请填写此项信息');
  178. } else {
  179. $form[] = $form_item;
  180. }
  181. }
  182. if (empty($form)) {
  183. throw new ValidateException('请先去用户设置:设置用户信息');
  184. }
  185. return Elm::createForm(Route::buildUrl('systemUserInfoFieldSave', ['uid' => $uid])->build(), $form)->setTitle('信息补充')->formData($userField ?: []);
  186. }
  187. /**
  188. * 报错或者编辑用户表单数据
  189. * @param int $uid
  190. * @param array $data
  191. * @param bool $is_user 是否用户端使用
  192. * @return true
  193. * @throws \think\db\exception\DataNotFoundException
  194. * @throws \think\db\exception\DbException
  195. * @throws \think\db\exception\ModelNotFoundException
  196. */
  197. public function save(int $uid, array $data = [], bool $is_user = true)
  198. {
  199. $info = $this->dao->getWhere(['uid' => $uid]);
  200. //获取标段字段信息
  201. $infoRepository = app()->make(UserInfoRepository::class);
  202. $where = ['is_used' => 1];
  203. if ($is_user) {
  204. $where = ['is_used' => 1, 'is_show' => 1];
  205. }
  206. $fields = $infoRepository->getSearch($where)->select()->toArray();
  207. $user_data = []; //用户表更新字段数据
  208. $fields_data = []; //扩展字段数据
  209. foreach ($fields as &$field) {
  210. foreach ($data as $new_field) {
  211. if ($new_field['field'] == $field['field']) {
  212. // 数据为空统一设置为null
  213. // if ($new_field['value'] === "") {
  214. // $new_field['value'] = null;
  215. // }
  216. $field['value'] = $new_field['value'];
  217. }
  218. }
  219. if ($is_user) {
  220. if ($field['is_used'] && $field['is_show'] && $field['is_require'] && (!isset($field['value']) || $field['value'] === null)) {
  221. throw new ValidateException($field['title'] . '字段不能为空');
  222. }
  223. } else {
  224. if (!isset($field['value']) || $field['value'] === null) {
  225. continue;
  226. }
  227. }
  228. //验证字段
  229. $this->validateFieldFormat($field['type'], $field['field'], $field['title'], [$field['field'] => $field['value']], $field['content']);
  230. if ($field['is_default']) {
  231. $user_data[$field['field']] = $field['value'];
  232. } else {
  233. $fields_data[$field['field']] = $field['value'];
  234. }
  235. }
  236. // Db::listen(function($sql){
  237. // var_dump(['sql' => $sql]);
  238. // });
  239. // var_dump(['info' => $info,'fields_data' => $fields_data]);
  240. // 更新或创建扩展信息
  241. if (!empty($fields_data)) {
  242. if (empty($info)) {
  243. $fields_data['uid'] = $uid;
  244. $this->dao->create($fields_data);
  245. } else {
  246. $this->dao->update($info['id'], $fields_data);
  247. }
  248. }
  249. // var_dump(['user_data' => $user_data]);
  250. // 更新用户信息
  251. if (!empty($user_data)) {
  252. // 验证用户信息字段
  253. validate(UserValidate::class)->scene('extend_info')->check($user_data);
  254. app()->make(UserRepository::class)->update($uid, $user_data);
  255. }
  256. unset($user_data);
  257. unset($fields_data);
  258. return true;
  259. }
  260. /**
  261. * 删除用户表单数据
  262. * @param int $uid
  263. * @return bool
  264. * @throws \think\db\exception\DataNotFoundException
  265. * @throws \think\db\exception\DbException
  266. * @throws \think\db\exception\ModelNotFoundException
  267. *
  268. * @date 2023/09/26
  269. * @author yyw
  270. */
  271. public function delete(int $uid)
  272. {
  273. $info = $this->dao->getWhere(['uid' => $uid]);
  274. if (empty($info)) {
  275. throw new ValidateException('数据异常');
  276. }
  277. $this->dao->delete($info['id']);
  278. return true;
  279. }
  280. }