RecycleBinTrait.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. namespace app\common\model;
  3. use think\Db;
  4. /**
  5. * 软删除回收站:{prefix}_recycle_time 为 0 表示正常,>0 为移入回收站的时间戳
  6. * where 中可使用 _recycle:active(默认)、recycle、all
  7. */
  8. trait RecycleBinTrait
  9. {
  10. /** @return string 如 vod_recycle_time;返回空字符串表示不使用回收站 */
  11. abstract protected function getRecycleTimeField(): string;
  12. protected function ensureRecycleColumnExists()
  13. {
  14. $f = $this->getRecycleTimeField();
  15. if ($f === '') {
  16. return;
  17. }
  18. static $done = [];
  19. $table = $this->getTable();
  20. if (isset($done[$table])) {
  21. return;
  22. }
  23. try {
  24. $rows = Db::query('SHOW COLUMNS FROM `' . str_replace('`', '``', $table) . '` LIKE \'' . str_replace('\'', '\\\'', $f) . '\'');
  25. } catch (\Exception $e) {
  26. $done[$table] = true;
  27. return;
  28. }
  29. if (!empty($rows)) {
  30. $done[$table] = true;
  31. return;
  32. }
  33. try {
  34. Db::execute('ALTER TABLE `' . str_replace('`', '``', $table) . '` ADD COLUMN `' . str_replace('`', '``', $f) . '` int(10) unsigned NOT NULL DEFAULT \'0\'');
  35. } catch (\Exception $e) {
  36. }
  37. $done[$table] = true;
  38. }
  39. protected function mergeRecycleWhere(array $where)
  40. {
  41. $f = $this->getRecycleTimeField();
  42. if ($f === '') {
  43. return $where;
  44. }
  45. $this->ensureRecycleColumnExists();
  46. $mode = 'active';
  47. if (isset($where['_recycle'])) {
  48. $mode = (string)$where['_recycle'];
  49. unset($where['_recycle']);
  50. }
  51. if ($mode === 'all') {
  52. return $where;
  53. }
  54. if ($mode === 'recycle') {
  55. $where[$f] = ['>', 0];
  56. return $where;
  57. }
  58. if (!array_key_exists($f, $where)) {
  59. $where[$f] = 0;
  60. }
  61. return $where;
  62. }
  63. public function recycleData($where)
  64. {
  65. $f = $this->getRecycleTimeField();
  66. if ($f === '') {
  67. return ['code' => 1001, 'msg' => lang('param_err')];
  68. }
  69. $this->ensureRecycleColumnExists();
  70. if (!is_array($where)) {
  71. $where = json_decode($where, true);
  72. }
  73. if (!is_array($where)) {
  74. return ['code' => 1001, 'msg' => lang('param_err')];
  75. }
  76. $where = $this->mergeRecycleWhere($where);
  77. $cnt = (int)$this->where($where)->count();
  78. if ($cnt < 1) {
  79. return ['code' => 1002, 'msg' => lang('del_err')];
  80. }
  81. $t = time();
  82. $res = $this->where($where)->update([$f => $t]);
  83. if ($res === false) {
  84. return ['code' => 1002, 'msg' => lang('del_err') . ':' . $this->getError()];
  85. }
  86. return ['code' => 1, 'msg' => lang('recycle_ok')];
  87. }
  88. public function restoreData($where)
  89. {
  90. $f = $this->getRecycleTimeField();
  91. if ($f === '') {
  92. return ['code' => 1001, 'msg' => lang('param_err')];
  93. }
  94. $this->ensureRecycleColumnExists();
  95. if (!is_array($where)) {
  96. $where = json_decode($where, true);
  97. }
  98. if (!is_array($where)) {
  99. return ['code' => 1001, 'msg' => lang('param_err')];
  100. }
  101. $where['_recycle'] = 'recycle';
  102. $where = $this->mergeRecycleWhere($where);
  103. $cnt = (int)$this->where($where)->count();
  104. if ($cnt < 1) {
  105. return ['code' => 1002, 'msg' => lang('del_err')];
  106. }
  107. $res = $this->where($where)->update([$f => 0]);
  108. if ($res === false) {
  109. return ['code' => 1002, 'msg' => lang('del_err') . ':' . $this->getError()];
  110. }
  111. return ['code' => 1, 'msg' => lang('recycle_restore_ok')];
  112. }
  113. }