Browse Source

初始化

master
jianglong 3 years ago
parent
commit
be63c1a9e7
  1. 1
      addons/qingdong/.addonrc
  2. 134
      addons/qingdong/Qingdong.php
  3. 23
      addons/qingdong/config.php
  4. 209
      addons/qingdong/config/cache.php
  5. 8935
      addons/qingdong/config/menu.php
  6. 361
      addons/qingdong/controller/Achievement.php
  7. 216
      addons/qingdong/controller/Approval.php
  8. 1355
      addons/qingdong/controller/Attendance.php
  9. 293
      addons/qingdong/controller/Autotask.php
  10. 298
      addons/qingdong/controller/Business.php
  11. 172
      addons/qingdong/controller/Common.php
  12. 142
      addons/qingdong/controller/Consume.php
  13. 200
      addons/qingdong/controller/Contacts.php
  14. 362
      addons/qingdong/controller/Contract.php
  15. 564
      addons/qingdong/controller/Customer.php
  16. 327
      addons/qingdong/controller/Daily.php
  17. 23
      addons/qingdong/controller/ErrorCode.php
  18. 206
      addons/qingdong/controller/Event.php
  19. 257
      addons/qingdong/controller/ExamineRecord.php
  20. 30
      addons/qingdong/controller/File.php
  21. 463
      addons/qingdong/controller/Index.php
  22. 258
      addons/qingdong/controller/Leads.php
  23. 199
      addons/qingdong/controller/Leadspool.php
  24. 250
      addons/qingdong/controller/Message.php
  25. 52
      addons/qingdong/controller/Notice.php
  26. 29
      addons/qingdong/controller/Operation.php
  27. 156
      addons/qingdong/controller/Product.php
  28. 207
      addons/qingdong/controller/Receivables.php
  29. 112
      addons/qingdong/controller/ReceivablesPlan.php
  30. 368
      addons/qingdong/controller/Record.php
  31. 103
      addons/qingdong/controller/Setting.php
  32. 595
      addons/qingdong/controller/Staff.php
  33. 325
      addons/qingdong/controller/StaffApi.php
  34. 906
      addons/qingdong/controller/Statistics.php
  35. 55
      addons/qingdong/controller/Wx.php
  36. 68
      addons/qingdong/controller/Wxbizdatacrypt.php
  37. 532
      addons/qingdong/helper.php
  38. 10
      addons/qingdong/info.ini
  39. 1457
      addons/qingdong/install.sql
  40. 3
      addons/qingdong/lang/zh-cn.php
  41. 38
      addons/qingdong/lang/zh-cn/staff.php
  42. 100
      addons/qingdong/library/Ding.php
  43. 113
      addons/qingdong/library/Ku.php
  44. 95
      addons/qingdong/library/PhpWord/Collection/AbstractCollection.php
  45. 27
      addons/qingdong/library/PhpWord/Collection/Bookmarks.php
  46. 27
      addons/qingdong/library/PhpWord/Collection/Charts.php
  47. 27
      addons/qingdong/library/PhpWord/Collection/Comments.php
  48. 27
      addons/qingdong/library/PhpWord/Collection/Endnotes.php
  49. 27
      addons/qingdong/library/PhpWord/Collection/Footnotes.php
  50. 27
      addons/qingdong/library/PhpWord/Collection/Titles.php
  51. 181
      addons/qingdong/library/PhpWord/ComplexType/FootnoteProperties.php
  52. 106
      addons/qingdong/library/PhpWord/ComplexType/ProofState.php
  53. 59
      addons/qingdong/library/PhpWord/ComplexType/TblWidth.php
  54. 166
      addons/qingdong/library/PhpWord/ComplexType/TrackChangesView.php
  55. 316
      addons/qingdong/library/PhpWord/Element/AbstractContainer.php
  56. 507
      addons/qingdong/library/PhpWord/Element/AbstractElement.php
  57. 60
      addons/qingdong/library/PhpWord/Element/Bookmark.php
  58. 77
      addons/qingdong/library/PhpWord/Element/Cell.php
  59. 129
      addons/qingdong/library/PhpWord/Element/Chart.php
  60. 72
      addons/qingdong/library/PhpWord/Element/CheckBox.php
  61. 122
      addons/qingdong/library/PhpWord/Element/Comment.php
  62. 41
      addons/qingdong/library/PhpWord/Element/Endnote.php
  63. 299
      addons/qingdong/library/PhpWord/Element/Field.php
  64. 116
      addons/qingdong/library/PhpWord/Element/Footer.php
  65. 89
      addons/qingdong/library/PhpWord/Element/Footnote.php
  66. 195
      addons/qingdong/library/PhpWord/Element/FormField.php
  67. 41
      addons/qingdong/library/PhpWord/Element/Header.php
  68. 602
      addons/qingdong/library/PhpWord/Element/Image.php
  69. 53
      addons/qingdong/library/PhpWord/Element/Line.php
  70. 180
      addons/qingdong/library/PhpWord/Element/Link.php
  71. 111
      addons/qingdong/library/PhpWord/Element/ListItem.php
  72. 85
      addons/qingdong/library/PhpWord/Element/ListItemRun.php
  73. 169
      addons/qingdong/library/PhpWord/Element/OLEObject.php
  74. 31
      addons/qingdong/library/PhpWord/Element/PageBreak.php
  75. 98
      addons/qingdong/library/PhpWord/Element/PreserveText.php
  76. 107
      addons/qingdong/library/PhpWord/Element/Row.php
  77. 190
      addons/qingdong/library/PhpWord/Element/SDT.php
  78. 307
      addons/qingdong/library/PhpWord/Element/Section.php
  79. 88
      addons/qingdong/library/PhpWord/Element/Shape.php
  80. 169
      addons/qingdong/library/PhpWord/Element/TOC.php
  81. 174
      addons/qingdong/library/PhpWord/Element/Table.php
  82. 153
      addons/qingdong/library/PhpWord/Element/Text.php
  83. 60
      addons/qingdong/library/PhpWord/Element/TextBox.php
  84. 130
      addons/qingdong/library/PhpWord/Element/TextBreak.php
  85. 80
      addons/qingdong/library/PhpWord/Element/TextRun.php
  86. 108
      addons/qingdong/library/PhpWord/Element/Title.php
  87. 101
      addons/qingdong/library/PhpWord/Element/TrackChange.php
  88. 46
      addons/qingdong/library/PhpWord/Escaper/AbstractEscaper.php
  89. 33
      addons/qingdong/library/PhpWord/Escaper/EscaperInterface.php
  90. 33
      addons/qingdong/library/PhpWord/Escaper/RegExp.php
  91. 97
      addons/qingdong/library/PhpWord/Escaper/Rtf.php
  92. 32
      addons/qingdong/library/PhpWord/Escaper/Xml.php
  93. 39
      addons/qingdong/library/PhpWord/Exception/CopyFileException.php
  94. 37
      addons/qingdong/library/PhpWord/Exception/CreateTemporaryFileException.php
  95. 25
      addons/qingdong/library/PhpWord/Exception/Exception.php
  96. 25
      addons/qingdong/library/PhpWord/Exception/InvalidImageException.php
  97. 25
      addons/qingdong/library/PhpWord/Exception/InvalidObjectException.php
  98. 27
      addons/qingdong/library/PhpWord/Exception/InvalidStyleException.php
  99. 25
      addons/qingdong/library/PhpWord/Exception/UnsupportedImageTypeException.php
  100. 108
      addons/qingdong/library/PhpWord/IOFactory.php

1
addons/qingdong/.addonrc

File diff suppressed because one or more lines are too long

134
addons/qingdong/Qingdong.php

@ -0,0 +1,134 @@
<?php
namespace addons\qingdong;
use app\admin\model\AuthRule;
use app\common\library\Menu;
use think\Addons;
use think\Exception;
use think\exception\PDOException;
/**
* 插件
*/
class Qingdong extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
$menu = self::getMenu();
Menu::create($menu['new']);
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
Menu::delete('qingdong');
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
Menu::enable('qingdong');
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
Menu::disable('qingdong');
return true;
}
/**
* 插件更新方法
*/
public function upgrade()
{
$menu = self::getMenu();
if (method_exists(Menu::class, 'upgrade')) {
Menu::upgrade('qingdong', $menu['new']);
} else {
self::menuCreateOrUpdate($menu['new'], $menu['old']);
}
return true;
}
private static function getMenu()
{
$newMenu = [];
$config_file = ADDON_PATH . "qingdong" . DS . 'config' . DS . "menu.php";
if (is_file($config_file)) {
$newMenu = include $config_file;
}
$oldMenu = AuthRule::where('name', 'like', "qingdong%")->select();
$oldMenu = array_column($oldMenu, null, 'name');
return ['new' => $newMenu, 'old' => $oldMenu];
}
private static function menuCreateOrUpdate($newMenu, $oldMenu, $parent = 0)
{
if (!is_numeric($parent)) {
$parentRule = AuthRule::getByName($parent);
$pid = $parentRule ? $parentRule['id'] : 0;
} else {
$pid = $parent;
}
$allow = array_flip(['file', 'name', 'title', 'icon', 'condition', 'remark', 'ismenu', 'weigh']);
foreach ($newMenu as $k => $v) {
$hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
$data = array_intersect_key($v, $allow);
$data['ismenu'] = isset($data['ismenu']) ? $data['ismenu'] : ($hasChild ? 1 : 0);
$data['icon'] = isset($data['icon']) ? $data['icon'] : ($hasChild ? 'fa fa-list' : 'fa fa-circle-o');
$data['pid'] = $pid;
$data['status'] = 'normal';
try {
if (!isset($oldMenu[$data['name']])) {
$menu = AuthRule::create($data);
} else {
$menu = $oldMenu[$data['name']];
}
if ($hasChild) {
self::menuCreateOrUpdate($v['sublist'], $oldMenu, $menu['id']);
}
} catch (PDOException $e) {
throw new Exception($e->getMessage());
}
}
}
/**
* 应用初始化
*/
public function appInit()
{
// 公共方法
require_once __DIR__ . '/helper.php';
if(!class_exists("\dingding\TopSdk")){
\think\Loader::addNamespace('dingding', ADDON_PATH . 'qingdong' . DS . 'library' . DS . 'dingding' . DS);
}
if(!class_exists("\WeWork\App")){
\think\Loader::addNamespace('WeWork', ADDON_PATH . 'qingdong' . DS . 'library' . DS . 'wework' . DS);
}
if(!class_exists("\PhpOffice\PhpWord\PhpWord")){
\think\Loader::addNamespace('PhpOffice\PhpWord', ADDON_PATH . 'qingdong' . DS . 'library' . DS . 'PhpWord' . DS);
}
}
}

23
addons/qingdong/config.php

@ -0,0 +1,23 @@
<?php
return [
[
//配置名称,该值在当前数组配置中确保唯一
'name' => 'mobile_name',
//配置标题
'title' => '网站名称',
//配置类型,支持string/text/number/datetime/array/select/selects/image/images/file/files/checkbox/radio/bool
'type' => 'string',
//分组选项卡
'group' => '分组1',
//配置值
'value' => 'CRM',
//配置验证规则,更之规则可参考nice-validator文件
'rule' => 'required',
'msg' => '请输入网站名称',
'tip' => 'h5或小程序登录页标题',
'ok' => '验证成功',
'extend' => ''
],
];

209
addons/qingdong/config/cache.php

@ -0,0 +1,209 @@
<?php
return array (
'table_name' => 'fa_qingdong_achievement,fa_qingdong_achievement_records,fa_qingdong_admin_config,fa_qingdong_approval,fa_qingdong_attendance,fa_qingdong_attendance_address,fa_qingdong_attendance_card,fa_qingdong_attendance_leave,fa_qingdong_attendance_rule,fa_qingdong_attendance_statisc,fa_qingdong_attendance_time,fa_qingdong_business,fa_qingdong_business_other,fa_qingdong_business_product,fa_qingdong_business_status,fa_qingdong_comment,fa_qingdong_consume,fa_qingdong_contacts,fa_qingdong_contacts_file,fa_qingdong_contacts_other,fa_qingdong_contract,fa_qingdong_contract_file,fa_qingdong_contract_other,fa_qingdong_contract_product,fa_qingdong_contract_ratio,fa_qingdong_customer,fa_qingdong_customer_file,fa_qingdong_customer_other,fa_qingdong_daily,fa_qingdong_daily_draft,fa_qingdong_daily_read,fa_qingdong_ding_contacts,fa_qingdong_ding_customer,fa_qingdong_ding_record,fa_qingdong_ding_staff,fa_qingdong_event,fa_qingdong_examine_record,fa_qingdong_fauser,fa_qingdong_feedback,fa_qingdong_field,fa_qingdong_file,fa_qingdong_flow,fa_qingdong_form,fa_qingdong_form_approval,fa_qingdong_form_field,fa_qingdong_goods,fa_qingdong_ku_customer,fa_qingdong_leads,fa_qingdong_leads_file,fa_qingdong_leads_other,fa_qingdong_login_token,fa_qingdong_message,fa_qingdong_notice,fa_qingdong_notice_template,fa_qingdong_operation_log,fa_qingdong_product,fa_qingdong_product_part,fa_qingdong_product_type,fa_qingdong_push_reload,fa_qingdong_receivables,fa_qingdong_receivables_other,fa_qingdong_receivables_plan,fa_qingdong_record,fa_qingdong_record_file,fa_qingdong_record_read,fa_qingdong_remind,fa_qingdong_seas_type,fa_qingdong_send_template,fa_qingdong_staff,fa_qingdong_staff_collect,fa_qingdong_staff_department,fa_qingdong_staff_ratio,fa_qingdong_staff_role,fa_qingdong_staff_rule,fa_qingdong_staff_sign_in',
'self_path' => '',
'update_data' => 'INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (1, \'seas\', \'auto\', \'1\', 1631875558, 1631875558, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (2, \'seas\', \'genjing\', \'1\', 1631875558, 1631875558, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (3, \'seas\', \'genjing_success\', \'1\', 1631875558, 1631875558, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (4, \'seas\', \'genjing_day\', \'0\', 1631875558, 1631875558, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (5, \'seas\', \'chengjiao\', \'0\', 1631875558, 1631875558, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (6, \'seas\', \'chengjiao_day\', \'0\', 1631875558, 1631875558, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (7, \'wechat\', \'mini_appid\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (8, \'wechat\', \'mini_secret\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (9, \'wechat\', \'appid\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (10, \'wechat\', \'secret\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (11, \'wechat\', \'examine_template\', \'0\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (12, \'wechat\', \'record_template\', \'0\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (13, \'wechat\', \'map_key\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (14, \'wechat\', \'web_url\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (15, \'dingding\', \'ding_key\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_admin_config`
VALUES (16, \'dingding\', \'ding_secret\', \'\', 1631875559, 1631875559, NULL);
INSERT INTO `__PREFIX__qingdong_field`
VALUES (138, \'leads\', \'线索来源\', \'[\\"电话营销\\",\\"拜访\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (139, \'leads\', \'客户行业\', \'[\\"互联网\\",\\"信息化\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (141, \'examine\', \'回款方式\', \'[\\"微信\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (147, \'contacts\', \'角色\',
\'[\\"普通员工\\",\\"决策人\\",\\"分项决策人\\",\\"商务决策\\",\\"财务决策\\",\\"使用人\\",\\"意见影响人\\",\\"采购\\",\\"老板\\",\\"股东\\",\\"职业经理人\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (148, \'other\', \'跟进类型\', \'[\\"到访\\",\\"电话\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (149, \'other\', \'消费方式\', \'[\\"吃饭\\",\\"住酒店\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (151, \'customer\', \'客户所属\', \'[\\"重点客户\\",\\"普通客户\\",\\"非优先客户\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (152, \'customer\', \'客户状态\', \'[\\"初次接触\\",\\"正在跟进\\",\\"准备购买\\",\\"准备付款\\",\\"已经购买\\",\\"暂时搁置\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (153, \'customer\', \'客户来源\', \'[\\"行业活动\\",\\"搜索引擎\\",\\"客户转介绍\\",\\"展会\\",\\"朋友介绍\\",\\"市场推广\\"]\');
INSERT INTO `__PREFIX__qingdong_field`
VALUES (158, \'daily\', \'报告类型\', \'[\\"日报\\",\\"周报\\",\\"月报\\",\\"季报\\",\\"年报\\"]\');
INSERT INTO `__PREFIX__qingdong_form` VALUES (11, \'线索管理\', \'leads\', \'{\\"data\\":[{\\"id\\":\\"name\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"线索名称\\",\\"readonly\\":false,\\"placeholder\\":\\"线索名称\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"source\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"线索来源\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"电话营销\\",\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"电话营销\\",\\"children\\":[],\\"expand\\":true,\\"__label\\":\\"电话营销\\",\\"__value\\":[\\"电话营销\\"]},{\\"key\\":\\"\\",\\"value\\":\\"主动来电\\",\\"__label\\":\\"拜访\\",\\"__value\\":[\\"主动来电\\"],\\"nodeKey\\":2,\\"isEdit\\":false,\\"label\\":\\"拜访\\"}],\\"required\\":true,\\"multiple\\":false,\\"is_delete\\":true,\\"placeholder\\":\\"请选择线索来源\\"}},{\\"id\\":\\"industry\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"客户行业\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"行业1\\",\\"__label\\":\\"互联网\\",\\"__value\\":[\\"行业1\\"],\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"互联网\\"},{\\"key\\":\\"\\",\\"value\\":\\"行业2\\",\\"__value\\":[\\"行业2\\"],\\"nodeKey\\":2,\\"isEdit\\":false,\\"label\\":\\"信息化\\",\\"__label\\":\\"信息化\\"}],\\"required\\":true,\\"multiple\\":false,\\"is_delete\\":true,\\"placeholder\\":\\"请选择客户行业\\"}},{\\"id\\":\\"mobile\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"手机号\\",\\"readonly\\":false,\\"placeholder\\":\\"手机号\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"level\\",\\"name\\":\\"评分\\",\\"type\\":1,\\"component\\":\\"Rate\\",\\"config\\":{\\"label\\":\\"客户级别\\",\\"allowHalf\\":true,\\"disabled\\":false,\\"type\\":\\"default\\",\\"is_delete\\":true}},{\\"id\\":\\"telephone\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"电话\\",\\"readonly\\":false,\\"placeholder\\":\\"电话\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"address_detail\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"地址\\",\\"readonly\\":false,\\"row\\":2,\\"placeholder\\":\\"请输入地址\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"next_time\\",\\"name\\":\\"时间选择框\\",\\"type\\":1,\\"component\\":\\"TimePicker\\",\\"config\\":{\\"label\\":\\"下次联系时间\\",\\"placeholder\\":\\"点击选择\\",\\"type\\":\\"time\\",\\"format\\":\\"YYYY-MM-DD HH:mm:ss\\",\\"confirm\\":true,\\"required\\":false,\\"readonly\\":false,\\"is_delete\\":true}},{\\"id\\":\\"remarks\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"备注信息\\",\\"readonly\\":false,\\"row\\":2,\\"placeholder\\":\\"备注信息\\",\\"required\\":false,\\"is_delete\\":true}}]}\', 1619592288, 1655433791, NULL);
INSERT INTO `__PREFIX__qingdong_form`
VALUES (12, \'客户管理\', \'customer\',
\'{\\"data\\":[{\\"id\\":\\"name\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"客户名称\\",\\"readonly\\":false,\\"placeholder\\":\\"请输入客户名称\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"subname\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"助记名称\\",\\"readonly\\":false,\\"placeholder\\":\\"请输入助记名称\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"industry\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"客户所属\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"终端客户\\",\\"__label\\":\\"重点客户\\",\\"__value\\":[\\"终端客户\\"],\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"重点客户\\"},{\\"key\\":\\"\\",\\"value\\":\\"代理商\\",\\"__label\\":\\"普通客户\\",\\"__value\\":[\\"代理商\\"],\\"nodeKey\\":2,\\"isEdit\\":false,\\"label\\":\\"普通客户\\"},{\\"key\\":\\"\\",\\"value\\":\\"同行\\",\\"__value\\":[\\"同行\\"],\\"nodeKey\\":3,\\"isEdit\\":false,\\"label\\":\\"非优先客户\\",\\"__label\\":\\"非优先客户\\"}],\\"required\\":true,\\"multiple\\":false,\\"is_delete\\":true,\\"placeholder\\":\\"请输入客户所属\\"}},{\\"id\\":\\"follow\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"客户状态\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"初次接触\\",\\"__label\\":\\"初次接触\\",\\"__value\\":[\\"初次接触\\"],\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"初次接触\\"},{\\"key\\":\\"\\",\\"value\\":\\"正在跟进\\",\\"__label\\":\\"正在跟进\\",\\"__value\\":[\\"正在跟进\\"],\\"nodeKey\\":2,\\"isEdit\\":false,\\"label\\":\\"正在跟进\\"},{\\"key\\":\\"\\",\\"value\\":\\"准备购买\\",\\"__label\\":\\"准备购买\\",\\"__value\\":[\\"准备购买\\"],\\"nodeKey\\":3,\\"isEdit\\":false,\\"label\\":\\"准备购买\\"},{\\"key\\":\\"\\",\\"value\\":\\"准备付款\\",\\"__label\\":\\"准备付款\\",\\"__value\\":[\\"准备付款\\"],\\"nodeKey\\":4,\\"isEdit\\":false,\\"label\\":\\"准备付款\\"},{\\"key\\":\\"\\",\\"value\\":\\"已经购买\\",\\"__label\\":\\"已经购买\\",\\"__value\\":[\\"已经购买\\"],\\"nodeKey\\":5,\\"isEdit\\":false,\\"label\\":\\"已经购买\\"},{\\"key\\":\\"\\",\\"value\\":\\"暂时搁置\\",\\"__label\\":\\"暂时搁置\\",\\"__value\\":[\\"暂时搁置\\"],\\"nodeKey\\":6,\\"isEdit\\":false,\\"label\\":\\"暂时搁置\\"}],\\"required\\":true,\\"multiple\\":false,\\"is_delete\\":true,\\"placeholder\\":\\"请输入客户状态\\"}},{\\"id\\":\\"level\\",\\"name\\":\\"评分\\",\\"type\\":1,\\"component\\":\\"Rate\\",\\"config\\":{\\"label\\":\\"客户星级\\",\\"allowHalf\\":true,\\"disabled\\":false,\\"type\\":\\"default\\",\\"is_delete\\":true,\\"placeholder\\":\\"客户星级\\"}},{\\"id\\":\\"source\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"客户来源\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"行业活动\\",\\"__label\\":\\"行业活动\\",\\"__value\\":[\\"行业活动\\"],\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"行业活动\\"},{\\"key\\":\\"\\",\\"value\\":\\"搜索引擎\\",\\"__label\\":\\"搜索引擎\\",\\"__value\\":[\\"搜索引擎\\"],\\"nodeKey\\":2,\\"isEdit\\":false,\\"label\\":\\"搜索引擎\\"},{\\"key\\":\\"\\",\\"value\\":\\"客户转介绍\\",\\"__label\\":\\"客户转介绍\\",\\"__value\\":[\\"客户转介绍\\"],\\"nodeKey\\":3,\\"isEdit\\":false,\\"label\\":\\"客户转介绍\\"},{\\"key\\":\\"\\",\\"value\\":\\"展会\\",\\"__label\\":\\"展会\\",\\"__value\\":[\\"展会\\"],\\"nodeKey\\":4,\\"isEdit\\":false,\\"label\\":\\"展会\\"},{\\"key\\":\\"\\",\\"value\\":\\"朋友介绍\\",\\"__label\\":\\"朋友介绍\\",\\"__value\\":[\\"朋友介绍\\"],\\"nodeKey\\":5,\\"isEdit\\":false,\\"label\\":\\"朋友介绍\\"},{\\"key\\":\\"\\",\\"value\\":\\"市场推广\\",\\"__value\\":[\\"市场推广\\"],\\"nodeKey\\":6,\\"isEdit\\":false,\\"label\\":\\"市场推广\\",\\"__label\\":\\"市场推广\\"}],\\"required\\":true,\\"multiple\\":false,\\"is_delete\\":true,\\"placeholder\\":\\"客户来源\\"}},{\\"id\\":\\"other_12771\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"备注信息\\",\\"row\\":2,\\"placeholder\\":\\"请输入备注信息\\",\\"required\\":false,\\"is_delete\\":true}}]}\',
1619592291, 1646217144, NULL);
INSERT INTO `__PREFIX__qingdong_form`
VALUES (13, \'联系人管理\', \'contacts\',
\'{\\"data\\":[{\\"id\\":\\"name\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"联系人姓名\\",\\"readonly\\":false,\\"placeholder\\":\\"请输入联系人姓名\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"subname\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"尊称\\",\\"readonly\\":false,\\"placeholder\\":\\"请输入尊称\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_21517\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"电话\\",\\"placeholder\\":\\"请输入联系人电话\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"mobile\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"手机号\\",\\"placeholder\\":\\"请输入联系人手机号\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"role\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"角色\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"普通员工\\",\\"__label\\":\\"普通员工\\",\\"__value\\":[\\"普通员工\\"],\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"普通员工\\"},{\\"key\\":\\"\\",\\"value\\":\\"决策人\\",\\"__label\\":\\"决策人\\",\\"__value\\":[\\"决策人\\"],\\"nodeKey\\":2,\\"isEdit\\":false,\\"label\\":\\"决策人\\"},{\\"key\\":\\"\\",\\"value\\":\\"分项决策人\\",\\"__label\\":\\"分项决策人\\",\\"__value\\":[\\"分项决策人\\"],\\"nodeKey\\":3,\\"isEdit\\":false,\\"label\\":\\"分项决策人\\"},{\\"key\\":\\"\\",\\"value\\":\\"商务决策\\",\\"__label\\":\\"商务决策\\",\\"__value\\":[\\"商务决策\\"],\\"nodeKey\\":4,\\"isEdit\\":false,\\"label\\":\\"商务决策\\"},{\\"key\\":\\"\\",\\"value\\":\\"财务决策\\",\\"__label\\":\\"财务决策\\",\\"__value\\":[\\"财务决策\\"],\\"nodeKey\\":5,\\"isEdit\\":false,\\"label\\":\\"财务决策\\"},{\\"key\\":\\"\\",\\"value\\":\\"使用人\\",\\"__label\\":\\"使用人\\",\\"__value\\":[\\"使用人\\"],\\"nodeKey\\":6,\\"isEdit\\":false,\\"label\\":\\"使用人\\"},{\\"key\\":\\"\\",\\"value\\":\\"意见影响人\\",\\"__label\\":\\"意见影响人\\",\\"__value\\":[\\"意见影响人\\"],\\"nodeKey\\":7,\\"isEdit\\":false,\\"label\\":\\"意见影响人\\"},{\\"key\\":\\"\\",\\"value\\":\\"采购\\",\\"__label\\":\\"采购\\",\\"__value\\":[\\"采购\\"],\\"nodeKey\\":8,\\"isEdit\\":false,\\"label\\":\\"采购\\"},{\\"key\\":\\"\\",\\"value\\":\\"老板\\",\\"__label\\":\\"老板\\",\\"__value\\":[\\"老板\\"],\\"nodeKey\\":9,\\"isEdit\\":false,\\"label\\":\\"老板\\"},{\\"key\\":\\"\\",\\"value\\":\\"股东\\",\\"__label\\":\\"股东\\",\\"__value\\":[\\"股东\\"],\\"nodeKey\\":10,\\"isEdit\\":false,\\"label\\":\\"股东\\"},{\\"key\\":\\"\\",\\"value\\":\\"职业经理人\\",\\"__value\\":[\\"职业经理人\\"],\\"nodeKey\\":11,\\"isEdit\\":false,\\"label\\":\\"职业经理人\\",\\"__label\\":\\"职业经理人\\"}],\\"required\\":true,\\"multiple\\":false,\\"is_delete\\":true,\\"placeholder\\":\\"请选择角色\\"}},{\\"id\\":\\"post\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"部门职务\\",\\"placeholder\\":\\"请输入部门职务\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_4367\\",\\"name\\":\\"日期选择框\\",\\"type\\":1,\\"component\\":\\"DatePicker\\",\\"config\\":{\\"label\\":\\"生日\\",\\"placeholder\\":\\"请输入联系人生日\\",\\"type\\":\\"date\\",\\"value\\":\\"\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"email\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"邮箱\\",\\"placeholder\\":\\"请输入邮箱\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_17344\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"微信\\",\\"placeholder\\":\\"请输入联系人微信\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_23536\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"备注信息\\",\\"row\\":2,\\"placeholder\\":\\"请输入备注信息\\",\\"required\\":false,\\"is_delete\\":true}}]}\',
1619592291, 1643096926, NULL);
INSERT INTO `__PREFIX__qingdong_form`
VALUES (14, \'合同管理\', \'contract\',
\'{\\"data\\":[{\\"id\\":\\"num\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"合同编号\\",\\"readonly\\":false,\\"placeholder\\":\\"输入合同编号\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"name\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"合同名称\\",\\"readonly\\":false,\\"placeholder\\":\\"请输入合同名称\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"money\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"合同金额\\",\\"readonly\\":false,\\"placeholder\\":\\"请输入合同金额\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"order_date\\",\\"name\\":\\"时间选择框\\",\\"type\\":1,\\"component\\":\\"TimePicker\\",\\"config\\":{\\"label\\":\\"下单时间\\",\\"placeholder\\":\\"点击选择\\",\\"type\\":\\"time\\",\\"format\\":\\"HH:mm:ss\\",\\"confirm\\":true,\\"required\\":true,\\"readonly\\":false,\\"is_delete\\":true}},{\\"id\\":\\"start_time\\",\\"name\\":\\"日期选择框\\",\\"type\\":1,\\"component\\":\\"DatePicker\\",\\"config\\":{\\"label\\":\\"合同开始时间\\",\\"placeholder\\":\\"点击选择\\",\\"type\\":\\"date\\",\\"format\\":\\"\\",\\"value\\":\\"\\",\\"required\\":true,\\"readonly\\":false,\\"is_delete\\":true}},{\\"id\\":\\"end_time\\",\\"name\\":\\"日期选择框\\",\\"type\\":1,\\"component\\":\\"DatePicker\\",\\"config\\":{\\"label\\":\\"合同结束时间\\",\\"placeholder\\":\\"点击选择\\",\\"type\\":\\"date\\",\\"format\\":\\"\\",\\"value\\":\\"\\",\\"required\\":true,\\"readonly\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_47006\\",\\"name\\":\\"单选框\\",\\"type\\":1,\\"component\\":\\"radio\\",\\"config\\":{\\"label\\":\\"是否含税\\",\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"含税\\"},{\\"key\\":\\"\\",\\"value\\":\\"不含税\\"}],\\"placeholder\\":\\"请输入\\",\\"required\\":false,\\"is_delete\\":true}}]}\',
1619592291, 1643020154, NULL);
INSERT INTO `__PREFIX__qingdong_form`
VALUES (15, \'回款管理\', \'examine\',
\'{\\"data\\":[{\\"id\\":\\"number\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"回款编号\\",\\"placeholder\\":\\"请输入回款编号\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"return_time\\",\\"name\\":\\"日期选择框\\",\\"type\\":1,\\"component\\":\\"DatePicker\\",\\"config\\":{\\"label\\":\\"回款日期\\",\\"placeholder\\":\\"点击选择\\",\\"type\\":\\"date\\",\\"value\\":\\"\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"money\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"回款金额\\",\\"placeholder\\":\\"请输入回款金额\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"return_type\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"回款方式\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"微信\\",\\"__label\\":\\"微信\\",\\"__value\\":[\\"微信\\"],\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"微信\\"}],\\"required\\":true,\\"is_delete\\":true}}]}\',
1619592291, 1643020163, NULL);
INSERT INTO `__PREFIX__qingdong_form` VALUES (16, \'日报管理\', \'daily\', \'{\\"data\\":[{\\"id\\":\\"other_43472\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.1.完成了哪些工作\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_48871\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.2.取得了哪些成绩\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_33048\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.3.当前进展如何\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_82389\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.4.计划实施情况\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}}]}\', 1619491859, 1640141699, NULL);
INSERT INTO `__PREFIX__qingdong_form` VALUES (17, \'周报管理\', \'weekly\', \'{\\"data\\":[{\\"id\\":\\"other_72263\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.1.完成了哪些工作\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_22415\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.2.取得了哪些成绩\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_41856\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.3.当前进展如何\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}}]}\', 1643020163, 1643020163, NULL);
INSERT INTO `__PREFIX__qingdong_form` VALUES (18, \'月报管理\', \'monthly\', \'{\\"data\\":[{\\"id\\":\\"other_79661\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.1.完成了哪些工作\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_52344\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.2.取得了哪些成绩\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_15457\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.3.当前进展如何\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}}]}\', 1643020163, 1643020163, NULL);
INSERT INTO `__PREFIX__qingdong_form` VALUES (19, \'季报管理\', \'quarterly\', \'{\\"data\\":[{\\"id\\":\\"other_43472\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.1.完成了哪些工作\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_48871\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.2.取得了哪些成绩\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_33048\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.3.当前进展如何\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_82389\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.4.计划实施情况\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}}]}\', 1619491859, 1640141727, NULL);
INSERT INTO `__PREFIX__qingdong_form` VALUES (20, \'年报管理\', \'yearly\', \'{\\"data\\":[{\\"id\\":\\"other_43472\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.1.完成了哪些工作\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_48871\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.2.取得了哪些成绩\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_33048\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.3.当前进展如何\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_82389\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"1.4.计划实施情况\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_90392\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"2.1 面临哪些挑战\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_72126\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"2.2 什么原因导致的\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_39787\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"2.3 有何改进措施\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"other_66752\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"3.1 节约了哪些成本\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_62312\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"3.2 提升了哪些效率\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_62889\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"3.3 优化了哪些步骤\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_98365\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"3.4 拓宽了哪些渠道\\",\\"row\\":2,\\"placeholder\\":\\"请输入内容\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_80726\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"4.1 下一步的安排\\",\\"row\\":2,\\"placeholder\\":\\"请输入下一步的安排\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_15038\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"4.2 需要的资源支持\\",\\"row\\":2,\\"placeholder\\":\\"请输入需要的资源支持\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_970\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"4.3 预计达到的结果\\",\\"row\\":2,\\"placeholder\\":\\"请输入预计达到的结果\\",\\"required\\":false,\\"is_delete\\":true}}]}\', 1643020163, 1643020163, NULL);
INSERT INTO `__PREFIX__qingdong_form` VALUES (21, \'外勤签到\', \'signin\', \'{\\"data\\":[{\\"id\\":\\"other_35260\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"备注\\",\\"row\\":2,\\"placeholder\\":\\"请输入备注\\",\\"required\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_65453\\",\\"name\\":\\"图片上传\\",\\"type\\":1,\\"component\\":\\"uploadImage\\",\\"config\\":{\\"label\\":\\"图片上传\\",\\"value\\":[],\\"required\\":false,\\"placeholder\\":\\"请上传图片\\",\\"maxnum\\":1,\\"is_delete\\":true,\\"format\\":[\\"jpg\\",\\"jpeg\\",\\"png\\"],\\"maxSize\\":5000}}],\\"isAddContact\\":true}\', 1643020163, 1657163099, NULL);
INSERT INTO `__PREFIX__qingdong_form` VALUES (22, \'商机管理\', \'business\', \'{\\"data\\":[{\\"id\\":\\"name\\",\\"name\\":\\"单行输入框\\",\\"type\\":1,\\"component\\":\\"input\\",\\"config\\":{\\"type\\":\\"text\\",\\"label\\":\\"商机名称\\",\\"readonly\\":false,\\"placeholder\\":\\"商机名称\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"money\\",\\"name\\":\\"数字框\\",\\"type\\":1,\\"component\\":\\"input-number\\",\\"config\\":{\\"label\\":\\"商机金额\\",\\"placeholder\\":\\"请输入商机金额\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"status\\",\\"name\\":\\"下拉选择框\\",\\"type\\":1,\\"component\\":\\"select\\",\\"config\\":{\\"label\\":\\"商机状态\\",\\"type\\":null,\\"content\\":[{\\"key\\":\\"\\",\\"value\\":\\"行业1\\",\\"__label\\":\\"验证客户\\",\\"__value\\":[\\"行业1\\"],\\"nodeKey\\":1,\\"isEdit\\":false,\\"label\\":\\"验证客户\\"},{\\"key\\":\\"\\",\\"value\\":\\"行业2\\",\\"__value\\":[\\"行业2\\"],\\"nodeKey\\":2,\\"isEdit\\":false,\\"label\\":\\"需求分析\\",\\"__label\\":\\"需求分析\\"},{\\"label\\":\\"方案/报价\\",\\"expand\\":true,\\"value\\":\\"0-0\\",\\"isEdit\\":false,\\"__label\\":\\"方案/报价\\",\\"__value\\":[\\"0-0\\"],\\"nodeKey\\":3},{\\"label\\":\\"赢单\\",\\"expand\\":true,\\"value\\":\\"0-0\\",\\"isEdit\\":false,\\"__label\\":\\"赢单\\",\\"__value\\":[\\"0-0\\"],\\"nodeKey\\":4},{\\"label\\":\\"输单\\",\\"expand\\":true,\\"value\\":\\"0-0\\",\\"isEdit\\":false,\\"__label\\":\\"输单\\",\\"__value\\":[\\"0-0\\"],\\"nodeKey\\":5}],\\"required\\":true,\\"multiple\\":false,\\"is_delete\\":true,\\"placeholder\\":\\"请选择商机状态\\"}},{\\"id\\":\\"expect_time\\",\\"name\\":\\"日期选择框\\",\\"type\\":1,\\"component\\":\\"DatePicker\\",\\"config\\":{\\"label\\":\\"预计成交时间\\",\\"placeholder\\":\\"请输入预计成交时间\\",\\"type\\":\\"date\\",\\"value\\":\\"\\",\\"required\\":true,\\"is_delete\\":true}},{\\"id\\":\\"next_time\\",\\"name\\":\\"时间选择框\\",\\"type\\":1,\\"component\\":\\"TimePicker\\",\\"config\\":{\\"label\\":\\"下次跟进时间\\",\\"placeholder\\":\\"点击选择\\",\\"type\\":\\"time\\",\\"format\\":\\"YYYY-MM-DD HH:mm:ss\\",\\"confirm\\":true,\\"required\\":false,\\"readonly\\":false,\\"is_delete\\":true}},{\\"id\\":\\"other_48629\\",\\"name\\":\\"图片上传\\",\\"type\\":1,\\"component\\":\\"uploadImage\\",\\"config\\":{\\"label\\":\\"图片上传\\",\\"value\\":[],\\"required\\":false,\\"placeholder\\":\\"请上传图片\\",\\"maxnum\\":1,\\"is_delete\\":true,\\"format\\":[\\"jpg\\",\\"jpeg\\",\\"png\\"],\\"maxSize\\":5000}},{\\"id\\":\\"remark\\",\\"name\\":\\"文本框\\",\\"type\\":1,\\"component\\":\\"textarea\\",\\"config\\":{\\"label\\":\\"备注信息\\",\\"readonly\\":false,\\"row\\":2,\\"placeholder\\":\\"备注信息\\",\\"required\\":false,\\"is_delete\\":true}}],\\"isAddContact\\":true}\', 1619592288, 1659082152, NULL);
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (1, \'审批通知\', \'examine\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"{{staff_name}}\\\\u53d1\\\\u8d77\\\\u4e00\\\\u4e2a\\\\u300a\\\\u5ba1\\\\u6279\\\\u300b\\\\u6307\\\\u5b9a\\\\u7531\\\\u60a8\\\\u5904\\\\u7406\\",\\"keyword1\\":\\"{{examine_type}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{{date}}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u8bf7\\\\u53ca\\\\u65f6\\\\u5904\\\\u7406\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (3, \'新建跟进记录通知\', \'record\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"{{staff_name}}\\\\u521a\\\\u521a\\\\u65b0\\\\u5efa\\\\u4e86\\\\u4e00\\\\u6761\\\\u300a\\\\u8ddf\\\\u8fdb\\\\u8bb0\\\\u5f55\\\\u300b\\\\u6307\\\\u5b9a\\\\u7531\\\\u60a8\\\\u5ba1\\\\u9605\\",\\"keyword1\\":\\"{{customer_name}}{{staff_department}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{{customer_follow}}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{{date}}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u8bf7\\\\u53ca\\\\u65f6\\\\u5904\\\\u7406\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (4, \'新建工作报告通知\', \'daily\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"{{staff_name}}\\\\u521a\\\\u521a\\\\u65b0\\\\u5efa\\\\u4e86\\\\u4e00\\\\u6761\\\\u300a\\\\u5de5\\\\u4f5c\\\\u62a5\\\\u544a\\\\u300b\\\\u6307\\\\u5b9a\\\\u7531\\\\u60a8\\\\u5ba1\\\\u9605\\",\\"keyword1\\":\\"{staff_name}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{daily_type}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{date}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (5, \'回收客户到公海通知\', \'seas\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"\\\\u60a8\\\\u7684\\\\u5ba2\\\\u6237\\\\u957f\\\\u65f6\\\\u95f4\\\\u672a\\\\u8ddf\\\\u8fdb\\\\uff0c\\\\u5df2\\\\u88ab\\\\u7cfb\\\\u7edf\\\\u81ea\\\\u52a8\\\\u56de\\\\u6536\\\\u5230\\\\u516c\\\\u6d77\\\\u6c60\\\\u5185\\\\u3002\\",\\"keyword1\\":\\"{{customer_name}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{{day}}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{{date}}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u5efa\\\\u8bae\\\\u5ba2\\\\u6237\\\\u53ca\\\\u65f6\\\\u8ddf\\\\u8fdb\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (6, \'出差签到通知\', \'sign\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"{{staff_name}}\\\\u63d0\\\\u4ea4\\\\u4e86\\\\u4e00\\\\u4e2a\\\\u51fa\\\\u5dee\\\\u7b7e\\\\u5230\\\\uff0c\\\\u7531\\\\u60a8\\\\u5ba1\\\\u9605\\\\uff01\\",\\"keyword1\\":\\"{{address}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{{date}}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{{customer_name}}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u8bf7\\\\u53ca\\\\u65f6\\\\u5ba1\\\\u9605\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (7, \'审批通过通知\', \'examine_adopt\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"\\\\u60a8\\\\u63d0\\\\u4ea4\\\\u7684\\\\u5ba1\\\\u6279\\\\u5df2\\\\u5ba1\\\\u6838\\\\u901a\\\\u8fc7\\\\uff01\\",\\"keyword1\\":\\"{{check_name}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{examine_type}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{submit_time}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u5ba1\\\\u6838\\\\u901a\\\\u8fc7\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (8, \'审批拒绝通知\', \'examine_refuse\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"\\\\u60a8\\\\u63d0\\\\u4ea4\\\\u7684\\\\u5ba1\\\\u6279\\\\u88ab\\\\u62d2\\\\u7edd\\\\uff01\\",\\"keyword1\\":\\"{{staff_name}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{check_name}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{examine_type}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"{{examine_desc}}\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u5ba1\\\\u6838\\\\u62d2\\\\u7edd\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (9, \'合同到期通知\', \'contract_expire\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"\\\\u5408\\\\u540c\\\\u5373\\\\u5c06\\\\u5230\\\\u671f\\\\uff0c\\\\u8bf7\\\\u5c3d\\\\u5feb\\\\u8ddf\\\\u8fdb\\\\u56de\\\\u6b3e\\",\\"keyword1\\":\\"{customer_name}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{money}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u8bf7\\\\u53ca\\\\u65f6\\\\u8ddf\\\\u8fdb\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (10, \'回款计划到期通知\', \'plan_expire\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"\\\\u5df2\\\\u5230\\\\u8ba1\\\\u5212\\\\u56de\\\\u6b3e\\\\u7ea6\\\\u5b9a\\\\u65f6\\\\u95f4\\\\uff0c\\\\u8bf7\\\\u5c3d\\\\u5feb\\\\u8ddf\\\\u8fdb\\\\u56de\\\\u6b3e\\",\\"keyword1\\":\\"{{customer_name}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{{plan_money}}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{{plan_time}}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u8bf7\\\\u53ca\\\\u65f6\\\\u8ddf\\\\u8fdb\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (11, \'评论通知\', \'comment\',
\'{\\"template_id\\":\\"\\",\\"first\\":\\"\\\\u8bc4\\\\u8bba\\\\u4e86\\\\u60a8\\\\u63d0\\\\u4ea4\\\\u7684\\\\u8ddf\\\\u8fdb\\\\u8bb0\\\\u5f55\\\\uff01\\",\\"keyword1\\":\\"{{staff_name}}\\",\\"keyword1_color\\":\\"#666\\",\\"keyword2\\":\\"{{content}}\\",\\"keyword2_color\\":\\"#666\\",\\"keyword3\\":\\"{{date}}\\",\\"keyword3_color\\":\\"#666\\",\\"keyword4\\":\\"\\",\\"keyword4_color\\":\\"#666\\",\\"keyword5\\":\\"\\",\\"keyword5_color\\":\\"#666\\",\\"remark\\":\\"\\\\u8bf7\\\\u53ca\\\\u65f6\\\\u5904\\\\u7406\\\\uff01\\",\\"remark_color\\":\\"#666\\"}\');
INSERT INTO `__PREFIX__qingdong_notice_template`
VALUES (12, \'日程通知\', \'event\',
\'{"template_id":"","first":"{{event_title}}日程即将开始","keyword1":"","keyword1_color":"#666","keyword2":"","keyword2_color":"#666","keyword3":"","keyword3_color":"#666","keyword4":"","keyword4_color":"#666","keyword5":"","keyword5_color":"#666","remark":"请及时处理!","remark_color":"#666"}\');
INSERT INTO `__PREFIX__qingdong_flow` VALUES (1, \'费用 \', \'[{}]\', 0, \'\', \'consume\', \'\', NULL, 1657014906, 1, 1657014906, 1657014906, NULL);
INSERT INTO `__PREFIX__qingdong_flow` VALUES (2, \'业绩\', \'[{}]\', 0, \'\', \'achievement\', \'\', NULL, 1657767346, 1, 1657767346, 1657767346, NULL);
INSERT INTO `__PREFIX__qingdong_flow` VALUES (3, \'回款\', \'[{}]\', 0, \'\', \'receivables\', \'\', NULL, 1658388920, 1, 1658388920, 1658388920, NULL);
INSERT INTO `__PREFIX__qingdong_flow` VALUES (4, \'合同\', \'[{}]\', 0, \'\', \'contract\', \'\', NULL, 1658388928, 1, 1658388928, 1658388928, NULL);
INSERT INTO `__PREFIX__qingdong_flow` VALUES (5, \'补卡\', \'[{}]\', 0, \'\', \'card\', \'\', NULL, 1658388928, 1, 1658388928, 1658388928, NULL);
INSERT INTO `__PREFIX__qingdong_flow` VALUES (6, \'请假\', \'[{}]\', 0, \'\', \'leave\', \'\', NULL, 1658388928, 1, 1658388928, 1658388928, NULL);
ALTER TABLE `__PREFIX__qingdong_achievement_records`
ADD COLUMN `flow_id` int(11) NULL COMMENT \'审核流程ID\' AFTER `flow_staff_ids`,
ADD COLUMN `order_id` int(11) NULL COMMENT \'审批流程步骤id\' AFTER `flow_id`;
ALTER TABLE `__PREFIX__qingdong_approval`
ADD COLUMN `flow_id` int(11) NULL COMMENT \'审核流程ID\' AFTER `check_status`,
ADD COLUMN `order_id` int(11) NULL COMMENT \'审批流程步骤id\' AFTER `flow_id`;
ALTER TABLE `__PREFIX__qingdong_consume`
ADD COLUMN `flow_id` int(11) NULL COMMENT \'审核流程ID\' AFTER `flow_staff_ids`,
ADD COLUMN `order_id` int(11) NULL COMMENT \'审批流程步骤id\' AFTER `flow_id`;
ALTER TABLE `__PREFIX__qingdong_contract`
ADD COLUMN `flow_id` int(11) NULL COMMENT \'审核流程ID\' AFTER `remarks`,
ADD COLUMN `order_id` int(11) NULL COMMENT \'审批流程步骤id\' AFTER `flow_id`;
ALTER TABLE `__PREFIX__qingdong_contract`
ADD COLUMN `ratios` varchar(255) NULL DEFAULT NULL COMMENT \'业绩比例\' AFTER `order_id`;
ALTER TABLE `__PREFIX__qingdong_contract` ADD COLUMN `business_id` int(11) NULL COMMENT \'商机ID\' AFTER `order_staff_id`;
ALTER TABLE `__PREFIX__qingdong_contract`
ADD COLUMN `ratio_id` int(11) NULL COMMENT \'绩效ID\' AFTER `order_id`;
ALTER TABLE `__PREFIX__qingdong_customer`
ADD COLUMN `ro_staff_id` varchar(255) NULL DEFAULT \'\' COMMENT \'只读权限\' AFTER `owner_staff_id`,
ADD COLUMN `rw_staff_id` varchar(255) NULL DEFAULT \'\' COMMENT \'读写权限\' AFTER `ro_staff_id`;
ALTER TABLE `__PREFIX__qingdong_customer` MODIFY COLUMN `address_detail` varchar(255) NULL DEFAULT NULL COMMENT \'详细地址\' AFTER `address`;
ALTER TABLE `__PREFIX__qingdong_customer` MODIFY COLUMN `remarks` text NULL COMMENT \'备注信息\' AFTER `lat`;
ALTER TABLE `__PREFIX__qingdong_file`
MODIFY COLUMN `types` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT \'类型(file、image)\' AFTER `id`;
ALTER TABLE `__PREFIX__qingdong_flow`
ADD COLUMN `status` tinyint(1) DEFAULT NULL COMMENT \'1 固定审批 0 授权审批\' AFTER `examine_ids`,
ADD COLUMN `remark` varchar(255) DEFAULT NULL COMMENT \'备注\' AFTER `status`,
ADD COLUMN `relation_type` varchar(255) DEFAULT NULL COMMENT \'关联类型\' AFTER `remark`,
ADD COLUMN `group_ids` varchar(255) DEFAULT NULL COMMENT \'关联角色组\' AFTER `relation_type`,
ADD COLUMN `weight` tinyint(4) DEFAULT NULL COMMENT \'权重\' AFTER `group_ids`,
ADD COLUMN `last_modified` int(11) DEFAULT NULL COMMENT \'最后修改时间\' AFTER `weight`,
ADD COLUMN `last_admin_id` int(11) DEFAULT NULL COMMENT \'最后修改人\' AFTER `last_modified`,
ADD COLUMN `deletetime` int(11) DEFAULT NULL AFTER `updatetime`;
ALTER TABLE `__PREFIX__qingdong_form_approval`
ADD COLUMN `examine_ids` text COMMENT \'默认审核人id\' AFTER `form_id`,
ADD COLUMN `status` tinyint(1) DEFAULT NULL COMMENT \'1 固定审批 0 授权审批\' AFTER `examine_ids`;
ALTER TABLE `__PREFIX__qingdong_product`
ADD COLUMN `cost_price` decimal(10,2) DEFAULT NULL COMMENT \'成本价\' AFTER `min_price`,
MODIFY COLUMN `description` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT \'产品描述\' AFTER `status`;
ALTER TABLE `__PREFIX__qingdong_product_part`
MODIFY COLUMN `description` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT \'产品描述\' AFTER `img`;
ALTER TABLE `__PREFIX__qingdong_receivables`
ADD COLUMN `flow_id` int(11) NULL COMMENT \'审核流程ID\' AFTER `check_status`,
ADD COLUMN `order_id` int(11) NULL COMMENT \'审批流程步骤id\' AFTER `flow_id`;
ALTER TABLE `__PREFIX__qingdong_staff_sign_in` ADD COLUMN `other` text NULL COMMENT \'表单信息\' AFTER `file_ids`;
ALTER TABLE `__PREFIX__qingdong_customer` ADD COLUMN `seas_id` varchar(128) NULL DEFAULT NULL COMMENT \'所属公海\' AFTER `parent_id`;
ALTER TABLE `__PREFIX__qingdong_staff` MODIFY COLUMN `role` int(11) NULL DEFAULT NULL COMMENT \'角色id\' AFTER `group_ids`;
ALTER TABLE `__PREFIX__qingdong_customer` ADD COLUMN `sea_time` int(11) NULL COMMENT \'放入公海时间\' AFTER `rw_staff_id`;
INSERT INTO `__PREFIX__qingdong_seas_type` VALUES (1, \'默认公海\', \'客户不满足其他公海规则时,会移入当前公海\', NULL, NULL, NULL, NULL);
INSERT INTO `__PREFIX__qingdong_staff_rule` VALUES (1, \'menus\', 0, \'seas\', \'公海客户\', \'\', 1, \'\');
INSERT INTO `__PREFIX__qingdong_staff_rule` VALUES (2, \'data\', 1, 1, \'默认公海\', \'\', 0, \'\');
ALTER TABLE `__PREFIX__qingdong_notice_template`
MODIFY COLUMN `data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT \'微信公众号\' AFTER `type`,
ADD COLUMN `wechat` text NULL COMMENT \'企业微信\' AFTER `data`,
ADD COLUMN `createtime` int(11) NULL COMMENT \'创建时间\' AFTER `wechat`,
ADD COLUMN `updatetime` int(11) NULL COMMENT \'修改时间\' AFTER `createtime`,
ADD COLUMN `deletetime` int(11) NULL COMMENT \'删除时间\' AFTER `updatetime`;
ALTER TABLE `__PREFIX__qingdong_staff`
ADD COLUMN `touser` varchar(50) NULL COMMENT \'企业微信userid\' AFTER `wx_openid`;
ALTER TABLE `__PREFIX__qingdong_leads`
ADD COLUMN `receive_time` int(11) NULL COMMENT \'分配时间\' AFTER `follow`;
ALTER TABLE `__PREFIX__qingdong_notice_template`
ADD COLUMN `enterprise_data` text NULL COMMENT \'企业微信通知\' AFTER `data`;
ALTER TABLE `__PREFIX__qingdong_product`
ADD COLUMN `goods_id` int(11) NULL DEFAULT NULL COMMENT \'商品ID\' AFTER `id`,
ADD COLUMN `type` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT \'规格\' AFTER `name`;
ALTER TABLE `__PREFIX__qingdong_product_type`
ADD COLUMN `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT \'内容\' AFTER `image`,
ADD COLUMN `status` tinyint(1) NULL DEFAULT NULL COMMENT \'状态\' AFTER `content`;
ALTER TABLE `__PREFIX__qingdong_record`
ADD COLUMN `location` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT \'定位信息\' AFTER `deletetime`,
ADD COLUMN `lng` double(16, 12) NULL DEFAULT NULL COMMENT \'地理位置经度\' AFTER `location`,
ADD COLUMN `lat` double(16, 12) NULL DEFAULT NULL COMMENT \'地理位置维度\' AFTER `lng`;
',
);

8935
addons/qingdong/config/menu.php

File diff suppressed because it is too large

361
addons/qingdong/controller/Achievement.php

@ -0,0 +1,361 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Achievement as AchievementModel;
use addons\qingdong\model\AchievementRecords;
use addons\qingdong\model\ExamineRecord;
use addons\qingdong\model\Flow;
use addons\qingdong\model\Message;
use addons\qingdong\model\StaffDepartment;
use addons\qingdong\model\Staff;
use think\Db;
use think\Exception;
/**
* 业绩管理接口
*/
class Achievement extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
/**
* 部门列表
*/
public function getDepartment() {
$department = StaffDepartment::where([])->field('id,name')->select();
$department = array_merge([['id' => 0, 'name' => '全部']], $department);
$this->success('请求成功', ['department' => $department, 'years' => getYears()]);
}
/**
* 获取员工业绩目标
*/
public function getStaffList() {
$department_id = input('department_id');
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);
$where = [];
if ($department_id) {
$where['department_id'] = $department_id;
}
$where['status'] = 1;
$staffModel = new Staff();
$staffs = $staffModel->where($where)->field('id,name,img,post')->with([
'achievement' => function ($query) use ($year, $status) {
$query->where(['year' => $year, 'status' => $status])->field('yeartarget,obj_id');
},
'department'
])->select();
foreach ($staffs as $k => $v) {
if (empty($v['achievement'])) {
$v['achievement'] = ['yeartarget' => 0];
}
$staffs[$k] = $v;
}
$this->success('请求成功', $staffs);
}
/**
* 获取部门业绩列表
*/
public function getDepartmentList() {
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);
$departmentModel = new StaffDepartment();
$staffs = $departmentModel->where([])->field('id,name')->with([
'achievement' => function ($query) use ($year, $status) {
$query->where(['year' => $year, 'status' => $status])->field('yeartarget,obj_id');
},
])->select();
foreach ($staffs as $k => $v) {
if (empty($v['achievement'])) {
$v['achievement'] = ['yeartarget' => 0];
}
$staffs[$k] = $v;
}
$this->success('请求成功', $staffs);
}
/**
* 获取团队业绩
*/
public function getTeamList() {
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);
$staffModel = new Staff();
//1最高管理员 2公司管理员 3部门经理 4部门主管 5组长 6员工
$staffs = $staffModel->where([
'role' => ['in', [1, 2, 3, 4, 5]]
])->field('id,name,img,post')->with([
'teamAchievement' => function ($query) use ($year, $status) {
//团队
$query->where(['year' => $year, 'status' => $status])->field('yeartarget,obj_id');
},
])->select();
$staffs = collection($staffs)->toArray();
foreach ($staffs as $k => $v) {
$v['achievement'] = $v['team_achievement'] ?? ['yeartarget' => 0];
unset($v['team_achievement']);
$staffs[$k] = $v;
}
$this->success('请求成功', $staffs);
}
/**
* 获取公司目标
*/
public function getCompanyAchievement() {
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);//1销售(目标)2回款(目标)
$model = new AchievementModel();
$achievements = $model->where([
'type' => 1,
'obj_id' => 1,
'year' => $year,
'status' => $status
])->find();
if (empty($achievements)) {
$model->save(['type' => 1, 'year' => $year, 'status' => $status]);
$achievements = $model->where(['type' => 1, 'year' => $year, 'status' => $status])->find();
}
$this->success('请求成功', $achievements);
}
/**
* 获取目标
*/
public function getMyAchievementDetail() {
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);//1销售(目标)2回款(目标)
$model = new AchievementModel();
$row = $model->where([
'obj_id' => $this->auth->id,
'type' => 3,
'year' => $year,
'status' => $status
])->find();
$this->success('请求成功', $row);
}
/**
* 获取目标详情
*/
public function getAchievementDetail() {
$type = input('type');
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);//1销售(目标)2回款(目标)
$ids = input('ids');
if (empty($ids)) {
$this->error('参数不能为空');
}
$ids = explode(',', $ids);
$model = new AchievementModel();
$row = $model->where([
'obj_id' => $ids[0],
'type' => $type,
'year' => $year,
'status' => $status
])->find();
$this->success('请求成功', $row);
}
/**
* 添加或修改目标
*/
public function addAchievement() {
$type = input('type');
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);//1销售(目标)2回款(目标)
$achievements = input('achievements/a');
$ids = input('ids');
$yeartarget = input('yeartarget',0);
$model = new AchievementModel();
$ids = explode(',', $ids);
$insertAll = [];
foreach ($ids as $id) {
$insertAll[] = [
'type' => $type,
'year' => $year,
'status' => $status,
'obj_id' => $id,
'january' => $achievements['january'] ?? 0,
'february' => $achievements['february'] ?? 0,
'march' => $achievements['march'] ?? 0,
'april' => $achievements['april'] ?? 0,
'june' => $achievements['june'] ?? 0,
'may' => $achievements['may'] ?? 0,
'july' => $achievements['july'] ?? 0,
'august' => $achievements['august'] ?? 0,
'september' => $achievements['september'] ?? 0,
'october' => $achievements['october'] ?? 0,
'november' => $achievements['november'] ?? 0,
'december' => $achievements['december'] ?? 0,
'yeartarget' => $yeartarget,
'createtime' => time(),
'updatetime' => time()
];
}
Db::startTrans();
try {
$model->where([
'obj_id' => ['in', $ids],
'type' => $type,
'year' => $year,
'status' => $status
])->delete();
if ($model->insertAll($insertAll) == false) {
throw new Exception('提交失败');
}
Db::commit();;
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('提交成功!');
}
/**
* 获取目标详情
*/
public function staffEditAchievement() {
$type = 3;//员工
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);//1销售(目标)2回款(目标)
$achievements = input('achievements/a');
$flow_staff_id = input('flow_staff_ids');
$yeartarget = input('yeartarget',0);
$model = new AchievementRecords();
$id = $this->auth->id;
$params = [
'type' => $type,
'year' => $year,
'status' => $status,
'obj_id' => $id,
'january' => $achievements['january'] ?? 0,
'february' => $achievements['february'] ?? 0,
'march' => $achievements['march'] ?? 0,
'april' => $achievements['april'] ?? 0,
'june' => $achievements['june'] ?? 0,
'may' => $achievements['may'] ?? 0,
'july' => $achievements['july'] ?? 0,
'august' => $achievements['august'] ?? 0,
'september' => $achievements['september'] ?? 0,
'october' => $achievements['october'] ?? 0,
'november' => $achievements['november'] ?? 0,
'december' => $achievements['december'] ?? 0,
'flow_staff_ids' => $flow_staff_id,
'owner_staff_id'=> $this->auth->id,
'check_status' => 0,
'yeartarget' => $yeartarget,
'createtime' => time(),
'updatetime' => time()
];
Db::startTrans();
try {
$flow = Flow::getsteplist(Flow::ACHIEVEMENT_STATUS);
$params['flow_id'] = $flow['flow_id'];
$params['order_id'] = $flow['order_id'];
if ($flow['status'] == 0) {//发起人自选
if (empty($params['flow_staff_ids'])) {
throw new Exception('审批人必须选择');
}
$params['flow_staff_ids'] = trim($params['flow_staff_ids']);
} else {
if (empty($flow['flow_staff_ids'])) {
throw new Exception('没有直属上级无法审批,请联系管理员!');
}
$params['flow_staff_ids'] = trim($flow['flow_staff_ids']);
}
if ($model->insert($params) === false) {
throw new Exception('添加失败');
}
$lastId = $model->getLastInsID();
if ($flow['status'] == 1) {//固定审批
//发送审批通知
Flow::sendStepRecord($flow,Flow::ACHIEVEMENT_STATUS, $lastId);
} else {//发起人自选 依次审批
$staff_id = explode(',', $params['flow_staff_ids'])[0];
if ($staff_id) {
ExamineRecord::addExaminse(ExamineRecord::ACHIEVEMENT_TYPE, $lastId, $staff_id);
}
}
Db::commit();;
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('提交成功,等待审核!');
}
/**
* 员工自己修改目标
*/
public function editRecords(){
$department_id = input('department_id');
$year = input('year', date('Y'), 'intval');
$status = input('status', 1);
$limit = input("limit/d", 10);
$where = [];
if ($department_id) {
$where['department_id'] = $department_id;
}
$where['year'] = $year;
$where['status'] = $status;
$model = new AchievementRecords();
$list = $model->where(['type'=>3,'obj_id'=>$this->auth->id])->where($where)->with(['staff'])->order('id desc')->paginate($limit);
$this->success('请求成功',$list);
}
/**
* 获取业绩详情表
*/
public function getRecordsDetail(){
$id=input('id');
$model = new AchievementRecords();
$records = $model->where(['id'=>$id])->with(['staff'])->find();
if (empty($records)) {
$this->error('业绩目标不存在');
}
if ($records['check_status'] == 0 || $records['check_status'] == 1) {
$records['is_examine'] = ExamineRecord::isExaminse(ExamineRecord::ACHIEVEMENT_TYPE, $id);
} else {
$records['is_examine'] = 0;
}
//标记通知已读
Message::setRead(Message::ACHIEVEMENT_TYPE, $id, $this->auth->id);
$this->success('请求成功', $records);
}
}

216
addons/qingdong/controller/Approval.php

@ -0,0 +1,216 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Approval as ApprovalModel;
use addons\qingdong\model\ExamineRecord;
use addons\qingdong\model\File;
use addons\qingdong\model\FormApproval;
use addons\qingdong\model\Message;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Form;
use think\Db;
use think\Exception;
/**
* 工作审批
*/
class Approval extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
/**
* 审核审核记录
*/
public function examineApprovalList(){
$check_status=input('check_status');//1审核中、2审核通过、3审核未通过
$formapproval_id=input('formapproval_id');//
$times=input('times');//
$where=[];
if($formapproval_id){
$where['formapproval_id']=$formapproval_id;
}
if($times){
$times = explode(',', $times);
$where['createtime']=['between',[strtotime($times[0]),strtotime($times[1])+86400-1]];
}
if ($check_status) {
//0待审核、1审核中、2审核通过、3审核未通过、4撤销
if ($check_status == 1) {
$where['check_status'] = ['in', [0, 1]];
} elseif ($check_status == 2) {
$where['check_status'] = 2;
} elseif ($check_status == 3) {
$where['check_status'] = 3;
} elseif ($check_status == 4) {
$where['check_status'] = 4;
} elseif ($check_status == 9) {
$where['check_status'] = 9;
}
}
$type = input('type', 0);// 0 全部 1 我创建 2 下属创建
if ($type == 1) {//我的客户
$where['create_staff_id'] = $this->auth->id;
} elseif ($type == 2) {//下属负责的客户
$where['create_staff_id'] = ['in', Staff::getLowerStaffId()];
}else{
$where['create_staff_id'] = ['in', Staff::getMyStaffIds()];
}
$staff_id=$this->auth->id;
$approvals= ApprovalModel::where($where)->where(function ($query) use ($staff_id){
$query->where('create_staff_id',$staff_id)
->whereOr('','exp', Db::raw('FIND_IN_SET(' . $staff_id. ',flow_staff_ids)'));
})->with(['createStaff','formapproval'])->order('id desc')->paginate();
$this->success('请求成功',$approvals);
}
/**
* 获取工作列表
*/
public function getList() {
$list = FormApproval::where([])->field('id,name,img')->select();
$this->success('请求成功', $list);
}
/**
* 获取form表单
*/
public function getFormapproval() {
$id = input('id');
$form = FormApproval::where(['id' => $id])->find();
$staff = Staff::where(['id' => ['in',explode(',', $form['flow_staff_ids'])]])->field('id,name,img')->select();
$forminfo = Form::where(array('id'=>$form['form_id']))->find();
$data=json_decode($forminfo['data'], true)['data']??[];
$this->success('请求成功',['data'=>$data,'staff'=>$staff] );
}
/**
* 添加审批
*/
public function addApproval() {
$params = $this->request->post();
if(empty( $params['data'])){
$this->error('数据不能为空');
}
if(empty( $params['formapproval_id'])){
$this->error('表单id不能为空');
}
$result = ApprovalModel::createApproval($params);
$this->success('保存成功');
}
/**
* 获取审批详情
*/
public function getDetail(){
$id = input('id');
if(empty($id)){
$this->error('参数不能为空');
}
$approval=ApprovalModel::where(['id'=>$id])->with(['formapproval'])->find()->toArray();
$type = Form::where(array('id'=>$approval['formapproval']['form_id']))->value('type');
$form = Form::getDataValue($type,$approval['content']);
foreach($form as $k=>$v){
if($v['component'] == 'uploadImage' || $v['component'] == 'uploadFile'){
if(key_exists($v['id'],$approval['content'])){
if(isset($approval['content'][$v['id']]) && $approval['content'][$v['id']]){
$whereT['id'] = array('in',$approval['content'][$v['id']]);
$fileinfo = File::where($whereT)->field('id,name,file_path')->select();
if($fileinfo){
$approval['content'][$v['id']] = $fileinfo;
}
}
}
}elseif($v['component'] == 'select'){
if(isset($v['config']['multiple']) && $v['config']['multiple'] == true){
if(key_exists($v['id'],$approval['content'])){
if(is_array($approval['content'][$v['id']]) && $approval['content'][$v['id']]){
$approval['content'][$v['id']] = implode(',',$approval['content'][$v['id']]);
}
}
}
}
}
if ($approval['check_status'] == 0 || $approval['check_status'] == 1) {
$approval['is_examine'] = ExamineRecord::isExaminse(ExamineRecord::APPROVAL_TYPE, $id);
} else {
$approval['is_examine'] = 0;
}
$approval['is_operation']=0;
if($approval['create_staff_id'] == $this->auth->id){
//是否可以操作
$approval['is_operation']=1;
}
Message::setRead(Message::APPROVAL_TYPE,$id,$this->auth->id);
$this->success('请求成功',$approval);
}
/**
* 修改审批
*/
public function editApproval(){
$id = input('id');
$params = $this->request->post();
$row = ApprovalModel::where(['id' => $id, 'check_status' => ['in', [3, 4]]])->find();
if (empty($row)) {
$this->error('审批信息不存在');
}
if(empty( $params['data'])){
$this->error('数据不能为空');
}
if(empty( $params['formapproval_id'])){
$this->error('表单id不能为空');
}
if(empty( $params['relation_type'])){
$this->error('关联类型不能为空');
}
Db::startTrans();
try {
$result = ApprovalModel::updateApproval($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('修改信息成功');
}
/**
* 撤回审批
*/
public function cancel(){
$id = input('id');
$customer = ApprovalModel::where(['id' => $id, 'check_status' => ['in', [0, 1]]])->find();
if (empty($customer)) {
$this->error('信息不存在');
}
Db::startTrans();
try {
ApprovalModel::where(['id' => $id])->update(['check_status' => 4]);
ExamineRecord::cancelExaminse(ExamineRecord::APPROVAL_TYPE,$id);
Db::commit();
} catch (Exception $e) {
Db::rollback();;
$this->error($e->getMessage());
}
$this->success('撤回成功');
}
}

1355
addons/qingdong/controller/Attendance.php

File diff suppressed because it is too large

293
addons/qingdong/controller/Autotask.php

@ -0,0 +1,293 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\AdminConfig;
use addons\qingdong\model\AttendanceRule;
use addons\qingdong\model\AttendanceStatisc;
use addons\qingdong\model\AttendanceTime;
use addons\qingdong\model\Message;
use addons\qingdong\model\Customer;
use addons\qingdong\model\Event;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Leads;
use addons\qingdong\model\Attendance;
use think\Db;
use think\Exception;
use think\Log;
/**
* 定时任务
*/
class Autotask extends \think\addons\Controller
{
protected $noNeedLogin = ["*"];
protected $layout = '';
public function _initialize()
{
parent::_initialize();
if (!$this->request->isCli()) {
$this->error('只允许在终端进行操作!');
}
}
/**
* 合同
*/
public function contract()
{
$endDate = date('Y-m-d', strtotime('+3 day'));
$contracts = \addons\qingdong\model\Contract::where(['check_status' => 2, 'contract_status' => 0, 'end_time' => ['lt', $endDate]])->select();
try {
//合同即将到期通知
foreach ($contracts as $v) {
Message::addMessage(Message::CONTRACT_EXPIRE_TYPE, $v['id'], $v['owner_staff_id'], '');
}
} catch (Exception $e) {
return $e->getMessage();
}
$this->plan();
return 'success';
}
/**
* 回款计划通知
*/
public function plan()
{
$endDate = date('Y-m-d', strtotime('+1 day'));
//进行中 -- 待回款
$plans = \addons\qingdong\model\ReceivablesPlan::where(['status' => 0, 'remind_date' => ['lt', $endDate]])->select();
try {
//回款计划即将到期通知
foreach ($plans as $v) {
Message::addMessage(Message::PLAN_EXPIRE_TYPE, $v['contract_id'], $v['owner_staff_id'], '');
}
} catch (Exception $e) {
return $e->getMessage();
}
return 'success';
}
/**
* 公海
*/
public function seas()
{
if (AdminConfig::getConfigValue('auto', AdminConfig::TYPE_SEAS)) {//自动回收客户
if (AdminConfig::getConfigValue('genjing', AdminConfig::TYPE_SEAS) == 1) {//未跟进客户回收
$day = AdminConfig::getConfigValue('genjing_day', AdminConfig::TYPE_SEAS);
$where = ['receivetime' => ['<', strtotime('-' . $day . ' day')]];
if (AdminConfig::getConfigValue('genjing_success', AdminConfig::TYPE_SEAS) == 1) {
$where['contract_status'] = 0;
}
$customers = Customer::where($where)->field('id,name,owner_staff_id')->select();
try {
foreach ($customers as $c) {
Customer::moveSeas($c['id']);
Message::addMessage(Message::SEAS_TYPE, $c['id'], $c['owner_staff_id'], 0);
}
} catch (Exception $e) {
Log::error($e->getMessage());
}
}
if (AdminConfig::getConfigValue('chengjiao', AdminConfig::TYPE_SEAS) == 1) {//未成交客户回收
$day = AdminConfig::getConfigValue('chengjiao_day', AdminConfig::TYPE_SEAS);
$where = [
'receivetime' => ['<', strtotime('-' . $day . ' day')],
'contract_status' => 0
];
$customers = Customer::where($where)->field('id,name,owner_staff_id')->select();
try {
foreach ($customers as $c) {
Customer::moveSeas($c['id']);
Message::addMessage(Message::SEAS_TYPE, $c['id'], $c['owner_staff_id'], 0);
}
} catch (Exception $e) {
Log::error($e->getMessage());
}
}
}
return 'success';
}
/**
* 日程提醒
* @return string
*/
public function event()
{
$endDate = date('Y-m-d H:i:s');
$events = Event::where(['status' => 0, 'remind_time' => ['lt', $endDate]])->select();
$endIds = Event::where([
'status' => ['in', [0, 1]],
'auto_end' => 1,
'end_time' => ['lt', $endDate]
])->column('id');
try {
//日程自动结束
Event::where(['id' => ['in', $endIds]])->update(['status' => 2]);
//日程时间提醒
foreach ($events as $v) {
if (Message::where([
'relation_type' => Message::EVENT_TYPE,
'relation_id' => $v['id'],
'to_staff_id' => $v['staff_id']
])->count()) {
//已经提醒过了
continue;
}
Message::addMessage(Message::EVENT_TYPE, $v['id'], $v['staff_id'], 0);
}
} catch (Exception $e) {
return $e->getMessage();
}
return 'success';
}
/**
* 打卡定时任务
*/
public function attendance()
{
$w = date('w');
$date = [
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
0 => 'weekday',
];
$weekname = $date[$w];
$times = AttendanceTime::where([$weekname => 1])->select();
if (empty($times)) {
return '未设置规则';
}
$row = AttendanceStatisc::where(['time' => date('Y-m-d')])->find();
if (!empty($row)) {
return '规则已生成';
}
$times = collection($times)->toArray();
$rule = AttendanceRule::where([])->find();
$statiscs = AttendanceStatisc::where(['time' => date('Y-m-d', strtotime('-1 day'))])->select();
foreach ($statiscs as $v) {
$update = [];
if (empty($t['clock_in']) && !empty($t['clock_out'])) {//缺卡
$update['clock_in_status'] = 1;
}
if (empty($t['clock_out']) && !empty($t['clock_in'])) {//缺卡
$update['clock_out_status'] = 1;
}
if (empty($t['clock_in']) && empty($t['clock_out'])) {//旷工
$update['clock_in_status'] = 2;
$update['clock_out_status'] = 2;
}
if ($update) {
$statiscModel = new AttendanceStatisc();
$statiscModel->save($update, ['id' => $v['id']]);
}
}
$staff_ids = explode(',', $rule['staff_id']);
$statisc = [];
foreach ($staff_ids as $sid) {
foreach ($times as $t) {
$statisc[] = [
'staff_id' => $sid,
'number' => $t['number'],
'time' => date('Y-m-d'),
'start_time' => $t['start_time'],
'end_time' => $t['end_time'],
'ustart_time' => $t['ustart_time'],
'uend_time' => $t['uend_time'],
'dstart_time' => $t['dstart_time'],
'dend_time' => $t['dend_time'],
'start_status' => $t['start_status'],
'end_status' => $t['end_status'],
];
}
}
$statiscModel = new AttendanceStatisc();
$result = $statiscModel->allowField(true)->saveAll($statisc);
if (empty($result)) {
return '生成规则失败';
}
return '生成规则成功';
}
/*
* 线索池分配
*/
public function leadpool(){
if(AdminConfig::getConfigValue('leadauto', AdminConfig::TYPE_LEAD)){
$leadauto = AdminConfig::getConfigValue('leadauto', AdminConfig::TYPE_LEAD);
$lead_day = AdminConfig::getConfigValue('lead_day', AdminConfig::TYPE_LEAD);
$attendance = AdminConfig::getConfigValue('leadcard', AdminConfig::TYPE_LEAD);
$department = AdminConfig::getConfigValue('department', AdminConfig::TYPE_LEAD);
//开启分配
if($leadauto == 1 && $lead_day>0 && $department){
$leadpool = Leads::where('owner_staff_id is null or owner_staff_id = 0')->order('id desc')->limit(100)->column('id');
if($leadpool){
$department = explode(',',$department);
$staffinfo = array();
foreach($department as $k=>$v){
$staffids = Staff::where('', 'exp', Db::raw('FIND_IN_SET(' . $v . ',group_ids)'))->where(['status'=>1])->column('id');
$staffinfo[] = $staffids;
}
if(!$staffinfo){
return '无数据';
}
$staffinfos =[];
foreach($staffinfo as $k=>$v){
foreach($v as $ks=>$vs){
$staffinfos[] = $vs;
}
}
$staff = array_unique($staffinfos);
foreach($leadpool as $ks=>$vs){
$stafflead =[];
foreach($staff as $k=>$v){
if($attendance == 1){ //打卡
$whereC['staff_id']= $v;
$whereC['createtime'] = array(array('egt',strtotime(date('Y-m-d 00:00:00'))),array('elt',strtotime(date('Y-m-d 23:59:59'))));
$leadcard = Attendance::where($whereC)->find();
if(!$leadcard){//未打卡不分配
continue;
}
}
$wherelead['owner_staff_id'] = $v;
$wherelead['receive_time'] = array(array('egt',strtotime('-'.$lead_day.' days',time())),array('elt',time()));
$lead = Leads::where($wherelead)->count();
$stafflead[] = array(
'id'=>$v,
'num'=>$lead
);
}
if($stafflead){
$num_count = array_column($stafflead,'num');//返回数组中指定的一列
array_multisort($num_count,SORT_ASC,$stafflead);
Leads::where(array('id'=>$vs))->update(array('owner_staff_id'=>$stafflead[0]['id'],'receive_time'=>time()));
}
}
}
}
}
return 'success';
}
}

298
addons/qingdong/controller/Business.php

@ -0,0 +1,298 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Business as BusinessModel;
use addons\qingdong\model\BusinessOther;
use addons\qingdong\model\FormField;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Message;
use addons\qingdong\model\Contract;
use addons\qingdong\model\BusinessStatus;
use addons\qingdong\model\File;
use think\Db;
use think\Exception;
/**
* 商机接口
*/
class Business extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = [];
//创建商机
public function addBusiness()
{
$params = $this->request->post();
$result = FormField::checkFields(FormField::BUSINESS_TYPE, $params);
if ($result !== true) {
$this->error($result);
}
Db::startTrans();
try {
$result = BusinessModel::createBusiness($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('添加商机成功');
}
}
//获取商机列表
public function getList()
{
$limit = input("limit/d", 10);
$customer_id = input('customer_id');
$params = $this->request->post();
$where= FormField::updateWhereField(FormField::BUSINESS_TYPE,$params);
if (isset($params['createtime']) && $params['createtime']) {//
$createtime = $params['createtime'];
$createtime = explode(',', $createtime);
$where['createtime'] = ['between', [strtotime($createtime[0]), strtotime($createtime[1]) + 86400 - 1]];
}
if (isset($params['staff_id']) && $params['staff_id']) {//下级员工筛选
$where['owner_staff_id'] = $params['staff_id'];
} else {
$where['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
if (isset($params['type']) && $params['type']) {//客户分类
if ($params['type'] == 1) {//我的创建
$where['owner_staff_id'] = $this->auth->id;
} elseif ($params['type'] == 2) {//下属创建
$where['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
}
}
}
$wheres =[];
if (isset($params['contract_status']) && $params['contract_status']) {
if($params['contract_status'] == 1){
$wheres['contract_status'] = 0;
}
if($params['contract_status'] == 2){
$wheres['contract_status'] = 1;
}
}
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
$records = BusinessModel::where($where)->where($wheres)->with([
'customer',
'ownerStaff',
])->order('id desc')->paginate($limit)->toArray();
$data=[];
foreach($records['data'] as $k=>$v){
$types = BusinessStatus::where(array('business_id'=>$v['id']))->order('id desc')->value('type');
if($types){
$v['type'] = (int)$types;
}else{
$v['type'] = 0;
}
$data[$k] = $v;
}
$allMoney = BusinessModel::where($where)->where($wheres)->sum('money');
$moneyinfo['repayment_money'] = BusinessModel::where($where)->where(array('contract_status'=>1))->sum('money'); //成交金额
$moneyinfo['no_money'] = sprintf("%.2f",$allMoney)-sprintf("%.2f",$moneyinfo['repayment_money']);//未成交金额
$moneyinfo['allmoney'] = $allMoney;//合同总金额
$this->success('请求成功', ['moneyinfo' => $moneyinfo, 'total' => $records['total'], 'per_page' => $records['per_page'], 'current_page' => $records['current_page'], 'last_page' => $records['last_page'], 'data' => $data]);
}
//获取商机详情
public function getDetail()
{
$id = input('id');
$contract = BusinessModel::where(['id' => $id])->with([
'customer',
'ownerStaff',
'product',
])->find();
if (empty($contract)) {
$this->error('商机不存在');
}
$contract = $contract->toArray();
$contract = BusinessOther::getOther($contract);
$type = BusinessStatus::where(array('business_id'=>$contract['id']))->order('id desc')->value('type');
$contract['type'] = $type ? (int)$type : 0;
//产品删除不显示
if(isset($contract['product']) && $contract['product']){
foreach($contract['product'] as $k=>$v){
if(!$v['name'] && !$v['num']){
unset($contract['product'][$k]);
}
}
}
//标记通知已读
Message::setRead(Message::BUSINESS_TYPE, $id, $this->auth->id);
$this->success('请求成功', $contract);
}
//修改商机
public function editBusiness()
{
$id = input('id');
$params = $this->request->post();
$row = BusinessModel::where(['id' => $id])->find();
if (empty($row)) {
$this->error('商机信息不存在');
}
$result = FormField::checkFields(FormField::BUSINESS_TYPE, $params,$id);
if ($result !== true) {
$this->error($result);
}
Db::startTrans();
try {
$result = BusinessModel::updateBusiness($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('修改商机成功');
}
/**
* 转移商机
*/
public function batch_change()
{
$ids = input('id');
$staff_id = input('owner_staff_id');
if(!$ids || !$staff_id){
$this->error('参数不正确');
}
$ids = BusinessModel::where([
'id' => $ids
])->column('id');
if (empty($ids)) {
$this->error('商机不存在');
}
$result = BusinessModel::batchTransfer($ids, $staff_id);
if(!$result){
$this->error('操作失败');
}
$this->success('操作成功');
}
//删除商机
public function delete()
{
$ids = input('id');
if(!$ids){
$this->error('参数不正确');
}
$data = BusinessModel::where([
'id' => $ids
])->column('id');
if (empty($data)) {
$this->error('商机不存在');
}
$result = BusinessModel::where(array('id'=>$ids))->update(array('updatetime'=>time(),'deletetime'=>time()));
if(!$result){
$this->error('删除失败');
}
$this->success('删除成功');
}
//关联商机列表
public function business_list(){
$ids = input('customer_id');
if(!$ids){
$this->error('参数不正确');
}
$data= BusinessModel::where(['customer_id'=>$ids,'owner_staff_id'=>['in',Staff::getMyStaffIds()]])->field('id,name')->select();
$this->success('请求成功',$data);
}
//商机合同
public function contract(){
$limit = input("limit/d", 10);
$ids = input('id');
if(!$ids){
$this->error('参数不正确');
}
$contract = Contract::where(array('business_id'=>$ids))->with([
'customer',
'contacts',
'ownerStaff',
'orderStaff',
'receivables'
])->order('id desc')->paginate($limit)->toArray();
$data = isset($contract['data'])?$contract['data']:[];
if($data){
foreach ($data as $k => $v) {
if (empty($v['receivables'])) {
$v['receivables'] = [
'repayment_money' => 0,
'be_money' => $v['money'],
'ratio' => 0
];
} else {
$be_money = $v['money'] - $v['receivables']['repayment_money'];
$be_money = ($be_money > 0) ? $be_money : 0;
$v['receivables'] = [
'repayment_money' => $v['receivables']['repayment_money'],
'be_money' =>$be_money,
'ratio' => round($v['receivables']['repayment_money'] / $v['money'] * 100, 2)
];
}
$data[$k] = $v;
}
}
$this->success('请求成功', ['total' => $contract['total'], 'per_page' => $contract['per_page'], 'current_page' => $contract['current_page'], 'last_page' => $contract['last_page'], 'data' => $data]);
}
//商机状态
public function business_status(){
$id = input('id');
$type = input('type',0);
$remark = input('remark');
$file = input('file');
if(!$id){
$this->error('参数不正确');
}
$data = array(
'id'=>$id,
'type'=>$type,
'remark'=>$remark,
'file'=>$file,
);
$business =BusinessModel::batchStatus($data);
if(!$business){
$this->error('操作失败');
}
$this->success('操作成功');
}
//商机历史
public function business_history(){
$id = input('id');
if(!$id){
$this->error('参数不正确');
}
$business = BusinessStatus::where(array('business_id'=>$id))->order('id desc')->select();
foreach($business as $k=>$v){
$business[$k]['createtime'] = date('Y-m-d H:i:s',$v['createtime']);
if($v['file']){
$business[$k]['file'] = File::where(array('id'=>['in',$v['file']]))->field('id,types,name,save_name,size,file_path')->select();
}
}
$this->success('请求成功',$business);
}
//查询商机列表
public function get_select_list(){
$limit = input("limit/d", 10);
$params = $this->request->post();
$where = [];
if(isset($params['name']) && $params['name']){
$where['name'] = array('like','%'.$params['name'].'%');
}
$data= BusinessModel::where(['owner_staff_id'=>['in',Staff::getMyStaffIds()]])->where($where)->field('id,name')->order('id desc')->paginate($limit)->toArray();;
$this->success('请求成功',$data);
}
}

172
addons/qingdong/controller/Common.php

@ -0,0 +1,172 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\AdminConfig;
use addons\qingdong\model\FormField;
use app\common\library\Upload;
use app\common\exception\UploadException;
use app\common\model\Area;
use addons\qingdong\model\Field;
use addons\qingdong\model\Form;
use app\common\model\Version;
use think\Config;
use think\Hook;
/**
* * 操作文档:https://doc.fastadmin.net/qingdong
* 软件介绍:https://www.fastadmin.net/store/qingdong.html
* 售后微信:qingdong_crm
* 公共接口
*/
class Common extends StaffApi {
protected $noNeedLogin = ['init','getConfig'];
protected $noNeedRight = '*';
/**
* 加载初始化
* @param string $version 版本号
* @param string $lng 经度
* @param string $lat 纬度
*/
public function init() {
if ($version = $this->request->request('version')) {
$lng = $this->request->request('lng');
$lat = $this->request->request('lat');
//配置信息
$upload = Config::get('upload');
//如果非服务端中转模式需要修改为中转
if ($upload['storage'] != 'local' && isset($upload['uploadmode']) && $upload['uploadmode'] != 'server') {
//临时修改上传模式为服务端中转
set_addon_config($upload['storage'], ["uploadmode" => "server"], false);
$upload = \app\common\model\Config::upload();
// 上传信息配置后
Hook::listen("upload_config_init", $upload);
$upload = Config::set('upload', array_merge(Config::get('upload'), $upload));
}
$upload['cdnurl'] = $upload['cdnurl'] ? $upload['cdnurl'] : cdnurl('', true);
$upload['uploadurl'] = preg_match("/^((?:[a-z]+:)?\/\/)(.*)/i", $upload['uploadurl']) ? $upload['uploadurl'] : url($upload['storage'] == 'local' ? '/api/common/upload' : $upload['uploadurl'], '', false, true);
$content = [
'citydata' => Area::getCityFromLngLat($lng, $lat),
'versiondata' => Version::check($version),
'uploaddata' => $upload,
'coverdata' => Config::get("cover"),
];
$this->success('', $content);
} else {
$this->error(__('Invalid parameters'));
}
}
/**
* 上传文件
* @ApiMethod (POST)
* @param File $file 文件流
*/
public function upload() {
$attachment = null;
//默认普通上传文件
$file = $this->request->file('file');
$name = input('name','');
try {
$upload = new Upload($file);
$attachment = $upload->upload();
$info = $attachment->toArray();
$file = new \addons\qingdong\model\File();
$params = [
'name' => $name ? $name :$info['filename'],
'save_name' => $info['url'],
'size' => isset($info['filesize']) ? $info['filesize'] : 0,
'types' => $info['mimetype'],
'file_path' => $info['url'],
'create_staff_id' => empty($staff)?0:$staff->id,
];
$file->data(array_filter($params));
$file->save();
$fileId = $file->id;
} catch (UploadException $e) {
return json_encode(['code' => 0, 'msg' => $e->getMessage()]);
}
$this->success(__('Uploaded successful'), [
'id' => $fileId,
'flie_url' => $params['file_path'],
'url' => cdnurl($params['file_path'], true)
]);
}
//select 字段表
public function selectOption() {
$fields = Field::where([])->select();
$data = [];
foreach ($fields as $v) {
$data[$v['name']] = json_decode($v['data'],true);
}
$this->success('请求成功', $data);
}
//获取form表单
public function getForm() {
$type = input('type', 'leads');//leads 线索 customer 客户 contacts 联系人 contract 合同 examine回款 product产品
$form = Form::where(['type' => $type])->find();
$this->success('请求成功', json_decode($form['data'], true));
}
//获取员工
public function getSelectStaff() {
$name = input('name');
$where = ['status' => 1];
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
$staffs = \addons\qingdong\model\Staff::where($where)->with(['department'])->field('id,name,department_id,nickname,post,img')->select();
$this->success('请求成功', $staffs);
}
/**
* 获取后台配置
*/
public function getConfig(){
$config=get_addon_config('qingdong');
$data=[
'map_key'=>AdminConfig::getConfigValue('map_key','wechat'),
'appid'=>AdminConfig::getConfigValue('appid','wechat'),
'mobile_name'=>$config['mobile_name']??'CRM'
];
$this->success('请求成功',$data);
}
/**
* 获取时间
*/
public function getTimes()
{
$times = input('times');
$times = setTimes($times, 'date');
$this->success('请求成功', ['times' => $times]);
}
/**
* 获取搜索字段
*/
public function getSearchFields(){
$type=input('type');//leads
$fields=FormField::where(['types'=>$type,'field'=>['like',"main_%"],'list_show'=>1,'info_type'=>'main'])->select();
$this->success('请求成功',$fields);
}
}

142
addons/qingdong/controller/Consume.php

@ -0,0 +1,142 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\ExamineRecord;
use addons\qingdong\model\Consume as ConsumeModel;
use addons\qingdong\model\Message;
use addons\qingdong\model\File;
use addons\qingdong\model\Staff;
use think\Db;
use think\Exception;
/**
* 费用接口
*/
class Consume extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = [];
//添加费用
public function addConsume()
{
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
Db::startTrans();
try {
$result = ConsumeModel::createConsume($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('添加费用成功');
}
}
//编辑费用
public function editConsume()
{
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
Db::startTrans();
try {
$result = ConsumeModel::updateConsume($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('添加费用成功');
}
}
//获取费用列表
public function getList()
{
$limit = input("limit/d", 10);
$customer_id = input('customer_id', '', 'intval');
$times = input('times', '');
$status = input('check_status',0);
$where = [];
$params = $this->request->post();
if ($times) {//
$times = explode(',', $times);
$where['createtime'] = ['between', [strtotime($times[0]), strtotime($times[1]) + 86400 - 1]];
}
if (isset($params['staff_id']) && $params['staff_id']) {//下级员工筛选
$where['staff_id'] = $params['staff_id'];
} else {
$where['staff_id'] = ['in', Staff::getMyStaffIds()];
if (isset($params['type']) && $params['type']) {//客户分类
if ($params['type'] == 1) {//我的客户
$where['staff_id'] = $this->auth->id;
} elseif ($params['type'] == 2) {//下属负责的客户
$where['staff_id'] = ['in', Staff::getLowerStaffId()];
}
}
}
if ($status) {
if($status == 1){//待审核
$where['check_status']=['in',[0,1]];
}elseif($status == 2){//通过
$where['check_status']=2;
}elseif($status == 3){//审核拒绝
$where['contract_status']=['in',[3,4]];
}
}
if($customer_id){
$where['customer_id'] = $customer_id;
}
$records = ConsumeModel::where($where)->with(['staff','customer'])->order('id desc')->paginate($limit)->toArray();
$remoney = ConsumeModel::where(['staff_id'=>$where['staff_id']])
->where(array('check_status'=>2))->sum('money');
$inmoney = ConsumeModel::where(['staff_id'=>$where['staff_id']])
->where(array('check_status'=>['in',[0,1]]))->sum('money');
$nomoney = ConsumeModel::where(['staff_id'=>$where['staff_id']])
->where(array('check_status'=>['in',[3,4]]))->sum('money');
$moneyinfo['remoney'] = $remoney;//已回款
$moneyinfo['inmoney'] = $inmoney;//回款中
$moneyinfo['nomoney'] = $nomoney;//未回款
$moneyinfo['allmoney'] = $remoney+$inmoney+$nomoney;//总金额
$records['moneyinfo']=$moneyinfo;
$this->success('请求成功', $records);
}
//获取费用详情
public function getDetail()
{
$id = input('id', '', 'intval');
$consume = ConsumeModel::where(['id' => $id])->with(['staff','customer'])->find();
if(empty($consume)){
$this->error('数据不存在');
}
$consume['files'] = File::where(['id' => ['in', explode(',', $consume['file_ids'])]])->field('id,types,name,file_path')->select();
if ($consume['check_status'] == 0 || $consume['check_status'] == 1) {
$consume['is_examine'] = ExamineRecord::isExaminse(ExamineRecord::CONSUME_TYPE, $id);
} else {
$consume['is_examine'] = 0;
}
//标记通知已读
Message::setRead(Message::CONSUME_TYPE, $id, $this->auth->id);
$this->success('请求成功', $consume);
}
}

200
addons/qingdong/controller/Contacts.php

@ -0,0 +1,200 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Contacts as ContactsModel;
use addons\qingdong\model\ContactsFile;
use addons\qingdong\model\ContactsOther;
use addons\qingdong\model\FormField;
use addons\qingdong\model\Record;
use addons\qingdong\model\Event as EventModel;
use addons\qingdong\model\OperationLog;
use addons\qingdong\model\Staff;
use think\Db;
use think\Exception;
/**
* 联系人接口
*/
class Contacts extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//创建联系人
public function addContacts() {
$params = $this->request->post();
if (empty($params['contacts'])) {
$this->error('联系人信息不能为空');
}
// 表单验证
if (($result = $this->qingdongValidate($params['contacts'], get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::CONTACTS_TYPE,$params['contacts']);
if ($result !== true) {
$this->error($result);
}
if (ContactsModel::where([
'mobile' => $params['contacts']['mobile'],
'customer_id' => $params['contacts']['customer_id']
])->find()) {
$this->error('联系人手机号已存在');
}
Db::startTrans();
try {
$mobile =$params['contacts']['mobile'];
$email =$params['contacts']['email']??'';
if(empty($mobile) && empty($email)){
$this->error('手机号码和邮箱至少填写一项!');
}
$rule = '^1(3|4|5|7|8)[0-9]\d{8}$^';
$rule2 = '^[0-9]+$^';
if (preg_match($rule, $mobile) == false && preg_match($rule2, $mobile) ==false) {
$this->error('手机号格式错误,国外手机号请填写区号,例如 86XXXX');
}
$contactsId = ContactsModel::createContacts($params['contacts']);
if (isset($params['is_event']) && $params['is_event'] == 1) {//跟进任务
$event = $params['event'];
$event['type'] = 2;//任务
$event['relation_type'] = EventModel::CONTACTS_TYPE;//联系人
$event['relation_id'] = $contactsId;
$event['end_time'] = $event['start_time'];
$event['level'] = 1;
$result = EventModel::createEvent($event);
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('创建联系人成功');
}
}
//编辑联系人
public function editContacts() {
$id = input('id');
$params = $this->request->post();
$row = ContactsModel::where(['id' => $id])->find();
if (empty($row)) {
$this->error('客户信息不存在');
}
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'edit')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::CONTACTS_TYPE,$params,$id);
if ($result !== true) {
$this->error($result);
}
if (ContactsModel::where([
'mobile' => $params['mobile'],
'customer_id' => $row['customer_id'],
'id' => ['neq', $params['id']]
])->find()) {
$this->error('联系人手机号已存在');
}
Db::startTrans();
try {
$result = ContactsModel::updateContacts($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('编辑联系人成功');
}
//删除联系人
public function delContacts() {
$id = input('id');
$row = ContactsModel::where(['id' => $id, 'owner_staff_id' => $this->auth->id])->find();
if (empty($row)) {
$this->error('您不是客户归属人,无法删除当前联系人');
}
$model = new ContactsModel();
if ($model->destroy(['id' => $id])) {
$this->success('删除成功');
}
Record::quickCreateRecord(Record::CUSTOMER_TYPE, $row['customer_id'],
'删除联系人:' . $row['name']);
OperationLog::createLog(OperationLog::CUSTOMER_TYPE, $row['customer_id'], '删除联系人:' . $row['name']);
$this->error('删除失败');
}
//获取联系人列表
public function getList() {
$limit = input("limit/d", 10);
$customer_id = input('customer_id');
$name = input('name');
$params = input();
$where = FormField::updateWhereField(FormField::CONTACTS_TYPE, $params);
if ($customer_id) {
$where['customer_id'] = $customer_id;
}else{
$where['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
}
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
$records = ContactsModel::where($where)->with(['customer'])->order('id desc')->paginate($limit);
$this->success('请求成功', $records);
}
//获取select联系人列表
public function getSelectList() {
$customer_id = input('customer_id');
$name = input('name','');
$where = [];
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
if ($name) {
$where['name'] = ['like',"%$name%"];
}
$list = ContactsModel::where($where)->with(['customer'])->field('id,customer_id,name,mobile')->select();
$list = collection($list)->toArray();
foreach ($list as $k => $v) {
$v['new_mobile'] = $v['mobile'];
$list[$k] = $v;
}
$this->success('请求成功', $list);
}
//获取联系人详情
public function getDetail() {
$id = input('id');
$contract = ContactsModel::where(['id' => $id])->with([
'customer',
'ownerStaff'
])->find();
if (empty($contract)) {
$this->error('信息不存在');
}
$contract = $contract->toArray();
$contract=ContactsOther::getOther($contract);
$this->success('请求成功', $contract);
}
//获取附件列表
public function getFilesList() {
$id = input('contacts_id');
$files = ContactsFile::where(['contacts_id' => $id])->field('file_id')->with(['file'])->select();
$this->success('请求成功', $files);
}
}

362
addons/qingdong/controller/Contract.php

@ -0,0 +1,362 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Contract as ContractModel;
use addons\qingdong\model\ContractFile;
use addons\qingdong\model\ContractOther;
use addons\qingdong\model\ExamineRecord;
use addons\qingdong\model\FormField;
use addons\qingdong\model\Ratio;
use addons\qingdong\model\Receivables;
use addons\qingdong\model\Message;
use addons\qingdong\model\Staff;
use think\Db;
use think\Exception;
/**
* 合同接口
*/
class Contract extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = [];
//创建合同
public function addContract()
{
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::CONTRACT_TYPE, $params);
if ($result !== true) {
$this->error($result);
}
if (isset($params['num'])) {
if (empty($params['num'])) {
$params['num'] = ContractModel::getNum();
}
$contract = ContractModel::where(['num' => $params['num']])->find();
if ($contract) {
$this->error('合同编号已存在');
}
} else {
$params['num'] = ContractModel::getNum();
}
Db::startTrans();
try {
$result = ContractModel::createContract($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('添加合同成功');
}
}
//获取select合同列表
public function getSelectList()
{
$customer_id = input('customer_id');
$name = input('name','');
$where = [];
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
if ($name) {
$where['name'] = ["like","%$name%"];
}
$records = ContractModel::where($where)->where(['check_status'=>2])->with(['ownerStaff'])->field('id,name,num,order_date,money')->order('id desc')->select();
$this->success('请求成功', $records);
}
//获取合同列表
public function getList()
{
$limit = input("limit/d", 10);
$customer_id = input('customer_id');
$contacts_id = input('contacts_id');
$status = input('status',0);
$params = $this->request->post();
$whereT =[];
$where= FormField::updateWhereField(FormField::CONTRACT_TYPE,$params);
if (isset($params['createtime']) && $params['createtime']) {//跟进状态
$createtime = $params['createtime'];
$createtime = explode(',', $createtime);
$where['order_date'] = ['between', [date('Y-m-d 00:00:00',strtotime($createtime[0])), date('Y-m-d 23:59:59',strtotime($createtime[1]) + 86400 - 1)]];
}
if (isset($params['staff_id']) && $params['staff_id']) {//下级员工筛选
$where['owner_staff_id'] = $params['staff_id'];
} else {
$where['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
if (isset($params['type']) && $params['type']) {//客户分类
if ($params['type'] == 1) {//我的客户
$where['owner_staff_id'] = $this->auth->id;
} elseif ($params['type'] == 2) {//下属负责的客户
$where['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
}
}
}
if ($status) {
if($status == 1){//待审核
$where['check_status']=['in',[0,1]];
}elseif($status == 2){//待回款
$where['check_status']=2;
$where['contract_status']=0;
}elseif($status == 3){//已回款
$where['check_status']=2;
$where['contract_status']=1;
}
}
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
if ($contacts_id) {
$where['contacts_id'] = $contacts_id;
}
$records = ContractModel::where($where)->with([
'customer',
'contacts',
'ownerStaff',
'orderStaff',
'receivables'
])->order('id desc')->paginate($limit)->toArray();
$data = $records['data'];
foreach ($data as $k => $v) {
if (empty($v['receivables'])) {
$v['receivables'] = [
'repayment_money' => 0,
'be_money' => $v['money'],
'ratio' => 0
];
} else {
$be_money = $v['money'] - $v['receivables']['repayment_money'];
$be_money = ($be_money > 0) ? $be_money : 0;
$ratio_m = 0;
if($v['money'] >0){
$ratio_m = round($v['receivables']['repayment_money'] / $v['money'] * 100, 2);
}
$v['receivables'] = [
'repayment_money' => $v['receivables']['repayment_money'],
'be_money' =>$be_money,
'ratio' => $ratio_m
];
}
$data[$k] = $v;
}
$whereT['owner_staff_id']=$where['owner_staff_id'];
$noMoney = ContractModel::where($whereT)->where(array('check_status'=>2))->sum('money');
$moneyinfo['repayment_money'] = Receivables::where($whereT)->where(array('check_status'=>2))->sum('money'); //已回款
$moneyinfo['be_money'] = sprintf("%.2f",$noMoney)-sprintf("%.2f",$moneyinfo['repayment_money']);//未回款
$moneyinfo['allmoney'] = $noMoney;//合同总金额
$this->success('请求成功', ['moneyinfo' => $moneyinfo, 'total' => $records['total'], 'per_page' => $records['per_page'], 'current_page' => $records['current_page'], 'last_page' => $records['last_page'], 'data' => $data]);
}
//获取客户相关合同列表
public function getCustomerContacts()
{
$customer_id = input('customer_id');
$contacts_id = input('contacts_id');
$where = [];
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
if ($contacts_id) {
$where['contacts_id'] = $contacts_id;
}
$records = ContractModel::where($where)->with(['receivables'])->field('id,name,money,num,check_status,order_date')->order('id desc')->select();
$records = collection($records)->toArray();
foreach ($records as $k => $v) {
if (empty($v['receivables'])) {
$v['receivables'] = [
'repayment_money' => 0,
'be_money' => $v['money'],
'ratio' => 0
];
} else {
$be_money = $v['money'] - $v['receivables']['repayment_money'];
$v['receivables'] = [
'repayment_money' => $v['receivables']['repayment_money'],
'be_money' => ($be_money > 0) ? $be_money : 0,
'ratio' => round($v['receivables']['repayment_money'] / $v['money'] * 100, 2)
];
}
$records[$k] = $v;
}
$this->success('请求成功', $records);
}
//获取合同详情
public function getDetail()
{
$id = input('id');
$contract = ContractModel::where(['id' => $id])->with([
'customer',
'contacts',
'ownerStaff',
'orderStaff',
'product',
'receivables',
'business'
])->find();
if (empty($contract)) {
//标记通知已读
Message::setRead(Message::CONTRACT_TYPE, $id);
$this->error('合同不存在');
}
$contract = $contract->toArray();
$contract = ContractOther::getOther($contract);
$receivablesMoney = Receivables::where(['contract_id' => $contract['id'], 'check_status' => 2])->sum('money');
//回款金额
$contract['receivables_money'] = $receivablesMoney;
$contract['ratios'] = json_decode($contract['ratios'],true);
if($contract['ratios']){
foreach ($contract['ratios'] as $k => $v) {
$v['staff'] = Staff::where(['id' => $v['staff_id']])->field('id,name,img,post')->find()->toArray();
$v['money'] = $contract['money'] * ($v['ratio'] / 100);
$contract['ratios'][$k] = $v;
}
}
if (empty($contract['receivables'])) {
$contract['receivables'] = [
'repayment_money' => 0,
'be_money' => $contract['money'],
'ratio' => 0
];
} else {
$be_money = $contract['money'] - $contract['receivables']['repayment_money'];
$be_ratio = 0;
if($contract['money'] > 0){
$be_ratio =round($contract['receivables']['repayment_money'] / $contract['money'] * 100, 2);
}
$contract['receivables'] = [
'repayment_money' => $contract['receivables']['repayment_money'],
'be_money' => ($be_money > 0) ? $be_money : 0,
'ratio' => $be_ratio
];
}
//产品删除不显示
if(isset($contract['product']) && $contract['product']){
foreach($contract['product'] as $k=>$v){
if(!$v['name'] && !$v['num']){
unset($contract['product'][$k]);
}
}
}
//标记通知已读
Message::setRead(Message::CONTRACT_TYPE, $id, $this->auth->id);
$this->success('请求成功', $contract);
}
//获取附件列表
public function getFilesList()
{
$id = input('contract_id');
$files = ContractFile::where(['contract_id' => $id])->field('file_id')->with(['file'])->select();
$this->success('请求成功', $files);
}
//撤回审核
public function cancel()
{
$id = input('id');
$customer = ContractModel::where(['id' => $id, 'check_status' => ['in', [0, 1]]])->find();
if (empty($customer)) {
$this->error('合同信息不存在');
}
$record = ExamineRecord::where([
'relation_type' => ExamineRecord::CONTRACT_TYPE,
'relation_id' => $id,
'status' => 0
])->find();
Db::startTrans();
try {
if ($message = Message::where(['relation_type' => 'examine', 'relation_id' => $record['id'], 'from_staff_id' => $this->auth->id])->find()) {
Message::where(['id' => $message['id']])->update(['status' => 1, 'read_time' => time()]);
}
ContractModel::where(['id' => $id])->update(['check_status' => 4]);
ExamineRecord::where([
'relation_type' => ExamineRecord::CONTRACT_TYPE,
'relation_id' => $id,
'status' => 0
])->update(['status' => 3]);
Db::commit();
} catch (Exception $e) {
Db::rollback();;
$this->error($e->getMessage());
}
$this->success('撤回成功');
}
//修改合同
public function editContract()
{
$id = input('id');
$params = $this->request->post();
$row = ContractModel::where(['id' => $id, 'check_status' => ['in', [3, 4]]])->find();
if (empty($row)) {
$this->error('合同信息不存在');
}
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::CONTRACT_TYPE, $params,$id);
if ($result !== true) {
$this->error($result);
}
Db::startTrans();
try {
$params['owner_staff_id'] = $row['owner_staff_id'];
$result = ContractModel::updateContract($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('修改合同信息成功');
}
//获取合同编号
public function getContractNumber()
{
$this->success('请求成功', ['number' => ContractModel::getNum()]);
}
/**
* 获取业绩分割比例
*/
public function getRatio()
{
$ratios = Ratio::where(['status' => 1])->field('name,ratio')->select();
$ratios = collection($ratios)->toArray();
foreach ($ratios as $k => $v) {
$v['ratio'] = json_decode($v['ratio'], true);
$ratios[$k] = $v;
}
$this->success('请求成功', $ratios);
}
}

564
addons/qingdong/controller/Customer.php

@ -0,0 +1,564 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Contacts;
use addons\qingdong\model\Customer as CustomerModel;
use addons\qingdong\model\CustomerFile;
use addons\qingdong\model\CustomerOther;
use addons\qingdong\model\Business;
use addons\qingdong\model\Contract;
use addons\qingdong\model\FormField;
use addons\qingdong\model\StaffSignIn;
use addons\qingdong\model\Consume;
use addons\qingdong\model\Receivables;
use addons\qingdong\model\OperationLog;
use addons\qingdong\model\Form;
use addons\qingdong\model\Record;
use addons\qingdong\model\Record as RecordModel;
use addons\qingdong\model\Staff;
use addons\qingdong\model\StaffCollect;
use addons\qingdong\model\Message;
use think\Db;
use think\Exception;
use function EasyWeChat\Kernel\Support\get_client_ip;
/**
* 操作文档:https://doc.fastadmin.net/qingdong
* 软件介绍:https://www.fastadmin.net/store/qingdong.html
* 售后微信:qingdong_crm
* 客户接口
*/
class Customer extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = [];
//获取select客户列表
public function getSelectList()
{
$name = input('name');
$where = [];
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
$staff_id=$this->auth->id;
$list = CustomerModel::where($where)->where(function ($query) use ($staff_id) {
$query->where('ro_staff_id', 'like', "%,{$staff_id},%")
->whereOr('rw_staff_id', 'like', "%,{$staff_id},%")
->whereOr('owner_staff_id', 'in', Staff::getMyStaffIds());
})->with(['ownerStaff'])->field('id,name,owner_staff_id,follow')->select();
$this->success('请求成功', $list);
}
//获取客户列表
public function getList()
{
$limit = input("limit/d", 10);
$params = $this->request->post();
$where= FormField::updateWhereField(FormField::CUSTOMER_TYPE,$params);
$whereStaff = [];
if (isset($params['name']) && $params['name']) {//客户名称
if(is_numeric($params['name'])){
$whereContact['mobile'] = ['like', "%".$params['name']."%"];
$customer_id= Contacts::where($whereContact)->column('customer_id');
$where['id'] = array('in',$customer_id);
}else{
$where['name|subname'] = ['like', "%{$params['name']}%"];
}
}
if (isset($params['level']) && $params['level']) {//客户星级
$where['level'] = $params['level'];
}
if (isset($params['source']) && $params['source']) {//客户来源
$where['source'] = $params['source'];
}
if (isset($params['follow']) && $params['follow']) {//跟进状态
$where['follow'] = $params['follow'];
}
if (isset($params['group_id']) && $params['group_id']) {//角色组
$ids = Staff::getGroupStaffIds($params['group_id']);
$where['id'] = ['in', $ids];
}
if (isset($params['createtime']) && $params['createtime']) {//
$createtime = $params['createtime'];
$createtime = explode(',', $createtime);
$where['createtime'] = ['between', [strtotime($createtime[0]), strtotime($createtime[1]) + 86400 - 1]];
}
$order = 'id desc';
if (isset($params['sort']) && $params['sort']) {
switch ($params['sort']) {
case 1://名称正序
$order = 'name asc';
break;
case 2://名称倒序
$order = 'name desc';
break;
case 3://创建时间正序
$order = 'createtime asc';
break;
case 4://创建时间倒序
$order = 'createtime desc';
break;
case 5://下次跟进时间正序
$order = 'next_time asc';
break;
case 6://下次跟进时间倒序
$order = 'next_time desc';
break;
}
}
if (isset($params['next_time']) && $params['next_time']) {//下次联系时间
$next_time = $params['next_time'];
$next_time = explode(',', $next_time);
$where['next_time'] = ['between', [$next_time[0], $next_time[1]]];
}
if (isset($params['staff_id']) && $params['staff_id']) {//下级员工筛选
$where['owner_staff_id'] = $params['staff_id'];
} else {
$staff_id = $this->auth->id;
$type = $params['type'] ?? 0;
if ($type == 1) {//我的客户
$whereStaff['owner_staff_id'] = $this->auth->id;
} elseif ($type == 2) {//下属负责的客户
$whereStaff['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
} elseif ($type == 3) {//我参与的客户
$whereStaff = function ($query) use ($staff_id) {
$query->where('ro_staff_id', 'like', "%,{$staff_id},%")
->whereOr('rw_staff_id', 'like', "%,{$staff_id},%");
};
}else{
$whereStaff = function ($query) use ($staff_id) {
$query->where(['ro_staff_id' => ['like', "%,{$staff_id},%"]])
->whereOr('rw_staff_id', 'like', "%,{$staff_id},%")
->whereOr(['owner_staff_id' => ['in', Staff::getMyStaffIds()]]);
};
}
}
$whereSeas = ['owner_staff_id' => ['neq', 0]];
if (isset($params['is_seas']) && $params['is_seas'] == 1) {//公海
//公海权限
$whereSeas=[];
$where['owner_staff_id'] = 0;
//公海权限
$rules=Staff::getStaffRule('seas');
$whereStaff = function ($query) use ($rules) {
foreach ($rules as $rule) {
$query->whereOr(['seas_id' => ['like', "%,{$rule},%"]]);
}
};
$order = 'sea_time desc';
}
if(is_array($whereStaff)){
//查询会冲突
$whereSeas=[];
}
if (isset($params['contract_status']) && $params['contract_status'] !== "") {
$where['contract_status'] = $params['contract_status'];
}
$list = CustomerModel::where($where)->where($whereStaff)->where($whereSeas)->with([
'ownerStaff',
'contacts'
])->field('id,name,next_time,owner_staff_id,level,follow')->order($order)->paginate($limit);
$this->success('请求成功', $list);
}
//查重客户名称
public function selectName()
{
$name = input('name');
if (CustomerModel::where(['name' => $name])->find()) {
$this->error('客户名称已存在');
}
$this->success('当前客户名称可使用');
}
//新增客户
public function addCustomer()
{
$params = $this->request->post();
if (empty($params['customer'])) {
$this->error('客户信息不能为空');
}
// 表单验证
if (($result = $this->qingdongValidate($params['customer'], get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::CUSTOMER_TYPE,$params['customer']);
if ($result !== true) {
$this->error($result);
}
if (CustomerModel::where(['name' => $params['customer']['name']])->find()) {
$this->error('客户名称已存在');
}
if (isset($params['is_event']) && $params['is_event'] == 1) {//是否创建跟进任务
if (empty($params['event'])) {
$this->error('跟进任务信息不能为空');
}
// 表单验证
if (($result = $this->qingdongValidate($params['event'], str_replace(ucwords($this->request->controller()), 'Event', get_class()), 'create_task')) !== true) {
$this->error($result);
}
}
Db::startTrans();
try {
//线索转化
$leads_id = '';
if(isset($params['leads_id'])){
$leads_id=$params['leads_id'];
}
$customerId = CustomerModel::createCustomer($params['customer'],$leads_id,$params['record']);
if(isset($params['customer']['mobile']) && $params['customer']['mobile']){
$retC = array(
'customer_id'=>$customerId,
'is_major'=>1,
'name'=>$params['customer']['name'],
'mobile'=>$params['customer']['mobile'],
'next_time'=>date('Y-m-d H:i:s'),
);
Contacts::createContacts($retC);
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('新增客户成功',array('id'=>$customerId));
}
}
//编辑客户
public function editCustomer()
{
$id = input('id');
$params = $this->request->post();
$row = CustomerModel::where(['id' => $id])->find();
if (empty($row)) {
$this->error('客户信息不存在');
}
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'edit')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::CUSTOMER_TYPE,$params,$id);
if ($result !== true) {
$this->error($result);
}
Db::startTrans();
try {
$result = CustomerModel::updateCustomer($params);
if(isset($params['mobile']) && $params['mobile']){
Contacts::where(array('customer_id'=>$id,'is_major'=>1))->update(array('mobile'=>$params['mobile'],'updatetime'=>time()));
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('修改客户成功');
}
//获取子公司
public function getLowerCustomer()
{
$id = input('id');
$customers = CustomerModel::where(['parent_id' => $id])->with([
'ownerStaff',
'contacts'
])->field('id,name,next_time,owner_staff_id,level,follow')->select();
$this->success('请求成功', $customers);
}
//客户详情
public function customerDetail()
{
$id = input('id');
$customer = CustomerModel::where(['id' => $id])->with([
'createStaff',
'ownerStaff',
'contacts'
])->find();
if (empty($customer)) {
$this->error('信息不存在');
}
$customer = $customer->toArray();
$customer['is_collect'] = StaffCollect::isCollect(StaffCollect::CUSTOMER_TYPE, $customer['id']) ? 1 : 0;
if ($customer['owner_staff_id'] == $this->auth->id ||
in_array($customer['owner_staff_id'],Staff::getLowerStaffId()) ||
in_array($this->auth->id, explode(',', $customer['rw_staff_id'])) ) {
$customer['operation'] = 'update';//修改权限
} else {
$customer['operation'] = 'read';//只读权限
}
$customer = CustomerOther::getOther($customer);
$form = Form::getDataValue('customer',$customer);
foreach($form as $ks=>$vs){
//备注显示
if($vs['component'] == 'textarea' && ($vs['config']['label'] == '备注信息' || $vs['config']['label'] == '备注')){
$customer[$vs['id']] = isset($customer[$vs['id']]) ? $customer[$vs['id']] :$customer['remarks'];
}
}
//商机数量
$customer['bussinessCount'] = Business::where(['customer_id'=>$id])->count();
//联系人数量
$customer['contactsCount'] = Contacts::where(['customer_id'=>$id])->count();
//签到数量
$customer['signCount'] = StaffSignIn::where(['customer_id'=>$id])->count();
//合同数量
$customer['contractCount'] = Contract::where(['customer_id'=>$id])->count();
//费用数量
$customer['consumeCount'] = Consume::where(['customer_id'=>$id])->count();
//回款数量
$customer['receivalbleCount'] = Receivables::where(['customer_id'=>$id])->count();
//子公司
$customer['companyCount'] = CustomerModel::where(['parent_id'=>$id])->count();
//团队
$ro_staff_id = [];
if($customer['ro_staff_id']){
$ro_staff_id = array_unique(array_filter(explode(',',$customer['ro_staff_id'])));
}
$rw_staff_id = [];
if($customer['rw_staff_id']){
$rw_staff_id = array_unique(array_filter(explode(',',$customer['rw_staff_id'])));
}
$customer['teamCount'] = count($ro_staff_id)+count($rw_staff_id);
//附件
$customer['fileCount'] = CustomerFile::where(['customer_id'=>$id])->count();
//操作记录
$customer['operateCount'] = OperationLog::where(['relation_id'=>$id,'relation_type'=>1,'operation_type' => 1])->count();
//标记通知已读
Message::setRead(Message::CUSTOMER_TYPE, $id, $this->auth->id);
$this->success('请求成功', $customer);
}
//移入公海
public function moveSeas()
{
$id = input('id');
$row = CustomerModel::where(['id' => $id, 'owner_staff_id' => $this->auth->id])->find();
if (empty($row)) {
$this->error('您不是负责人暂无权限移除');
}
Db::startTrans();
try {
CustomerModel::moveSeas($id);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('放入成功');
}
//转移客户
public function transfer()
{
$id = input('id');
$staff_id = input('staff_id');
if (empty($staff_id)) {
$this->error('参数错误');
}
$staff = Staff::get($staff_id);
if (empty($staff)) {
$this->error('接收对象不存在');
}
$row = CustomerModel::where(['id' => $id])->find();
if (empty($row)) {
$this->error('客户不存在');
}
try {
CustomerModel::transfer($id, $staff_id);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success('转移客户成功');
}
//领取公海客户
public function receive()
{
$customer_id = input('customer_id');
$where = ['owner_staff_id' => 0];
if ($customer_id) {
$where['id'] = $customer_id;
}
$customers = CustomerModel::where($where)->count();
if ($customers == 0) {
$this->error('公海内暂无客户');
}
try {
$id = CustomerModel::receive($customer_id);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success('领取成功', ['id' => $id]);
}
//重点关注客户
public function collect()
{
$customer_id = input('customer_id');
try {
StaffCollect::addCollect(StaffCollect::CUSTOMER_TYPE, $customer_id);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success('重点关注成功');
}
//取消重点关注
public function cancelCollect()
{
$customer_id = input('customer_id');
try {
StaffCollect::cancel(StaffCollect::CUSTOMER_TYPE, $customer_id);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success('取消重点关注成功');
}
//重点关注客户列表
public function collectList()
{
$limit = input("limit/d", 10);
$ids = StaffCollect::where(['staff_id' => $this->auth->id, 'relation_type' => 1])->column('relation_id');
$list = CustomerModel::where(['id' => ['in', $ids]])->with([
'ownerStaff',
'contacts'
])->field('id,name,next_time,owner_staff_id,level,follow')->order('id desc')->paginate($limit);
$this->success('请求成功', $list);
}
//获取附件列表
public function getFilesList()
{
$id = input('customer_id');
$files = CustomerFile::where(['customer_id' => $id])->field('file_id')->with(['file'])->select();
$this->success('请求成功', $files);
}
//周围客户
public function nearby()
{
$lng = input('lng');
$lat = input('lat');
//我的客户
$type = input('type',0);
//距离
$distance = input('distance', 5, 'intval');
$name = input('name', '', 'trim');
if (empty($lng) && empty($lat)) {
$this->error('参数错误');
}
$range = 180 / pi() * $distance / 6372.797; //里面的 1 就代表搜索 1km 之内,单位km
$lngR = $range / cos($lat * pi() / 180);
$maxLat = $lat + $range; //最大纬度
$minLat = $lat - $range; //最小纬度
$maxLng = $lng + $lngR; //最大经度
$minLng = $lng - $lngR; //最小经度
$where = ['lng' => ['between', [$minLng, $maxLng]], 'lat' => ['between', [$minLat, $maxLat]]];
//客户分类
$whereStaff=[];
$staff_id=$this->auth->id;
if ($type == 1) {//我的客户
$whereStaff['owner_staff_id'] = $this->auth->id;
} elseif ($type == 2) {//下属负责的客户
$whereStaff['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
} elseif ($type == 3) {//我参与的客户
$whereStaff = function ($query) use ($staff_id) {
$query->where('ro_staff_id', 'like', "%,{$staff_id},%")
->whereOr('rw_staff_id', 'like', ",{$staff_id},");
};
}else{
$whereStaff = function ($query) use ($staff_id) {
$query->where('ro_staff_id', 'like', "%,{$staff_id},%")
->whereOr('rw_staff_id', 'like', "%,{$staff_id},%")
->whereOr('owner_staff_id', 'in', Staff::getMyStaffIds());
};
}
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
$customers = CustomerModel::where($where)->where($whereStaff)->field('id,owner_staff_id,name,location,next_time,lng,lat,address_detail,follow')->with('ownerStaff')->select();
$data = [];
//所属员工列表
$myStaffIds = Staff::getMyStaffIds();
foreach ($customers as $k => $v) {
if ($v['owner_staff_id'] == 0) {
$v['type'] = 0;//公海
} elseif ($v['owner_staff_id'] == $this->auth->id) {
$v['type'] = 1;//自己的
} elseif (in_array($v['owner_staff_id'], $myStaffIds)) {
$v['type'] = 2;//团队的
} else {
$v['type'] = 3;//其他人
}
$v['juli_num'] = getdistance($lng, $lat, $v['lng'], $v['lat']);
$v['juli'] = float_number($v['juli_num']);
$data[$v['juli']][] = $v;
}
ksort($data);
$result = [];
foreach ($data as $v) {
$result = array_merge($result, array_values($v));
}
$this->success('请求成功', $result);
}
//获取搜索员工列表
public function getSearchStaffList()
{
$name = input('name','');
$where = [];
if($name){
$where['name'] = ['like',"%$name%"];
}
$ids = Staff::getMyStaffIds();
$staff = Staff::where([
'id' => ['in', $ids],
'status' => 1
])->where($where)->field('id,name,img,post')->select();
$this->success('请求成功', $staff);
}
}

327
addons/qingdong/controller/Daily.php

@ -0,0 +1,327 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Daily as DailyModel;
use addons\qingdong\model\DailyRead;
use addons\qingdong\model\File;
use addons\qingdong\model\Form;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Message;
use addons\qingdong\model\DailyDraft;
use think\Db;
use think\Exception;
/**
* 工作报告接口
*/
class Daily extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//创建
public function createDaily()
{
$params = $this->request->post();
Db::startTrans();
try {
$params['create_staff_id'] = $this->auth->id;
$dailyId = DailyModel::createDaily($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('创建工作报告成功');
}
//获取
public function getList()
{
$limit = input("limit/d", 10);
$is_read = input('is_read', 0);
$staff_ids = input('staff_id', 0);
$type = input('type', 0);
$times = input('times', '');
$where = [];
$where['create_staff_id'] = ['in', Staff::getMyStaffIds()];
if ($staff_ids) {
$where['create_staff_id'] = $staff_ids;
}
if ($type) {
$where['type'] = $type;
}
if ($times) {//筛选时间
$times = explode(',', $times);
$where['createtime'] = ['between', [strtotime($times[0]), strtotime($times[1]) + 86400 - 1]];
}
$staff_id = $this->auth->id;
if ($is_read == 1) {//已读
$ids = DailyRead::where(['staff_id' => $staff_id])->column('daily_id');
$where['id'] = ['in', $ids];
} elseif ($is_read == 2) {//未读
$ids = DailyRead::where(['staff_id' => $staff_id])->column('daily_id');
$where['id'] = ['not in', $ids];
}
$followWhere = [];
$elseWhere = [];
if (!$staff_ids) {
$followWhere[] = ['exp', Db::raw('FIND_IN_SET(' . $this->auth->id . ',reminds_id)')];
if ($type) {
$elseWhere['type'] = ['eq', $type];
}
if ($is_read == 1) {//已读
$elseWhere['id'] = ['in', $ids];
} elseif ($is_read == 2) {//未读
$elseWhere['id'] = ['not in', $ids];
}
}
$records = DailyModel::where($where)->whereOr(function ($query) use ($followWhere, $elseWhere) {
$query->where($followWhere)->where($elseWhere);
})->with([
'staff',
'read' => function ($query) use ($staff_id) {
$query->where(['staff_id' => $staff_id]);
}
])->order('id desc')->paginate($limit)->toArray();
$data = $records['data'];
foreach ($data as $k => $v) {
if (!empty($v['read'])) {
$v['is_read'] = 1;
} else {
$v['is_read'] = 0;
}
$data[$k] = $v;
}
$this->success('请求成功', [
'total' => $records['total'],
'per_page' => $records['per_page'],
'current_page' => $records['current_page'],
'last_page' => $records['last_page'],
'data' => $data
]);
$this->success('请求成功', $records);
}
//获取详情
public function getDailyDetail()
{
$id = input('id');
if (empty($id)) {
$this->error('参数不能为空');
}
$record = DailyModel::where(['id' => $id])->with([
'staff',
])->find();
if (empty($record)) {
$this->error('记录不存在');
}
$record = $record->toArray();
$reminds_id = $record['reminds_id'];
$reminds_id = explode(',', $reminds_id);
$names = Staff::where(['id' => ['in', $reminds_id]])->column('name');
$record['staff_name'] = implode(',', $names);
if ($record['other']) {
if(is_array($record['other'])){
$other = $record['other'];
}else{
$other = json_decode($record['other'], true);
}
} else {
$other = [];
}
$record = array_merge($record, $other);
switch($record['type']){
case '日报':
$type = 'daily';
break;
case '周报':
$type ='weekly';
break;
case '月报':
$type = 'monthly';
break;
case '季报':
$type = 'quarterly';
break;
case '年报':
$type = 'yearly';
break;
default:
$type = 'daily';
break;
}
$form = Form::getDataValue($type,$record);
foreach($form as $k=>$v){
if($v['component'] == 'uploadImage' || $v['component'] == 'uploadFile'){
if(key_exists($v['id'],$record)){
if(isset($record[$v['id']]) && $record[$v['id']]){
$whereT['id'] = array('in',$record[$v['id']]);
$fileinfo = File::where($whereT)->field('id,name,file_path')->select();
if($fileinfo){
$record[$v['id']] = $fileinfo;
}
}
}
}
}
//标记通知已读
Message::setRead(Message::DAILY_TYPE, $id, $this->auth->id);
//添加阅读记录
DailyRead::addRead($id, $this->auth->id);
$this->success('请求成功', $record);
}
//获取工作报告已读 未读
public function getDailyRead()
{
$id = input('id');
if (empty($id)) {
$this->error('参数错误');
}
$daily = DailyModel::where(['id' => $id])->find();
if (empty($daily)) {
$this->error('记录不存在');
}
$create_staff_id = $daily['create_staff_id'];
$read = DailyRead::where(['daily_id' => $id])->group('staff_id')->field('id,staff_id')->with(['staff'])->select();
$staffIds = [];
foreach ($read as $v) {
$staffIds[] = $v['staff_id'];
}
//全部可看数据的人
$allids = explode(',', $daily->reminds_id);
$not_ids = array_diff($allids, $staffIds);
$notRead = Staff::where(['id' => ['in', $not_ids]])
->field('id,name,img')->select();
$this->success('请求成功', ['read' => $read, 'not_read' => $notRead]);
}
//草稿创建
public function daily_draft()
{
$params = $this->request->post();
Db::startTrans();
try {
$params['create_staff_id'] = $this->auth->id;
//自定义字段
$other = [];
foreach ($params as $name => $val) {
if (strstr($name, 'other_') !== false) {
if(is_array($val)){
$other[$name] = implode(',',$val);
}else{
$other[$name] = $val;
}
unset($params[$name]);
}
}
$params['other'] = json_encode($other);
$where['create_staff_id'] = $this->auth->id;
$where['type'] = $params['type'];
$info = DailyDraft::where($where)->find();
if ($info) {
$result = DailyDraft::where(array('id' => $info['id']))->update($params);
} else {
$result = DailyDraft::create($params);
}
if (false === $result) {
// 验证失败 输出错误信息
throw new Exception('草稿保存失败');
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('草稿保存成功');
}
//获取详情
public function getDailyDraftDetail()
{
$type = input('type');
if (!$type) {
$this->error('参数不正确');
}
$where['create_staff_id'] = $this->auth->id;
$where['type'] = $type;
$record = DailyDraft::where($where)->find();
if (empty($record)) {
$this->success('记录不存在');
}
switch ($record['type']) {
case '日报':
$record['type_index'] = 0;
break;
case '周报':
$record['type_index'] = 1;
break;
case '月报':
$record['type_index'] = 2;
break;
case '季报':
$record['type_index'] = 3;
break;
case '年报':
$record['type_index'] = 4;
break;
default:
$record['type_index'] = 0;
break;
}
$record = $record->toArray();
$reminds_id = $record['reminds_id'];
$reminds_id = explode(',', $reminds_id);
$names = Staff::where(['id' => ['in', $reminds_id]])->field('id,img,name,post')->select();
$record['staff_info'] = $names;
if ($record['other']) {
$other = json_decode($record['other'], true);
} else {
$other = [];
}
$record = array_merge($record, $other);
$this->success('请求成功', $record);
}
//修改工作报告
public function updateDaily()
{
$params = $this->request->post();
if(empty($params['id'])){
$this->error('参数不能为空');
}
Db::startTrans();
try {
$dailyId = DailyModel::updateDaily($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('创建工作报告成功');
}
}

23
addons/qingdong/controller/ErrorCode.php

@ -0,0 +1,23 @@
<?php
namespace addons\qingdong\controller;
/**
* error code 说明.
* <ul>
* <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
* </ul>
*/
class ErrorCode
{
public static $OK = 0;
public static $IllegalAesKey = -41001;
public static $IllegalIv = -41002;
public static $IllegalBuffer = -41003;
public static $DecodeBase64Error = -41004;
}
?>

206
addons/qingdong/controller/Event.php

@ -0,0 +1,206 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Event as EventModel;
use addons\qingdong\model\File;
use addons\qingdong\model\Form;
use addons\qingdong\model\StaffSignIn;
use addons\qingdong\model\Message;
use addons\qingdong\model\Staff;
use think\Db;
use think\Exception;
/**
* 日程接口
*/
class Event extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = [];
//获取日程
public function getEvent()
{
//开始时间
$start_day = input('start_day');
//结束时间
$end_day = input('end_day');;
if (empty($start_day) || empty($end_day)) {
$this->error('开始时间或结束时间不能为空');
}
if ($end_day < $start_day) {
$this->error('开始时间不能小于结束时间');
}
$this->success('请求成功', EventModel::getTimeList($start_day, $end_day));
}
//添加日程
public function addEvent()
{
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
Db::startTrans();
try {
$params['type'] = 1;//日程
$result = EventModel::createEvent($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('添加日程成功');
}
}
//变更状态
public function changeStatus()
{
$id = input('id');
$status = input('status', 0);
if (empty($id)) {
$this->error('参数错误');
}
Db::startTrans();
try {
EventModel::changeStatus($id, $status);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('变更成功');
}
//
public function getList()
{
$relation_type = input('relation_type', '', 'intval');// 1客户 2联系人 3合同 4线索
$relation_id = input('relation_id', '', 'intval');
$limit = input("limit/d", 10);
$where = [];
$where['relation_type'] = $relation_type;
$where['relation_id'] = $relation_id;
$where['staff_id'] = $this->auth->id;
$records = EventModel::where($where)->with(['staff'])->field('id,staff_id,type,title,start_time,end_time,status,auto_end,level,remindtype,remark,color,createtime')->order('id desc')->paginate($limit);
$this->success('请求成功', $records);
}
//添加签到
public function addSign()
{
$params = $this->request->post();
$location = input('location');
$lng = input('lng');
$lat = input('lat');
$files = input('file_ids');
$customer_id = input('customer_id');
$content = input('content');
if (empty($lng) || empty($lat)) {
$this->error('地理位置不能为空');
}
//自定义字段
$other = [];
foreach ($params as $name => $val) {
if (strstr( $name,'other_') !== false) {
if(is_array($val)){
$other[$name] = implode(',',$val);
}else{
$other[$name] = $val;
}
unset($params[$name]);
}
}
$data = [
'location' => $location,
'lng' => $lng,
'lat' => $lat,
'file_ids' => $files,
'customer_id' => $customer_id,
'staff_id' => $this->auth->id,
'other' => json_encode($other, JSON_UNESCAPED_UNICODE)
];
$model = new StaffSignIn();
if ($result = $model->save($data)) {
$lastId = $model->getLastInsID();
//通知上级
Message::addMessage(Message::SIGN_TYPE, $lastId, $this->auth->parent_id, $this->auth->id);
$this->success('签到成功');
}
$this->error('签到失败');
}
//获取签到信息
public function getSign()
{
$customer_id = input('customer_id', 0, 'intval');
$limit = input("limit/d", 10);
$where = [];
$type = input('type', 0);// 0 全部 1 我创建 2 下属创建
if ($type == 1) {//我的客户
$where['staff_id'] = $this->auth->id;
} elseif ($type == 2) {//下属负责的客户
$where['staff_id'] = ['in', Staff::getLowerStaffId()];
}else{
$where['staff_id'] = ['in', Staff::getMyStaffIds()];
}
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
$staffSign = StaffSignIn::where($where)->with(['staff', 'customer'])
->order('id desc')->paginate($limit);
//标记通知已读
Message::setRead(Message::SIGN_TYPE,0, $this->auth->id);
$this->success('请求成功', $staffSign);
}
/**
* 获取签到详情
*/
public function getSignDetail(){
$id = input('id', 0, 'intval');
$staffSign = StaffSignIn::where(['id'=>$id])->with(['staff', 'customer'])->find();
if(empty($staffSign)){
$this->error('数据不存在');
}
if($staffSign['other']){
$other = json_decode($staffSign['other'],true);
$form = Form::getDataValue('signin');
foreach($form as $k=>$v){
if($v['component'] == 'uploadImage' || $v['component'] == 'uploadFile'){
$other[$v['id'].'_str'] = '';
if(key_exists($v['id'],$other)){
if(isset($other[$v['id']]) && $other[$v['id']]){
$whereT['id'] = array('in',$other[$v['id']]);
$fileinfo = File::where($whereT)->field('id,name,file_path,save_name')->select();
if($fileinfo){
$other[$v['id']] = $fileinfo;
$fileinfodata = '';
foreach($fileinfo as $kss=>$vss){
$fileinfodata = $vss['save_name'].','.$fileinfodata;
}
$other[$v['id'].'_str'] = rtrim($fileinfodata,',');
}
}
}
}
}
$staffSign['other'] = $other;
}
$this->success('请求成功',$staffSign);
}
}

257
addons/qingdong/controller/ExamineRecord.php

@ -0,0 +1,257 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\AchievementRecords;
use addons\qingdong\model\AttendanceStatisc;
use addons\qingdong\model\Business;
use addons\qingdong\model\BusinessStatus;
use addons\qingdong\model\Flow;
use addons\qingdong\model\FormApproval;
use addons\qingdong\model\Message;
use addons\qingdong\model\Contract;
use addons\qingdong\model\Consume;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Receivables;
use addons\qingdong\model\Achievement;
use addons\qingdong\model\Approval;
use addons\qingdong\model\ExamineRecord as ExamineRecordModel;
use think\Cache;
use think\Db;
use think\Exception;
use think\Log;
/**
* 审批记录
*/
class ExamineRecord extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//审批记录
public function getList() {
$relation_type = input('relation_type');
$relation_id = input('relation_id');
$list = ExamineRecordModel::where([
'relation_type' => $relation_type,
'relation_id' => $relation_id
])->with('checkStaff')->select();
$this->success('请求成功', $list);
}
//审核
public function examine() {
$relation_type = input('relation_type');
$relation_id = input('relation_id');
$content = input('content');
$status = input('status');
$record = ExamineRecordModel::where([
'relation_type' => $relation_type,
'relation_id' => $relation_id,
'status' => 0,
'check_staff_id' => $this->auth->id
])->find();
if (empty($record)) {
$this->error('没有待审核数据');
}
$staff = Staff::info();
Db::startTrans();
try {
$model = new ExamineRecordModel();
if ($model->isUpdate(true)->save([
'status' => $status,
'content' => $content,
'check_time' => time()
], ['id' => $record['id']]) == false) {
throw new Exception('修改失败');
}
switch ($relation_type) {
case $model::CONSUME_TYPE://费用
$rowModel = new \addons\qingdong\model\Consume();
$row = $rowModel->where(['id' => $relation_id])->find();
break;
case $model::CONTRACT_TYPE://合同
$rowModel = new \addons\qingdong\model\Contract();
$row = $rowModel->where(['id' => $relation_id])->find();
break;
case $model::RECEIVABLES_TYPE://回款
$rowModel = new \addons\qingdong\model\Receivables();
$row = $rowModel->where(['id' => $relation_id])->find();
break;
case $model::ACHIEVEMENT_TYPE://业绩目标
$rowModel = new \addons\qingdong\model\AchievementRecords();
$row = $rowModel->where(['id' => $relation_id])->find()->toArray();
break;
case $model::APPROVAL_TYPE://审批
$rowModel = new \addons\qingdong\model\Approval();
$row = $rowModel->where(['id' => $relation_id])->find()->toArray();
$row['staff_id'] = $row['create_staff_id'];
break;
case $model::CARD_TYPE://补卡审核
$rowModel = new \addons\qingdong\model\AttendanceCard();
$row = $rowModel->where(['id' => $relation_id])->find()->toArray();
$row['staff_id'] = $row['create_staff_id'];
break;
case $model::LEAVE_TYPE://请假
$rowModel = new \addons\qingdong\model\Leave();
$row = $rowModel->where(['id' => $relation_id])->find()->toArray();
$row['staff_id'] = $row['create_staff_id'];
break;
default:
throw new Exception('参数错误');
}
if ($message = Message::where(['relation_type' => 'examine', 'relation_id' => $record['id'],'to_staff_id'=>$this->auth->id])->find()) {
Message::where(['id' => $message['id']])->update(['status' => 1, 'read_time' => time()]);
}
$check_staff_ids = explode(',', trim($row['check_staff_ids'], ','));
$check_staff_ids[] = $staff->id;
if ($status == 1) {//审核通过
$flow= Flow::getstepdetail($relation_type,$relation_id);
//给下一审核人发送通知
$result=Flow::sendStepRecord($flow,$relation_type, $relation_id,$check_staff_ids,$staff->id);
//已完成审核
if ($result['status']== true) {
$rowModel->save([
'check_status' => 2,
'check_staff_ids' => implode(',', $check_staff_ids),
'order_id'=>$result['order_id']
], ['id' => $relation_id]);
switch ($relation_type) {
case $model::CONTRACT_TYPE://合同
\addons\qingdong\model\Customer::where(['id'=>$row['customer_id']])->update(['contract_status'=>1]);
//合同签署成功后商机变为赢单
if($row['business_id']){
BusinessStatus::create(array('business_id'=>$row['business_id'],'type'=>4,'remark'=>'合同签署'));
Business::where(array('id'=>$row['business_id']))->update(array('contract_status'=>1,'updatetime'=>time()));
}
break;
case $model::ACHIEVEMENT_TYPE://业绩目标
$m=new \addons\qingdong\model\Achievement();
$m->where(['type'=>$row['type'],'status'=>$row['status'],'obj_id'=>$row['obj_id']])->delete();
unset($row['id']);
unset($row['createtime']);
unset($row['updatetime']);
unset($row['deletetime']);
$m->allowField(true)->save($row);
$row['staff_id']=$row['obj_id'];
break;
case $model::RECEIVABLES_TYPE://回款
$m=new \addons\qingdong\model\Contract();
$contract=$m->where(['id'=>$row['contract_id']])->with(['receivables'])->find();
if($contract['receivables']['repayment_money'] >= $contract['money']){
$m->save(['contract_status'=>1],['id'=>$row['contract_id']]);//已完成
}
break;
case $model::CARD_TYPE://补卡
if($row['type'] == 1){//早退
$name='clock_out_status';
$name_time='clock_out';
}else{//迟到
$name='clock_in_status';
$name_time='clock_in';
}
AttendanceStatisc::where(['id'=>$row['statisc_id']])->update([$name=>5,$name_time=>$row['time']]);
break;
case $model::LEAVE_TYPE://请假
break;
}
Message::addMessage(Message::EXAMINE_ADOPT_TYPE,$record['id'],$row['owner_staff_id']?? $row['staff_id'],$staff->id);
//删除 或签的待审批通知
Message::setRead(Message::EXAMINE_TYPE,$record['id']);
ExamineRecordModel::where([
'relation_type' => $relation_type,
'relation_id' => $relation_id,
'status' => 0,
])->update(['status'=>3]);
} else {
$rowModel->save([
'check_staff_ids' => implode(',', $check_staff_ids),
'order_id'=>$result['order_id']
], ['id' => $relation_id]);
}
} else {
//审核未通过
$rowModel->save(['check_status' => 3, 'check_staff_ids' => ''], ['id' => $relation_id]);
Message::addMessage(Message::EXAMINE_REFUSE_TYPE,$record['id'],$row['owner_staff_id']?? $row['staff_id'],$staff->id,'');
//删除待审批通知
$ids = ExamineRecordModel::where([
'relation_type' => $relation_type,
'relation_id' => $relation_id,
'status' => 0,
])->column('id');
Message::where(['relation_type' => Message::EXAMINE_TYPE, 'relation_id' => ['in', $ids], 'status' => 0])->update(['read_time' => time(), 'status' => 1]);
ExamineRecordModel::where([
'relation_type' => $relation_type,
'relation_id' => $relation_id,
'status' => 0,
])->update(['status'=>3]);
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
Log::record($e->getMessage());
$this->error($e->getMessage());
}
$this->success('审核成功');
}
/**
* 获取审批列表
*/
public function get_examine_list()
{
$limit = input("limit/d", 10);
//合同审批,回款审批、业绩目标审批、办公审批 费用
$relation_type = input('type');
$status = input('status',0);
if($status == 1){
$status = array('in','1,2');
}
$data = ExamineRecordModel::where(['relation_type' => $relation_type,
'status' => $status,
'check_staff_id' => $this->auth->id])->order('id desc')->paginate($limit)->toArray();
if($data['data']){
foreach($data['data'] as $k=>$v){
$data['data'][$k]['content_info'] = Message::where(array('relation_id'=>$v['id'],'relation_type'=>'examine'))->value('content');
if ($v['relation_type'] == ExamineRecordModel::CONSUME_TYPE) {
$data['data'][$k]['relation_name'] = Consume::where(['id' => $v['relation_id']])->value('consume_type');
} elseif ($v['relation_type'] == ExamineRecordModel::CONTRACT_TYPE) {
$data['data'][$k]['relation_name'] = Contract::where(['id' => $v['relation_id']])->value('name');
} elseif ($v['relation_type'] == ExamineRecordModel::RECEIVABLES_TYPE) {
$data['data'][$k]['relation_name'] = Receivables::where(['id' => $v['relation_id']])->value('number');
} elseif($v['relation_type'] == ExamineRecordModel::ACHIEVEMENT_TYPE) {
$data['data'][$k]['relation_name'] = $acchieve = AchievementRecords::where(['id' => $v['relation_id']])->value('year');;
} elseif($v['relation_type'] == ExamineRecordModel::APPROVAL_TYPE) {
$approval = Approval::where(['id' => $v['relation_id']])->value('formapproval_id');
$data['data'][$k]['relation_name'] = '';
if($approval){
$data['data'][$k]['relation_name'] = FormApproval::where(['id'=>$approval])->value('name');
}
}elseif($v['relation_type'] == ExamineRecordModel::CARD_TYPE) {
$data['data'][$k]['relation_name'] = '补卡';
}elseif($v['relation_type'] == ExamineRecordModel::LEAVE_TYPE) {
$data['data'][$k]['relation_name'] = '请假';
}
else{
$data['data'][$k]['relation_name']='';
}
}
}
$this->success('请求成功', $data);
}
}

30
addons/qingdong/controller/File.php

@ -0,0 +1,30 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\File as FileModel;
/**
* 附件接口
*/
class File extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//修改附件名称
public function editName() {
$id = input("id", 0);
$name = input('name', '');
$filemodel = new FileModel();
$row = $filemodel->get($id);
if (empty($row)) {
$this->error('附件不存在');
}
if ($row->save(['name' => $name])) {
$this->success('修改成功');
} else {
$this->error('修改失败');
}
}
}

463
addons/qingdong/controller/Index.php

@ -0,0 +1,463 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Contract as ContractModel;
use addons\qingdong\model\Event;
use addons\qingdong\model\ExamineRecord;
use addons\qingdong\model\Feedback;
use addons\qingdong\model\ReceivablesPlan;
use addons\qingdong\model\Customer;
use addons\qingdong\model\Contacts;
use addons\qingdong\model\Contract;
use addons\qingdong\model\Leads;
use addons\qingdong\model\Receivables;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Record;
use addons\qingdong\model\Message;
use addons\qingdong\model\Business;
/**
* * 操作文档:https://doc.fastadmin.net/qingdong
* 软件介绍:https://www.fastadmin.net/store/qingdong.html
* 售后微信:qingdong_crm
* 首页接口
*/
class Index extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$this->error("当前插件暂无前台页面");
}
//搜索
public function search()
{
$keywords = input('keywords');
$type = input('type');
if (empty($keywords)) {
$this->error('筛选字段不能为空');
}
//客户
$customer = Customer::where([
'name' => ['like', "%$keywords%"],
'owner_staff_id' => ['in', Staff::getMyStaffIds()],
])->with([
'ownerStaff',
'contacts'
])->field('id,name,next_time,owner_staff_id,level,follow')->select();
//联系人
$contacts = Contacts::where([
'name' => ['like', "%$keywords%"],
'owner_staff_id' => ['in', Staff::getMyStaffIds()],
])->with(['customer'])->field('id,name,mobile,customer_id')->select();
//线索
$leads = Leads::where([
'name' => ['like', "%$keywords%"],
'owner_staff_id' => ['in', Staff::getMyStaffIds()],
])->with(['ownerStaff'])->field('id,owner_staff_id,name,follow,level,next_time,mobile')->select();
$this->success('请求成功', [
'customer' => $customer,
'contacts' => $contacts,
'leads' => $leads
]);
}
//反馈
public function feedback()
{
$content = input('content', '', 'trim');
$file = input('file', '', 'trim');
if (empty($content)) {
$this->error('请输入反馈内容!');
}
$model = new Feedback();
$model->save([
'staff_id' => $this->auth->id,
'content' => $content,
'file_ids' => $file
]);
$this->success('反馈成功');
}
//待办事项
public function agent()
{
$where['create_staff_id'] = $this->auth->id;
$where['next_time'] = array(array('egt', date('Y-m-d 00:00:00')), array('lt', date('Y-m-d 23:59:59')));
$where['follow_type'] = ['neq', '其它'];
$where['status'] = 0;
// 待跟进客户
$where1['relation_type'] = 1;
$customerlist = Record::where($where)->where($where1)->column('id');
$customerlist1 = 0;
if ($customerlist) {
$whereExit['id'] = array('in', $customerlist);
$whereExit['next_time'] = array('gt', date('Y-m-d 23:59:59'));
$customerlist1 = Record::where($whereExit)->count();
}
$customer = count($customerlist) - $customerlist1;
//待跟进合同
$where2['relation_type'] = 3;
$contractlist = Record::where($where)->where($where2)->column('id');
$contractlist1 = 0;
if ($contractlist) {
$whereExitC['id'] = array('in', $contractlist);
$whereExitC['next_time'] = array('gt', date('Y-m-d 23:59:59'));
$contractlist1 = Record::where($whereExitC)->count();
}
$contract = count($contractlist) - $contractlist1;
//待跟进线索
$where3['relation_type'] = 4;
$leadlist = Record::where($where)->where($where3)->column('id');
$leadlist1 = 0;
if ($leadlist) {
$whereExitL['id'] = array('in', $leadlist);
$whereExitL['next_time'] = array('gt', date('Y-m-d 23:59:59'));
$leadlist1 = Record::where($whereExitL)->count();
}
$lead = count($leadlist) - $leadlist1;
//待跟进联系人
$where4['relation_type'] = 2;
$contactslist = Record::where($where)->where($where4)->column('id');
$contactslist1 = 0;
if ($contactslist1) {
$whereExitCs['id'] = array('in', $contactslist);
$whereExitCs['next_time'] = array('gt', date('Y-m-d 23:59:59'));
$contactslist1 = Record::where($whereExitCs)->count();
}
$contacts = count($contactslist) - $contactslist1;
//待跟进商机
$where5['relation_type'] = 5;
$businesslist = Record::where($where)->where($where5)->column('id');
$businesslist1 = 0;
if ($businesslist1) {
$whereExitB['id'] = array('in', $businesslist);
$whereExitB['next_time'] = array('gt', date('Y-m-d 23:59:59'));
$businesslist1 = Record::where($whereExitB)->count();
}
$business = count($businesslist) - $businesslist1;
//待审核合同
$examine = ExamineRecord::where([
'relation_type' => ExamineRecord::CONTRACT_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//待审核回款
$receivables = ExamineRecord::where([
'relation_type' => ExamineRecord::RECEIVABLES_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//待回款提醒
$receivablesPlan = ReceivablesPlan::where([
'remind_date' => ['elt', date('Y-m-d')],
'status' => 0,
'owner_staff_id' => $this->auth->id
])->count();
//待处理日程
$eventOne = Event::where([
'type' => 1,
'status' => ['in', [0, 1]],
'start_time' => ['lt', date('Y-m-d', strtotime('+1 day'))],
'staff_id|owner_staff_id' => $this->auth->id,
])->count();
$this->success('请求成功', [
'customer' => $customer,
'business' => $business,
'contract' => $contract,
'lead' => $lead,
'contacts' => $contacts,
'event_one' => $eventOne,
'examine' => $examine,
'receivables' => $receivables,
'receivables_plan' => $receivablesPlan
]);
}
//待处理日程
public function event_one()
{
// 待处理日程
$eventTask = Event::where([
'type' => 1,
'status' => ['in', [0, 1]],
'start_time' => ['lt', date('Y-m-d', strtotime('+1 day'))],
'staff_id|owner_staff_id' => $this->auth->id,
])->order('id desc')->select();
//标记通知已读
Message::where([
'relation_type' => Message::EVENT_TYPE,
'to_staff_id' => $this->auth->id,
'status' => 0
])->update(['read_time' => time(), 'status' => 1]);
foreach ($eventTask as &$ves) {
$ves['start_time'] = date('Y-m-d H:i', strtotime($ves['start_time']));
$ves['end_time'] = date('Y-m-d H:i', strtotime($ves['end_time']));
}
$this->success('请求成功', $eventTask);
}
//跟进任务
public function event_task()
{
// 待跟进任务
$eventTask = Event::where([
'type' => 2,
'status' => ['in', [0, 1]],
'start_time' => ['lt', date('Y-m-d', strtotime('+1 day'))],
'staff_id' => $this->auth->id
])->select();
foreach ($eventTask as &$ves) {
$ves['start_time'] = date('Y-m-d H:i', strtotime($ves['start_time']));
$ves['end_time'] = date('Y-m-d H:i', strtotime($ves['end_time']));
}
$this->success('请求成功', $eventTask);
}
//待审核合同
public function examine_contract()
{
//待审核合同
$ids = ExamineRecord::where([
'relation_type' => ExamineRecord::CONTRACT_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->column('relation_id');
$contracts = ContractModel::where(['id' => ['in', $ids]])->with([
'customer',
'contacts',
'ownerStaff',
'orderStaff',
'receivables'
])->order('id desc')->select();
$contracts = collection($contracts)->toArray();
foreach ($contracts as $k => $v) {
if (empty($v['receivables'])) {
$v['receivables'] = [
'repayment_money' => 0,
'be_money' => $v['money'],
'ratio' => 0
];
} else {
$be_money = $v['money'] - $v['receivables']['repayment_money'];
$v['receivables'] = [
'repayment_money' => $v['receivables']['repayment_money'],
'be_money' => ($be_money > 0) ? $be_money : 0,
'ratio' => round($v['receivables']['repayment_money'] / $v['money'] * 100, 2)
];
}
$contracts[$k] = $v;
}
$this->success('请求成功', $contracts);
}
//待审核回款
public function examine_receivables()
{
//待审核回款
$ids = ExamineRecord::where([
'relation_type' => ExamineRecord::RECEIVABLES_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id,
])->column('relation_id');
$receivables = Receivables::where(['id' => ['in', $ids]])->with([
'contract',
'createStaff'
])->order('id desc')->select();
$this->success('请求成功', $receivables);
}
//待回款提醒
public function examine_receivables_plan()
{
//待回款提醒
$receivablesPlan = ReceivablesPlan::where([
'remind_date' => ['elt', date('Y-m-d')],
'status' => 0,
'owner_staff_id' => $this->auth->id,
])->order('id desc')->with(['contract', 'customer'])->select();
$this->success('请求成功', $receivablesPlan);
}
//数据简报
public function briefing()
{
$type = input('type', 0);//0 本人及下属 1 仅本人 2 仅下属
$times = input('times', '');
$times = explode(',', $times);
if (empty($times)) {
$this->error('参数不能为空');
}
$startDate=strtotime($times[0]);
$endDate=strtotime($times[1])+86400-1;
$where = [
'createtime' => ['between', [$startDate, $endDate]]
];
$whereC = [
'order_date' => ['between', [date('Y-m-d 00:00:00',$startDate), date('Y-m-d 23:59:59',$endDate)]]
];
$whereR = [
'return_time' => ['between', [date('Y-m-d 00:00:00',$startDate), date('Y-m-d 23:59:59',$endDate)]]
];
if ($type == 1) {
$where['owner_staff_id'] = $this->auth->id;
$whereC['owner_staff_id'] = $this->auth->id;
$whereR['owner_staff_id'] = $this->auth->id;
} elseif ($type == 2) {
$where['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
$whereC['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
$whereR['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
} else {
$where['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
$whereC['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
$whereR['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
}
//客户 线索 联系人 合同 回款 跟进次数 处理审批
$leads = Leads::where($where)->count();
$customer = Customer::where($where)->count();
$contacts = Contacts::where($where)->count();
$contract = Contract::where([])->where($whereC)->count();
$contract_money = Contract::where(['check_status'=>2])->where($whereC)->sum('money');
$receivables_money = Receivables::where(['check_status'=>2])->where($whereR)->sum('money');
$record = Record::where([
'create_staff_id' => $where['owner_staff_id'],
'createtime' => $where['createtime']
])->where(['follow_type' => ['neq', '其它']])->count();
$examine = ExamineRecord::where([
'check_staff_id' => $where['owner_staff_id'],
'createtime' => $where['createtime']
])->count();
//商机总数
$business = Business::where($where)->count();
//客户成交量
$customer_complate = Customer::where($where)->where(['contract_status' => 1])->count();
//客户未成交量
$customer_nocomplate = Customer::where($where)->where(['contract_status' => 0])->count();
//商机成交总数
$business_complate = Business::where($where)->where(['contract_status' => 1])->count();
//商机未成交总数
$business_nocomplate = Business::where($where)->where(['contract_status' => 0])->count();
//商机成交金额
$business_complate_money = Business::where($where)->where(['contract_status' => 1])->sum('money');
//商机未成交金额
$business_nocomplate_money = Business::where($where)->where(['contract_status' => 0])->sum('money');
$this->success('请求成功', [
'leads' => $leads,
'customer' => $customer,
'contacts' => $contacts,
'contract' => $contract,
'contract_money' => $contract_money,
'receivables' => $receivables_money,
'record' => $record,
'business' => $business,
'examine' => $examine,
'customer_complate' => $customer_complate,
'customer_nocomplate' => $customer_nocomplate,
'business_complate' => $business_complate,
'business_nocomplate' => $business_nocomplate,
'business_complate_money' => $business_complate_money,
'business_nocomplate_money' => $business_nocomplate_money,
]);
}
/**
*交易额排行
*/
public function contractRanding()
{
$date = input('date', date('Y-m'));
$type = input('type', 0);//0 本人及下属 1 仅本人 2 仅下属
//月底
$endDate = date('Y-m-d', strtotime('+1 month', strtotime(date($date . '-1'))) - 1);
$where = [
'order_date' => ['between', [$date . '-1', $endDate]],
'check_status' => 2,
];
$contracts = Contract::where($where)->group('owner_staff_id')->field('owner_staff_id,sum(money) as money')->order('money desc')->select();
$list = [];
foreach ($contracts as $v) {
$list[$v['owner_staff_id']] = $v['money'];
}
$contracts = $list;
$data = [];
$staffs = Staff::getList();
foreach ($staffs as $v) {
if (isset($contracts[$v['id']])) {
$data[$v['id']] = $contracts[$v['id']];
} else {
$data[$v['id']] = 0;
}
}
arsort($data);
$staffs = Staff::getKeyList();
$result = [];
$i = 1;
$oneMoney = 0;
if ($type == 1) {//本人
$showStaffIds = [$this->auth->id];
} elseif ($type == 2) {//下属
$showStaffIds = Staff::getLowerStaffId();
} else {//全部
$showStaffIds = Staff::getMyStaffIds();
}
foreach ($data as $id => $money) {
if ($i == 1) {
$oneMoney = $money;
}
$val = $staffs[$id];
$val['money'] = $money;
$val['ratio'] = $oneMoney ? sprintf("%.2f", $money / $oneMoney * 100) : 0;
$val['rank'] = $i;
$i++;
if (in_array($id, $showStaffIds)) {
$result[] = $val;
}
}
if (count($result) >= 10) {
$top = array_slice($result, 0, 3);
$bottom = array_slice($result, -3, 3);
$middle = array_slice($result, 3, 4);
$result = array_merge($top, $bottom, $middle);
}
$this->success('请求成功', $result);
}
//服务协议
public function serviceContent()
{
$this->success('请求成功', [
'content' => "<h1>用户服务协议</h1>",
'name' => '青动时代',
'logo' => ''
]);
}
}

258
addons/qingdong/controller/Leads.php

@ -0,0 +1,258 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Event;
use addons\qingdong\model\Form;
use addons\qingdong\model\FormField;
use addons\qingdong\model\Leads as LeadsModel;
use addons\qingdong\model\LeadsFile;
use addons\qingdong\model\LeadsOther;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Record;
use think\Db;
use think\Exception;
/**
* 线索接口
*/
class Leads extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
public function _initialize()
{
parent::_initialize();
try{
\think\Db::execute("SET @@sql_mode='';");
}catch (Exception $e){
}
}
//添加线索
public function addLeads() {
$params = $this->request->post();
if (empty($params['leads'])) {
$this->error('线索信息不能为空');
}
// 表单验证
if (($result = $this->qingdongValidate($params['leads'], get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::LEADS_TYPE, $params['leads']);
if ($result !== true) {
$this->error($result);
}
try {
$params['leads'] = Form::updateFormParams(Form::LEADS_TYPE, $params['leads']);
$leadsId = LeadsModel::createLeads($params['leads']);
} catch (Exception $e) {
$this->error($e->getMessage());
}
if ($result) {
$this->success('添加线索成功');
}
}
//获取线索列表
public function getList() {
$name = input('name', '', 'trim');
$mobile = input('mobile', '', 'trim');
$limit = input("limit/d", 10);
$params = $this->request->post();
$where= FormField::updateWhereField(FormField::LEADS_TYPE,$params);
if (isset($params['createtime']) && $params['createtime']) {//跟进状态
$createtime = $params['createtime'];
$createtime = explode(',', $createtime);
$where['createtime'] = ['between', [strtotime($createtime[0]), strtotime($createtime[1])+86400-1]];
}
$wheres=[];
//0:全部 1:我负责的 2:下属负责的 3:今日待跟进 4:今日已跟进 5:从未跟进的
$team = input('team',0);
switch($team){
case 1:
$staff = Staff::info();
$wheres['owner_staff_id'] = $staff->id;
break;
case 2:
$wheres['owner_staff_id'] = array('in',Staff::getLowerStaffId());
break;
case 3:
$start = date('Y-m-d 00:00:00');
$end = date('Y-m-d 23:59:59');
$record = collection(Record::where(array('status'=>0,'relation_type'=>4,'next_time'=>array(array('egt',$start),array('elt',$end))))->field("id,relation_id")->select())->toArray();
$relationId = [];
foreach($record as $k=>$v){
$whereRe['id'] = array('gt',$v['id']);
$whereRe['relation_id'] = $v['relation_id'];
$recordData = Record::where($whereRe)->count();
if($recordData == 0){
$relationId[] = $v['relation_id'];
}
}
$wheres['id'] = array('in',$relationId);
$staff = Staff::info();
$wheres['owner_staff_id'] = $staff->id;
break;
case 4:
$start = date('Y-m-d 00:00:00');
$end = date('Y-m-d 23:59:59');
$relationId = Record::where(array('status'=>1,'relation_type'=>4,'next_time'=>array(array('egt',$start),array('elt',$end))))->field("id,relation_id")->column('relation_id');
$wheres['id'] = array('in',$relationId);
$staff = Staff::info();
$wheres['owner_staff_id'] = $staff->id;
break;
case 5:
$record = collection(Record::where(array('relation_type'=>4))->column('relation_id'))->toArray();
$wheres['id'] = array('not in',$record);
$staff = Staff::info();
$wheres['owner_staff_id'] = $staff->id;
break;
default:
$wheres['owner_staff_id'] = array('in',Staff::getMyStaffIds());
break;
}
if (isset($params['staff_id']) && $params['staff_id']) {//下级员工筛选
$wheres['owner_staff_id'] = $params['staff_id'];
}
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
if ($mobile) {
$where['mobile'] = ['like', "%{$mobile}%"];
}
$where['is_transform']=0;
$records = LeadsModel::where($where)->where($wheres)->with(['ownerStaff'])->field('id,owner_staff_id,name,follow,mobile,level,next_time,source')->order('id desc')->paginate($limit);
$this->success('请求成功', $records);
}
//获取线索详情
public function getDetail() {
$id = input('id', '', 'intval');
$leads = LeadsModel::where(['id' => $id])->with([
'createStaff',
'ownerStaff',
'tranferStaff'
])->find();
if(empty($leads)){
$this->error('信息不存在');
}
$leads=$leads->toArray();
$leads=LeadsOther::getOther($leads);
$this->success('请求成功', $leads);
}
//获取选择列表
public function getSelectList() {
$name = input('name','');
$where = ['owner_staff_id' => $this->auth->id,'is_transform'=>0];
if ($name) {
$where['name'] = ['like',"%$name%"];
}
$records = LeadsModel::where($where)->field('id,owner_staff_id,name,follow,mobile')->order('id desc')->select();
$this->success('请求成功', $records);
}
//转移线索
public function transfer()
{
$id = input('id');
$staff_id = input('staff_id');
if (!$staff_id || !$id) {
$this->error('参数错误');
}
$staff = Staff::get($staff_id);
if (empty($staff)) {
$this->error('接收对象不存在');
}
$row = LeadsModel::where(['id' => $id])->find();
if (empty($row)) {
$this->error('线索不存在');
}
try {
LeadsModel::transfer($id, $staff_id);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success('转移线索成功');
}
//修改线索
public function editLeads() {
$id = input('id');
$params = $this->request->post();
$row = LeadsModel::where(['id' => $id, 'owner_staff_id' => $this->auth->id])->find();
if (empty($row)) {
$this->error('您不是线索负责人无法修改信息');
}
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::LEADS_TYPE, $params,$id);
if ($result !== true) {
$this->error($result);
}
try {
$params= Form::updateFormParams(Form::LEADS_TYPE, $params);
LeadsModel::updateLeads($params);
} catch (Exception $e) {
$this->error($e->getMessage());
}
if ($result) {
$this->success('修改线索成功');
}
}
//删除线索
public function delLeads() {
$id = input('id');
$model = new LeadsModel();
$row = $model->where(['owner_staff_id' => $this->auth->id, 'id' => $id])->find();
if (empty($row)) {
$this->error('您没有权限删除线索');
}
if($row->owner_staff_id != $this->auth->id){
$this->error('您没有权限删除线索');
}
Db::startTrans();
try{
$model->where(['id' => $id])->delete();
$enentWhere = [
'relation_id' => $id,
'type' => 2,
'relation_type' => Event::LEADS_TYPE,
];
Event::where($enentWhere)->delete();
Db::commit();
}catch (Exception $e){
Db::rollback();
$this->error($e->getMessage());
}
$this->success('删除成功');
}
//获取附件列表
public function getFilesList() {
$id = input('leads_id');
$files = LeadsFile::where(['leads_id' => $id])->field('file_id')->with(['file'])->select();
$this->success('请求成功', $files);
}
}

199
addons/qingdong/controller/Leadspool.php

@ -0,0 +1,199 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Event;
use addons\qingdong\model\Leads as LeadsModel;
use addons\qingdong\model\LeadsFile;
use addons\qingdong\model\LeadsOther;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Record;
use think\Db;
use think\Exception;
/**
* 线索池接口
*/
class Leadspool extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
public function _initialize()
{
parent::_initialize();
try{
\think\Db::execute("SET @@sql_mode='';");
}catch (Exception $e){
}
}
//添加线索
public function addLeads() {
$params = $this->request->post();
if (empty($params['leads'])) {
$this->error('线索信息不能为空');
}
try {
$leadsId = LeadsModel::createLeads($params['leads'],1);
} catch (Exception $e) {
$this->error($e->getMessage());
}
if ($leadsId) {
$this->success('添加线索成功');
}
}
//获取线索列表
public function getList() {
$name = input('name', '', 'trim');
$mobile = input('mobile', '', 'trim');
$limit = input("limit/d", 10);
$params = $this->request->post();
$where = [];
if (isset($params['createtime']) && $params['createtime']) {//跟进状态
$createtime = $params['createtime'];
$createtime = explode(',', $createtime);
$where['createtime'] = ['between', [strtotime($createtime[0]), strtotime($createtime[1])+86400-1]];
}
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
if ($mobile) {
$where['mobile'] = ['like', "%{$mobile}%"];
}
$records = LeadsModel::where($where)->where('owner_staff_id is null or owner_staff_id = 0')->with(['createStaff'])->field('id,create_staff_id,name,follow,mobile,level,next_time,source')->order('id desc')->paginate($limit);
$this->success('请求成功', $records);
}
//获取线索详情
public function getDetail() {
$id = input('id', '', 'intval');
$leads = LeadsModel::where(['id' => $id])->with([
'createStaff',
])->find();
if(empty($leads)){
$this->error('信息不存在');
}
$leads=$leads->toArray();
$leads=LeadsOther::getOther($leads);
$this->success('请求成功', $leads);
}
//获取选择列表
public function getSelectList() {
$name = input('name','');
$where = ['owner_staff_id' => $this->auth->id,'is_transform'=>0];
if ($name) {
$where['name'] = ['like',"%$name%"];
}
$records = LeadsModel::where($where)->field('id,owner_staff_id,name,follow,mobile')->order('id desc')->select();
$this->success('请求成功', $records);
}
//转移线索
public function transfer()
{
$id = input('id');
$staff_id = input('staff_id');
if (!$staff_id && !$id) {
$this->error('参数错误');
}
$row = LeadsModel::where(['id' =>['in',$id] ])->find();
if (empty($row)) {
$this->error('线索不存在');
}
$id = explode(',',$id);
try {
LeadsModel::transfer($id, $staff_id);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success('转移成功');
}
//修改线索
public function editLeads() {
$id = input('id');
$params = $this->request->post();
$row = LeadsModel::where(['id' => $id])->find();
if (empty($row)) {
$this->error('线索信息不存在');
}
try {
$result = LeadsModel::updateLeads($params);
} catch (Exception $e) {
$this->error($e->getMessage());
}
if ($result) {
$this->success('修改线索成功');
}
}
//删除线索
public function delLeads() {
$id = input('id');
$model = new LeadsModel();
$row = $model->where(['id' => $id])->find();
if (empty($row)) {
$this->error('线索不存在');
}
Db::startTrans();
try{
$model->where(['id' => $id])->delete();
$enentWhere = [
'relation_id' => $id,
'type' => 2,
'relation_type' => Event::LEADS_TYPE,
];
Event::where($enentWhere)->delete();
Db::commit();
}catch (Exception $e){
Db::rollback();
$this->error($e->getMessage());
}
$this->success('删除成功');
}
//获取附件列表
public function getFilesList() {
$id = input('leads_id');
$files = LeadsFile::where(['leads_id' => $id])->field('file_id')->with(['file'])->select();
$this->success('请求成功', $files);
}
//领取线索
public function achieve()
{
$id = input('id');
if (empty($id)) {
$this->error('参数错误');
}
$row = LeadsModel::where(['id' =>$id ])->find();
if (empty($row)) {
$this->error('线索不存在');
}
try {
LeadsModel::transfer($id, $this->auth->id);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success('领取成功');
}
}

250
addons/qingdong/controller/Message.php

@ -0,0 +1,250 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Event;
use addons\qingdong\model\ExamineRecord;
use addons\qingdong\model\Message as MessageModel;
use addons\qingdong\model\Notice;
use addons\qingdong\model\ReceivablesPlan;
use addons\qingdong\model\Record;
/**
* 通知接口
*/
class Message extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = [];
/**
* 获取通知列表
*/
public function getList()
{
$limit = input("limit/d", 10);
$where = ['to_staff_id' => $this->auth->id ,'relation_type'=>['neq',MessageModel::EXAMINE_TYPE]];
$records = MessageModel::where($where)->with(['fromStaff', 'examine'])->order('status asc,id desc')->paginate($limit);
$this->success('请求成功', $records);
}
/**
* 获取审批列表
*/
public function getExamineRecord()
{
$limit = input("limit/d", 10);
//合同审批,回款审批、业绩目标审批、办公审批 费用
$relation_type = input('type');
$status = input('status',0);
if($status == 1){
$status = array('in','2,3');
}
$ids = ExamineRecord::where(['relation_type' => $relation_type,
'status' => $status,
'check_staff_id' => $this->auth->id])->column('id');
$where = ['to_staff_id' => $this->auth->id, 'relation_id' => ['in', $ids], 'relation_type' => MessageModel::EXAMINE_TYPE];
$records = MessageModel::where($where)->with(['fromStaff', 'examine'])->order('status asc,id desc')->paginate($limit);
$this->success('请求成功', $records);
}
/**
* 获取审批通知详情
*/
public function getExamineInfo()
{
$data = [
ExamineRecord::CONTRACT_TYPE => ['count' => 0, 'msg' => '暂无消息'],
ExamineRecord::CONSUME_TYPE => ['count' => 0, 'msg' => '暂无消息'],
ExamineRecord::RECEIVABLES_TYPE => ['count' => 0, 'msg' => '暂无消息'],
ExamineRecord::APPROVAL_TYPE => ['count' => 0, 'msg' => '暂无消息'],
ExamineRecord::ACHIEVEMENT_TYPE => ['count' => 0, 'msg' => '暂无消息'],
ExamineRecord::CARD_TYPE => ['count' => 0, 'msg' => '暂无消息'],
ExamineRecord::LEAVE_TYPE => ['count' => 0, 'msg' => '暂无消息'],
];
foreach ($data as $type=>$v) {
$ids = ExamineRecord::where(['status' => 0, 'check_staff_id' => $this->auth->id,
'relation_type' => $type
])->column('id');
$count = MessageModel::where(['to_staff_id' => $this->auth->id,'relation_id' => ['in', $ids],
'relation_type' => MessageModel::EXAMINE_TYPE])
->count();
if ($count) {
$msg = MessageModel::where(['to_staff_id' => $this->auth->id, 'relation_id' => ['in', $ids],
'relation_type' => MessageModel::EXAMINE_TYPE])
->order('id desc')
->value('content');
$data[$type] = ['count' => $count, 'msg' => $msg];
}
}
$this->success('请求成功', $data);
}
/**
* 获取通知详情
*/
public function getInfo()
{
$leadsCount = MessageModel::where(['to_staff_id' => $this->auth->id,
'relation_type' => ['neq', MessageModel::EXAMINE_TYPE], 'status' => 0])->count();
if ($leadsCount > 0) {//其他提醒消息
$leadsDetail = MessageModel::where([
'relation_type' => ['neq', MessageModel::EXAMINE_TYPE],
'to_staff_id' => $this->auth->id,
'status' => 0
])->order('id desc')->find();
}
$noticeWhere['read_staff_ids'] = ['not like', "%,{$this->auth->id},%"];
$noticeCount = Notice::where($noticeWhere)->count();
if ($noticeCount > 0) {
$noticeDetail = Notice::where(['read_staff_ids' => ['not like', "%,{$this->auth->id},%"]])->order('id desc')->find();
}
$eventOne = Event::where([
'type' => 1,
'status' => ['in', [0, 1]],
'start_time' => ['lt', date('Y-m-d', strtotime('+1 day'))],
'staff_id|owner_staff_id' => $this->auth->id
])->count();
//合同审批
$contract = ExamineRecord::where([
'relation_type' => ExamineRecord::CONTRACT_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//回款审批
$receivables = ExamineRecord::where([
'relation_type' => ExamineRecord::RECEIVABLES_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//费用审批
$consume = ExamineRecord::where([
'relation_type' => ExamineRecord::CONSUME_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//业绩目标审批
$achievement = ExamineRecord::where([
'relation_type' => ExamineRecord::ACHIEVEMENT_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//办公审批
$approval = ExamineRecord::where([
'relation_type' => ExamineRecord::APPROVAL_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//补卡审批
$card = ExamineRecord::where([
'relation_type' => ExamineRecord::CARD_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
//请假审批
$leave = ExamineRecord::where([
'relation_type' => ExamineRecord::LEAVE_TYPE,
'status' => 0,
'check_staff_id' => $this->auth->id
])->count();
$receivablesPlan = ReceivablesPlan::where([
'remind_date' => ['elt', date('Y-m-d')],
'status' => 0,
'owner_staff_id' => $this->auth->id
])->count();
$eventsCount = Event::where([
'start_time' => ['lt', date('Y-m-d', strtotime('+1 day'))],
'end_time' => ['lt', date('Y-m-d', strtotime('+1 day'))],
'status' => ['in', [0, 1]],
'staff_id' => $this->auth->id,
])->count();
$where['create_staff_id'] = $this->auth->id;
$where['next_time'] = array(array('egt',date('Y-m-d 00:00:00')),array('lt',date('Y-m-d 23:59:59')));
$where['follow_type'] = ['neq', '其它'];
$where['status'] = 0;
// 待跟进客户
$where1['relation_type'] = 1;
$customerlist = Record::where($where)->where($where1)->column('id');
$customerlist1 = 0;
if($customerlist){
$whereExit['id'] = array('in',$customerlist);
$whereExit['next_time'] = array('gt',date('Y-m-d 23:59:59'));
$customerlist1 = Record::where($whereExit)->count();
}
$customer = count($customerlist) - $customerlist1;
//待跟进合同
$where2['relation_type'] = 3;
$contractlist = Record::where($where)->where($where2)->column('id');
$contractlist1 = 0;
if($contractlist){
$whereExitC['id'] = array('in',$contractlist);
$whereExitC['next_time'] = array('gt',date('Y-m-d 23:59:59'));
$contractlist1 = Record::where($whereExitC)->count();
}
$contracts = count($contractlist)-$contractlist1;
//待跟进线索
$where3['relation_type'] = 4;
$leadlist = Record::where($where)->where($where3)->column('id');
$leadlist1 = 0;
if($leadlist){
$whereExitL['id'] = array('in',$leadlist);
$whereExitL['next_time'] = array('gt',date('Y-m-d 23:59:59'));
$leadlist1 = Record::where($whereExitL)->count();
}
$lead = count($leadlist)-$leadlist1;
//待跟进联系人
$where4['relation_type'] = 2;
$contactslist = Record::where($where)->where($where4)->column('id');
$contactslist1 = 0;
if($contactslist1){
$whereExitCs['id'] = array('in',$contactslist);
$whereExitCs['next_time'] = array('gt',date('Y-m-d 23:59:59'));
$contactslist1 = Record::where($whereExitCs)->count();
}
$contacts = count($contactslist)-$contactslist1;
//待跟进商机
$where5['relation_type'] = 5;
$businesslist = Record::where($where)->where($where5)->column('id');
$businesslist1 = 0;
if($businesslist1){
$whereExitB['id'] = array('in',$businesslist);
$whereExitB['next_time'] = array('gt',date('Y-m-d 23:59:59'));
$businesslist1 = Record::where($whereExitB)->count();
}
$business = count($businesslist)-$businesslist1;
//提醒消息
$data = [
'leads' => ['count' => $leadsCount, 'msg' => $leadsDetail['content'] ?? '暂无消息'],//提醒消息
'examine' => ['count' => $contract + $receivables+$consume+$achievement+$approval+$card+$leave,
'msg' => '审批消息提醒'],//提醒消息
'notice' => ['count' => $noticeCount, 'msg' => $noticeDetail['title'] ?? '暂无消息'],//系统公告
'agent' => [
'count' => $eventOne + $receivablesPlan+ $customer + $contracts + $lead + $contacts + $business,
'msg' => '您有新的待办事项需要处理!'
],//待办事项
'task' => [
'count' => $eventsCount,
'msg' => '即将超时的任务提醒!'
],//超时任务
'total' => $leadsCount + $noticeCount + $eventOne + $contract + $receivables + $receivablesPlan + $eventsCount+ $customer + $contracts + $lead + $contacts + $business+$consume+$achievement+$approval+$card+$leave,
'userinfo' => $this->auth->getUserinfo()
];
$this->success('请求成功', $data);
}
}

52
addons/qingdong/controller/Notice.php

@ -0,0 +1,52 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Notice as NoticeModel;
/**
* 公告接口
*/
class Notice extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//公告列表
public function getList() {
$limit = input("limit/d", 10);
$records = NoticeModel::where([])->order('id desc')->paginate($limit);
$items = $records->items();
foreach ($items as $k => $v) {
$read_staff_ids = explode(',', $v['read_staff_ids']);
$v['is_show'] = in_array($this->auth->id, $read_staff_ids);
$items[$k] = $v;
}
$this->success('请求成功', $records);
}
//获取公告详情
public function getDetail() {
$id = input('id', '', 'intval');
$notice = NoticeModel::where(['id' => $id,])->find();
if (empty($notice)) {
$this->error('公告不存在');
}
preg_match_all('/<img.+src=\"?(.+\.(jpg|gif|bmp|bnp|png))\"?.+>/i',$notice['content'],$match);
foreach ($match[1] as $v){
$notice['content']=str_replace($v,cdnurl($v,true),$notice['content']);
}
$read_staff_ids = explode(',', $notice['read_staff_ids']);
if (!in_array($this->auth->id, $read_staff_ids)) {
$read_staff_ids[] = $this->auth->id;
NoticeModel::where(['id' => $notice['id']])->update(['read_staff_ids' => implode(',', $read_staff_ids).',']);
}
$this->success('请求成功', $notice);
}
}

29
addons/qingdong/controller/Operation.php

@ -0,0 +1,29 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\OperationLog;
/**
* 操作记录
*/
class Operation extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//
public function getList() {
$relation_type = input('relation_type', '');//1客户 2联系人 3合同
$relation_id = input('relation_id', '');
if(empty($relation_type) || empty($relation_id)){
$this->error('参数不能为空');
}
//操作记录
$logs=OperationLog::where([
'relation_type' => $relation_type,
'relation_id' => $relation_id,
'operation_type' => 1
])->field('id,content,operation_id,createtime')->with(['staff'])->select();
$this->success('请求成功',$logs);
}
}

156
addons/qingdong/controller/Product.php

@ -0,0 +1,156 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Product as ProductModel;
use addons\qingdong\model\ProductPart;
use addons\qingdong\model\Producttype;
/**
* 产品
*/
class Product extends StaffApi
{
protected $noNeedLogin = [];
protected $noNeedRight = [];
/**
* 获取select产品列表
*/
public function getSelectList()
{
$name = input('name');
$type_id = input('type_id');
$where = [];
if ($name) {
$where['name|num'] = ['like', "%{$name}%"];
}
if ($type_id) {
$where['type_id'] = $type_id;
}
$list = ProductModel::where($where)->field('id,name,type,num,img,unit,price,min_price,status,cost_price,wholesale')->select();
$this->success('请求成功', $list);
}
/**
* 获取产品分类列表
*/
public function getProducttypeList()
{
$name = input('name');
$where=[];
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
$list = Producttype::where($where)->field('id,name')->select();
$this->success('请求成功', $list);
}
/**
* 获取产品配置列表
*/
public function getPartList()
{
$product_id = input('product_id');
$name = input('name');
$where = [];
if ($name) {
$where['name'] = ['like', "%{$name}%"];
}
$where['product_id'] = $product_id;
$list = ProductPart::where($where)->field('id,name,img,description')->select();
$this->success('请求成功', $list);
}
/**
* 获取产品详情
*/
public function getProductDetail()
{
$id = input('id');
$product = ProductModel::where(['id' => $id])->find();
if (empty($product)) {
$this->error('产品不存在');
}
preg_match_all("/(<img .*?src=\")(.*?)(\".*?>)/is", $product['description'], $matchpic);
foreach ($matchpic[2] as $url) {
$img = cdnurl($url, true);
$product['description'] = str_replace($url, $img, $product['description']);
}
$this->success('请求成功', $product);
}
/**
* 添加产品
*/
public function addProduct()
{
$params = $this->request->post();
if ($params) {
$parts = $params['parts'] ?? [];
$model = new ProductModel();
$model->allowField(true)->save($params);
$lastid = $model->getLastInsID();
$partModel = new ProductPart();
foreach ($parts as &$v) {
$v['product_id'] = $lastid;
}
$partModel->allowField(true)->saveAll($parts);
$this->success('添加产品成功');
}
}
/**
* 添加产品配件
*/
public function addProductPart()
{
$params = $this->request->post();
if ($params) {
$partModel = new ProductPart();
$partModel->save($params);
$this->success('添加产品配置成功');
}
}
/**
* 修改产品信息
*/
public function editProduct()
{
$params = $this->request->post();
if ($params) {
$model = new ProductModel();
$row = $model->get($params['id']);
if (empty($row)) {
$this->error('产品不存在');
}
$row->allowField(true)->save($params);
$this->success('添加产品成功');
}
}
/**
* 修改产品配件
*/
public function editProductPart()
{
$params = $this->request->post();
if ($params) {
$partModel = new ProductPart();
$row = $partModel->get($params['id']);
if (empty($row)) {
$this->error('产品配置不存在');
}
$row->allowField(true)->save($params);
$this->success('修改产品配置成功');
}
}
}

207
addons/qingdong/controller/Receivables.php

@ -0,0 +1,207 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\ExamineRecord;
use addons\qingdong\model\FormField;
use addons\qingdong\model\Message;
use addons\qingdong\model\Receivables as ReceivablesModel;
use addons\qingdong\model\ReceivablesOther;
use addons\qingdong\model\Contract;
use addons\qingdong\model\Staff;
use think\Db;
use think\Exception;
/**
* 回款详情
*/
class Receivables extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//新增回款
public function addReceivables() {
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::RECEIVABLES_TYPE, $params);
if ($result !== true) {
$this->error($result);
}
if (ReceivablesModel::where(['number' => $params['number'], 'contract_id' => $params['contract_id']])->find()) {
$this->error('回款编号已存在');
}
$contract=Contract::where(['id'=>$params['contract_id']])->find();
if(empty($contract)){
$this->error('合同不存在');
}
if($contract['check_status'] != 2){
$this->error('当前合同未审核通过');
}
Db::startTrans();
try {
$params['owner_staff_id'] = $contract['owner_staff_id'];
ReceivablesModel::createReceivables($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('新增回款成功');
}
}
//获取回款列表
public function getList()
{
$customer_id = input('customer_id');
$contract_id = input('contract_id');
$times = input('times');
$staff_id = input('staff_id');
$check_status = input('check_status');
$limit = input('limit');
$type = input('type',0);
$params=input();
$where= FormField::updateWhereField(FormField::RECEIVABLES_TYPE,$params);
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
if ($contract_id) {
$where['contract_id'] = $contract_id;
}
if ($staff_id) {
$where['owner_staff_id'] = $staff_id;
} else {
if ($type == 1) {//我的客户
$where['owner_staff_id'] = $this->auth->id;
} elseif ($type == 2) {//下属负责的客户
$where['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
}else{
$where['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
}
}
if ($times) {//回款日期
$times = explode(',', $times);
$where['return_time'] = ['between', [$times[0], $times[1]]];
}
if ($check_status) {
if ($check_status == 1) {//审核中
$where['check_status'] = ['in', [0, 1]];
} elseif ($check_status == 2) {//审核通过
$where['check_status'] = 2;
} elseif ($check_status == 3) {//其他
$where['check_status'] = ['in', [3, 4]];
}
}
$list = ReceivablesModel::where($where)->with(['contract'])->order('id desc')->paginate($limit)->toArray();
$remoney = ReceivablesModel::where(['owner_staff_id'=>$where['owner_staff_id']])
->where(array('check_status'=>2))->sum('money');
$inmoney = ReceivablesModel::where(['owner_staff_id'=>$where['owner_staff_id']])
->where(array('check_status'=>['in',[0,1]]))->sum('money');
$nomoney = ReceivablesModel::where(['owner_staff_id'=>$where['owner_staff_id']])
->where(array('check_status'=>['in',[3,4]]))->sum('money');
$moneyinfo['remoney'] = $remoney;//已回款
$moneyinfo['inmoney'] = $inmoney;//回款中
$moneyinfo['nomoney'] = $nomoney;//未回款
$moneyinfo['allmoney'] = $remoney+$inmoney+$nomoney;//总金额
$list['moneyinfo']=$moneyinfo;
$this->success('请求成功',$list);
}
//回款详情
public function getDetail() {
$id = input('id');
$receivables = ReceivablesModel::where(['id' => $id])->with([
'customer',
'contract',
'plan',
'ownerStaff',
'createStaff'
])->find();
if (empty($receivables)) {
//标记通知已读
Message::setRead(Message::RECEIVABLES_TYPE, $id, $this->auth->id);
$this->error('信息不存在');
}
$receivables=$receivables->toArray();
$receivables=ReceivablesOther::getOther($receivables);
//标记通知已读
Message::setRead(Message::RECEIVABLES_TYPE, $id, $this->auth->id);
$this->success('请求成功', $receivables);
}
//撤回审核
public function cancel() {
$id = input('id');
$customer = ReceivablesModel::where(['id' => $id, 'check_status' => 1])->find();
if (empty($customer)) {
$this->error('回款信息不存在');
}
Db::startTrans();
try {
ReceivablesModel::where(['id' => $id])->update(['check_status' => 4]);
ExamineRecord::where([
'relation_type' => ExamineRecord::RECEIVABLES_TYPE,
'relation_id' => $id,
'status' => 0
])->update(['status' => 3]);
Db::commit();
} catch (Exception $e) {
Db::rollback();;
$this->error($e->getMessage());
}
$this->success('撤回成功');
}
//修改回款
public function editReceivables() {
$id = input('id');
$params = $this->request->post();
$row = ReceivablesModel::where(['id' => $id, 'check_status' => ['in', [3, 4]]])->find();
if (empty($row)) {
$this->error('回款信息不存在');
}
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
$result = FormField::checkFields(FormField::RECEIVABLES_TYPE, $params,$id);
if ($result !== true) {
$this->error($result);
}
Db::startTrans();
try {
ReceivablesModel::updateReceivables($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('修改回款信息成功');
}
//获取回款编号
public function getReceivablesNumber()
{
$this->success('请求成功', ['number' => ReceivablesModel::getNum()]);
}
}

112
addons/qingdong/controller/ReceivablesPlan.php

@ -0,0 +1,112 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Message;
use addons\qingdong\model\ReceivablesPlan as ReceivablesPlanModel;
use addons\qingdong\model\Staff;
use think\Db;
use think\Exception;
/**
* 回款计划
*/
class ReceivablesPlan extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
//新增回款计划
public function addPlan() {
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
if (ReceivablesPlanModel::where([
'num' => $params['num'],
'contract_id' => $params['contract_id']
])->find()) {
$this->error('计划回款期数已存在');
}
Db::startTrans();
try {
ReceivablesPlanModel::createPlan($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('新增回款计划成功');
}
}
//获取回款计划列表
public function getList()
{
$customer_id = input('customer_id');
$contract_id = input('contract_id');
$times = input('times');
$staff_id = input('staff_id');
$status = input('status', null);
$limit = input('limit');
$type = input('type',0);
$where = [];
if ($customer_id) {
$where['customer_id'] = $customer_id;
}
if ($contract_id) {
$where['contract_id'] = $contract_id;
}
if ($staff_id) {
$where['owner_staff_id'] = $staff_id;
} else {
if ($type == 1) {//我的客户
$where['owner_staff_id'] = $this->auth->id;
} elseif ($type == 2) {//下属负责的客户
$where['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
}else{
$where['owner_staff_id'] = ['in', Staff::getMyStaffIds()];
}
}
if ($times) {//计划回款日期
$times = explode(',', $times);
$where['return_date'] = ['between', [$times[0], $times[1]]];
}
if($status !== null){
$where['status'] = $status;
}
$list = ReceivablesPlanModel::where($where)->with(['contract', 'customer', 'createStaff'])
->order('id desc')->paginate($limit);
$this->success('请求成功', $list);
}
//获取select回款计划列表
public function getSelectList() {
$contract_id = input('contract_id');
$where = [];
$where['contract_id'] = $contract_id;
$where['status'] = 0;
$list = ReceivablesPlanModel::where($where)->field('id,num')->select();
$this->success('请求成功', $list);
}
//回款详情
public function getDetail() {
$id = input('id');
$customer = ReceivablesPlanModel::where(['id' => $id])->with(['contract', 'customer', 'createStaff'])->find();
//标记通知已读
Message::setRead(Message::PLAN_TYPE, $id, $this->auth->id);
$this->success('请求成功', $customer);
}
}

368
addons/qingdong/controller/Record.php

@ -0,0 +1,368 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Comment;
use addons\qingdong\model\Contacts;
use addons\qingdong\model\Message;
use addons\qingdong\model\Record as RecordModel;
use addons\qingdong\model\RecordRead;
use addons\qingdong\model\Customer;
use addons\qingdong\model\Contract;
use addons\qingdong\model\Leads;
use addons\qingdong\model\Staff;
use addons\qingdong\model\Business;
use think\Db;
use think\Exception;
use function EasyWeChat\Kernel\Support\get_client_ip;
/**
* 跟进记录
*/
class Record extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
/**
* 获取跟进记录
*/
public function getList() {
$relation_type = input('relation_type', '', 'intval');// 1客户 2联系人 3合同 5商机
$relation_id = input('relation_id', '', 'intval');
$limit = input("limit/d", 10);
$is_read = input('is_read', 0);
$type = input('type', 0);// 0 全部 1 我创建 2 下属创建
$follow_type = input('follow_type', '');
$times = input('times','');
$where = [];
if ($relation_type) {
$where['relation_type'] = $relation_type;
if($relation_id){
$where['relation_id'] = $relation_id;
}
}
if ($type == 1) {//我的客户
$where['create_staff_id'] = $this->auth->id;
} elseif ($type == 2) {//下属负责的客户
$where['create_staff_id'] = ['in', Staff::getLowerStaffId()];
}else{
$where['create_staff_id'] = ['in', Staff::getMyStaffIds()];
}
if($follow_type){
$where['follow_type'] = $follow_type;
}else{
$where['follow_type'] = ['neq', '其它'];
}
if ($times) {
$times = explode(',', $times);
$where['createtime'] = ['between', [strtotime($times[0]), strtotime($times[1]) + 86400 - 1]];
}
$staff_id = $this->auth->id;
if ($is_read == 1) {//已读
$ids = RecordRead::where(['staff_id' => $staff_id])->column('record_id');
$where['id'] = ['in', $ids];
} elseif ($is_read == 2) {//未读
$ids = RecordRead::where(['staff_id' => $staff_id])->column('record_id');
$where['id'] = ['not in', $ids];
}
$records = RecordModel::where($where)->with([
'staff',
'file',
'read' => function ($query) use ($staff_id) {
$query->where(['staff_id' => $staff_id]);
}
])->order('id desc')->paginate($limit)->toArray();
$data = $records['data'];
foreach ($data as $k => $v) {
$customerWhere['id'] = $v['relation_id']?? '';
$v['comment_num'] =0;//评论数
if($v['relation_type'] == RecordModel::CUSTOMER_TYPE) {
$v['comment_num'] =Comment::where(array('relation_type'=>1,'relation_id'=>$v['id']))->count();
$v['relation_name'] = Customer::where(['id' => $v['relation_id']])->value('name');
}elseif($v['relation_type'] == RecordModel::CONTACTS_TYPE) {
$v['comment_num'] =Comment::where(array('relation_type'=>2,'relation_id'=>$v['id']))->count();
$v['relation_name'] = Contacts::where(['id' => $v['relation_id']])->value('name');
}elseif($v['relation_type'] == RecordModel::CONTRACT_TYPE) {
$v['comment_num'] =Comment::where(array('relation_type'=>3,'relation_id'=>$v['id']))->count();
$v['relation_name'] = Contract::where(['id' => $v['relation_id']])->value('name');
}elseif($v['relation_type'] == RecordModel::LEADS_TYPE) {
$v['comment_num'] =Comment::where(array('relation_type'=>4,'relation_id'=>$v['id']))->count();
$v['relation_name'] = Leads::where(['id' => $v['relation_id']])->value('name');
} elseif($v['relation_type'] == RecordModel::BUSINESS_TYPE) {
$v['comment_num'] =Comment::where(array('relation_type'=>5,'relation_id'=>$v['id']))->count();
$v['relation_name'] = Business::where(['id' => $v['relation_id']])->value('name');
}else{
$v['customer'] = [];
}
if (!empty($v['read'])) {
$v['is_read'] = 1;
} else {
$v['is_read'] = 0;
}
if($v['staff_id']){
$v['staff'] = Staff::where(['id'=>$v['staff_id']])->field('id,img,name,post')->find();
}
$data[$k] = $v;
}
$this->success('请求成功', [
'total' => $records['total'],
'per_page' => $records['per_page'],
'current_page' => $records['current_page'],
'last_page' => $records['last_page'],
'data' => $data
]);
$this->success('请求成功', $records);
}
/**
* 创建跟进记录
*/
public function createRecord() {
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
Db::startTrans();
try {
$result = RecordModel::createRecord($params);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result) {
$this->success('创建跟进记录成功');
}
}
/**
* 获取根据记录详情
*/
public function getRecordDetail() {
$id = input('id');
if (empty($id)) {
$this->error('参数不能为空');
}
$record = RecordModel::where(['id' => $id])->with([
'staff',
'file'
])->find();
if (empty($record)) {
$this->error('根据记录不存在');
}
$record = $record->toArray();
if ($record['relation_type'] == RecordModel::CUSTOMER_TYPE) {
$record['relation_name'] = Customer::where(['id' => $record['relation_id']])->value('name');
} elseif ($record['relation_type'] == RecordModel::CONTACTS_TYPE) {
$record['relation_name'] = Contacts::where(['id' => $record['relation_id']])->value('name');
} elseif ($record['relation_type'] == RecordModel::CONTRACT_TYPE) {
$record['relation_name'] = Contract::where(['id' => $record['relation_id']])->value('name');
} elseif($record['relation_type'] == RecordModel::LEADS_TYPE) {
$record['relation_name'] = Leads::where(['id' => $record['relation_id']])->value('name');
} elseif($record['relation_type'] == RecordModel::BUSINESS_TYPE) {
$record['relation_name'] = Business::where(['id' => $record['relation_id']])->value('name');
}else{
$record['relation_name']='';
}
$reminds_id = $record['reminds_id'];
$reminds_id = explode(',', $reminds_id);
$names = Staff::where(['id' => ['in', $reminds_id]])->column('name');
$record['staff_name'] = implode(',', $names);
if($record['staff_id']){
$record['staff'] = Staff::where(['id'=>$record['staff_id']])->field('id,img,name,post')->find();
}
//标记通知已读
Message::setRead(Message::RECORD_TYPE, $id, $this->auth->id);
//添加阅读记录
RecordRead::addRead($id, $this->auth->id);
$this->success('请求成功', $record);
}
/**
* 添加评论
*/
public function addComment() {
$content = input('content');
$record_id = input('record_id');
$relation_type = input('relation_type');
if (empty($content)) {
$this->error('评论内容不能为空');
}
$data = [
'relation_type' => $relation_type,
'relation_id' => $record_id,
'staff_id' => $this->auth->id,
'content' => $content,
'status' => 1,
'ip' => get_client_ip(),
];
$commentModel = new Comment();
$commentModel->save($data);
$record = RecordModel::get($record_id);
Message::addMessage(Message::COMMENT_TYPE,$record_id,$record['create_staff_id'],$this->auth->id);
$staff_ids=$commentModel->where(['relation_type'=>$relation_type,'relation_id'=>$record_id])->group('staff_id')->column('staff_id');
foreach ($staff_ids as $staff_id) {
//发送通知
if($staff_id != $this->auth->id){
Message::addMessage(Message::COMMENT_TYPE,$record_id,$staff_id,$this->auth->id);
}
}
$this->success('评论成功');
}
/**
* 评论列表
*/
public function commentList() {
$record_id = input('record_id');
$relation_type = input('relation_type');
$comments = Comment::where([
'relation_type' => $relation_type,
'relation_id' => $record_id,
'status' => 1
])->field('id,staff_id,content,createtime')->with(['staff'])->select();
$this->success('请求成功', $comments);
}
/**
* 获取跟进客户
*/
public function getcustomerList() {
$limit = input("limit/d", 10);
$time = input('time', 0);
$type = input('type', 1);
$where['create_staff_id'] = $this->auth->id;
if($type == 6){
$where['relation_type'] = 3;
}elseif($type == 7){
$where['relation_type'] = 4;
}elseif($type == 8){
$where['relation_type'] = 2;
}elseif($type == 9){
$where['relation_type'] = 5;
}else{
$where['relation_type'] = 1;
}
$where['follow_type'] = ['neq', '其它'];
$staff_id = $this->auth->id;
if ($time == 1) {//7天
$where['next_time'] = array(array('egt',date('Y-m-d', strtotime('-7 day'))),array('lt',date('Y-m-d', strtotime('+1 day'))));
} elseif ($time == 2) {//14天
$where['next_time'] = array(array('egt',date('Y-m-d', strtotime('-14 day'))),array('lt',date('Y-m-d', strtotime('+1 day'))));
}elseif($time == 3){
$where['next_time'] = array(array('egt',date('Y-m-d', strtotime('-30 day'))),array('lt',date('Y-m-d', strtotime('+1 day'))));
}elseif($time == 4){ //今日
$where['next_time'] = array(array('egt',date('Y-m-d 00:00:00')),array('elt',date('Y-m-d 23:59:59')));
}
$where['status'] = 0;
$records = RecordModel::where($where)->with([
'staff',
'file',
'read' => function ($query) use ($staff_id) {
$query->where(['staff_id' => $staff_id]);
}
])->order('id desc')->paginate($limit)->toArray();
$data = $records['data'];
foreach ($data as $k => $v) {
$customerWhere['id'] = $v['relation_id']?? '';
if($type == 6){
//合同
$v['customer'] = Contract::where($customerWhere)->find();
}elseif($type == 7){
//线索
$v['customer'] = Leads::where($customerWhere)->find();
}elseif($type == 8){
//联系人
$v['customer'] = Contacts::where($customerWhere)->find();
}elseif($type == 9){
//商机
$v['customer'] = Business::where($customerWhere)->find();
}
else{
$v['customer'] = Customer::where($customerWhere)->find();
}
if (!empty($v['read'])) {
$v['is_read'] = 1;
} else {
$v['is_read'] = 0;
}
$data[$k] = $v;
}
$this->success('请求成功', [
'total' => $records['total'],
'per_page' => $records['per_page'],
'current_page' => $records['current_page'],
'last_page' => $records['last_page'],
'data' => $data
]);
$this->success('请求成功', $records);
}
/*
*待办跟进
*/
public function record_add(){
$type = input('type',0);
$content = input('remarks');
$record_id = input('record_id');
$relation_type = input('relation_type');
if (empty($content)) {
$this->error('备注不能为空');
}
$data = [
'relation_type' => $relation_type,
'relation_id' => $record_id,
'staff_id' => $this->auth->id,
'content' => $content,
'status' => 1,
'ip' => get_client_ip(),
];
Db::startTrans();
$commentModel = new Comment();
$resultC = $commentModel->save($data);
$recordU = RecordModel::where(array('id'=>$record_id))->update(array('status'=>1,'updatetime'=>time()));
$resultR= true;
if($type ==1){
$params = $this->request->post();
// 表单验证
if (($result = $this->qingdongValidate($params, get_class(), 'create')) !== true) {
$this->error($result);
}
try {
unset($params['type']);
unset($params['remarks']);
unset($params['record_id']);
$resultR = RecordModel::createRecord($params);
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
}
if(!$resultC || !$resultR || !$recordU){
Db::rollback();
$this->error('跟进失败');
}
Db::commit();
$this->success('跟进成功');
}
}

103
addons/qingdong/controller/Setting.php

@ -0,0 +1,103 @@
<?php
// +----------------------------------------------------------------------
// | Description: 客户模块设置
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace addons\qingdong\controller;
use addons\qingdong\model\Customer;
use addons\qingdong\model\Staff;
/**
* 客户模块设置
*/
class Setting extends StaffApi
{
/**
* 获取团队成员
*/
public function team()
{
$id = input('id');
$customer = Customer::get($id);
if (empty($customer)) {
$this->error('客户不存在');
}
$owner_staff = Staff::where(['id' => $customer->owner_staff_id])->find();
$rw_staffs = Staff::where(['id' => ['in', explode(',', $customer->rw_staff_id)]])->select();
$ro_staffs = Staff::where(['id' => ['in', explode(',', $customer->ro_staff_id)]])->select();
$staffs = [];
if ($owner_staff) {
$staffs[] = [
'id' => $owner_staff->id,
'name' => $owner_staff->name,
'img' => $owner_staff->img,
'post' => $owner_staff->post,
'mobile' => $owner_staff->mobile,
'roles' => 1,
'is_edit' => 1,
];
}
foreach ($rw_staffs as $v) {
$staffs[] = [
'id' => $v->id,
'name' => $v->name,
'img' => $v->img,
'post' => $v->post,
'mobile' => $v->mobile,
'roles' => 2,
'is_edit' => 1,
];
}
foreach ($ro_staffs as $v) {
$staffs[] = [
'id' => $v->id,
'name' => $v->name,
'img' => $v->img,
'post' => $v->post,
'mobile' => $v->mobile,
'roles' => 2,
'is_edit' => 0,
];
}
$this->success('请求成功', $staffs);
}
/**
* 修改团队成员
*/
public function editShowStaff()
{
$id = input('id');
$staff = input('staff/a');
$model = Customer::get($id);
if (empty($model)) {
$this->error('客户不存在');
}
$ro_staff_id = [];
$rw_staff_id = [];
foreach ($staff as $v) {
if ($v['is_edit'] == 1) {
$rw_staff_id[] = $v['id'];
} else {
$ro_staff_id[] = $v['id'];
}
}
$ro_staff_id = array_diff($ro_staff_id, $rw_staff_id);
$rw_staff_id=implode(',', $rw_staff_id);
$ro_staff_id=implode(',', $ro_staff_id);
$result = $model->save(['rw_staff_id' => ",{$rw_staff_id},",
'ro_staff_id' => ",{$ro_staff_id},"]);
if ($result === false) {
$this->error('修改失败');
}
$this->success('修改成功');
}
}

595
addons/qingdong/controller/Staff.php

@ -0,0 +1,595 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Contacts;
use addons\qingdong\model\Contract;
use addons\qingdong\model\Customer;
use addons\qingdong\model\Flow;
use addons\qingdong\model\Leads;
use addons\qingdong\model\Receivables;
use addons\qingdong\model\Remind;
use addons\qingdong\model\Staff as StaffModel;
use addons\qingdong\model\StaffDepartment;
use addons\qingdong\library\Wechat;
use addons\qingdong\model\Achievement;
use addons\qingdong\model\Record;
use fast\Http;
use think\Exception;
use think\Log;
use think\Validate;
/**
* * 操作文档:https://doc.fastadmin.net/qingdong
* 软件介绍:https://www.fastadmin.net/store/qingdong.html
* 售后微信:qingdong_crm
* 员工登录 注册接口
*/
class Staff extends StaffApi
{
protected $noNeedLogin = ['test', 'wxLogin', 'login','logintest'];
protected $noNeedRight = ['getInfo', 'editInfo', "use_phone"];
public function _initialize()
{
parent::_initialize();
}
//是否登录
public function isLogin()
{
$this->success('已登录', ['userinfo' => $this->auth->getUserinfo()]);
}
/**
* 会员登录
*
* @ApiMethod (POST)
* @param string $account 账号
* @param string $password 密码
*/
public function login()
{
$account = $this->request->post('account');
$password = $this->request->post('password');
if (!$account || !$password) {
$this->error(__('Invalid parameters'));
}
$ret = $this->auth->login($account, $password);
if ($ret) {
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Logged in successful'), $data);
} else {
$this->error($this->auth->getError());
}
}
//获取个人基本信息
public function getInfo()
{
$staff = StaffModel::where(['id' => $this->auth->id])->with(['department', 'parent'])->find();
$group_ids=explode(',',$staff['group_ids']);
$staff['role_type'] = 1;//基础和团队
if (in_array(1, $group_ids)) {//超级管理员
$staff['role_type'] = 9;
}
$this->success('请求成功', $staff);
}
//员工绑定信息
public function staffBind(){
$staff=StaffModel::get($this->auth->id);
$data=[
'is_bind_wechat'=>$staff['openid']?1:($staff['wx_openid']?1:0)
];
$this->success('请求成功',$data);
}
//绑定微信
public function wechatBind(){
$type=input('type');//applet小程序 web 网页授权
$code = input('code');
if($type == 'web'){
$wechat = new Wechat('wxOfficialAccount');
if(empty($wechat->config['app_id'])){
$this->error('微信公众号appid未设置');
}
if(empty($wechat->config['secret'])){
$this->error('微信公众号secret未设置');
}
$decryptSession = $wechat->getOfficialAccessToken($code);
if (isset($decryptSession['errcode']) && $decryptSession['errcode'] != 0) {
$this->error(__('解析失败!'));
}
$openid = $decryptSession['openid'];
$unionid = $decryptSession['unionid'] ?? '';
Log::info(json_encode($decryptSession,JSON_UNESCAPED_UNICODE));
//判断用户是否存在
$staff = StaffModel::where(['wx_openid' => $openid])->find();
if($staff){
$this->error('该微信号已绑定账号');
}
$staffModel=new StaffModel();
$result=$staffModel->save(['wx_openid'=>$openid,'unionid'=>$unionid],['id'=>$this->auth->id]);
if($result){
$this->success('绑定成功');
}
$this->error('绑定失败');
}elseif($type == 'applet'){
$wechat = new Wechat('wxMiniProgram');
if(empty($wechat->config['app_id'])){
$this->error('微信小程序appid未设置');
}
if(empty($wechat->config['secret'])){
$this->error('微信小程序secret未设置');
}
$decryptSession = $wechat->code($code);
if (isset($decryptSession['errcode']) && $decryptSession['errcode'] != 0) {
$this->error(__('解析失败!'));
}
$openid = $decryptSession['openid'];
$unionid = $decryptSession['unionid'] ?? '';
//判断用户是否存在
$staff = StaffModel::where(['openid' => $openid])->find();
if($staff){
$this->error('该微信号已绑定账号');
}
$staffModel=new StaffModel();
$result=$staffModel->save(['openid'=>$openid,'unionid'=>$unionid],['id'=>$this->auth->id]);
if($result){
$this->success('绑定成功');
}
$this->error('绑定失败');
}
}
//解绑微信
public function unboundWechat()
{
$staffId = $this->auth->id;
$model = new StaffModel();
$staff = $model->where(['id' => $staffId])->find();
if (empty($staff)) {
$this->error('员工不存在');
}
if ($model->isUpdate(true)->save(['id' => $staffId, 'wx_openid' => null,
'unionid' => null, 'openid' => null])) {
$this->success('解绑微信成功');
}
$this->error('操作失败');
}
//修改个人基本信息
public function editInfo()
{
$name = input('name');
$img = input('img');
$email = input('email');
$sex = input('sex');
$num = input('num');
$post = input('post');
$mobile = input('mobile');
$staffs = StaffModel::where(array('id' => $this->auth->id))->find();
$staffs->mobile = $mobile;
$staffs->img = $img;
$staffs->email = $email;
$staffs->sex = $sex;
$staffs->num = $num;
$staffs->post = $post;
$staffs->updatetime = time();
$result = $staffs->save();
if (!$result) {
$this->error('修改失败');
}
$this->success('修改成功');
}
//授权手机号
public function use_phone()
{
$code = $this->request->post('code','',null);
$encryptedData = $this->request->post('encryptedData','',null);
$iv = $this->request->post('iv','',null);
$config = new Wechat('wxMiniProgram');
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $config->config['app_id'] . "&secret=" . $config->config['secret'] . "&js_code=" . $code . "&grant_type=authorization_code";
$user = curl_getinfo($url);
$arr = json_decode($user, true);
if (isset($arr['errcode']) && $arr['errcode'] != 0) {
$this->error('操作失败!');
}
if (!isset($arr['openid']) || !isset($arr['session_key'])) {
$this->error('授权失败,请重新授权!');
}
$openId = $arr['openid'];
$pc = new Wxbizdatacrypt($config->config['app_id'], $arr['session_key']);
$errCode = $pc->decryptData($encryptedData, $iv, $data);
if ($errCode != 0) {
$this->error('授权失败,请重新授权!');
}
$decryptUserInfo = json_decode($data, true);
if (isset($decryptUserInfo['phoneNumber']) && !empty($decryptUserInfo['phoneNumber'])) {
$user_id = $this->auth->id;
$userInfo = StaffModel::where(array('id' => $user_id))->update(array('mobile' => $decryptUserInfo['phoneNumber']));
if ($userInfo === false) {
$this->error('绑定失败!');
}
$data = ['mobile' => $decryptUserInfo['phoneNumber']];
$this->success('绑定成功', $data);
} else {
$this->error('授权失败!');
}
}
//获取下级员工列表
public function getStaffList()
{
$ids = StaffModel::getLowerStaffId();
$staff = StaffModel::where([
'id' => ['in', $ids],
'status' => 1
])->with(['parent'])->field('id,name,nickname,img,num,mobile,post,parent_id')->select();
$this->success('请求成功', $staff);
}
//获取员工详情
public function getStaffDetail()
{
$id = input('id');
if (empty($id)) {
$this->error('员工不存在');
}
$staff = StaffModel::with(['department', 'parent'])->where([
'id' => $id,
])->find();
$this->success('请求成功', $staff);
}
//待审核员工列表
public function getCheckStaffList()
{
$staff = StaffModel::where([
'status' => 0,
'name' => ['neq', '']
])->field('id,name,nickname,img,num,mobile,post,status')->select();
$this->success('请求成功', $staff);
}
//修改员工信息
public function updateStaff()
{
$name = input('name', '');
$img = input('img', '');
$email = input('email', '');
$sex = input('sex', 0);
$num = input('num', '');
$post = input('post', '');
$parent_id = input('parent_id', 0);
$id = input('id', 0, 'intval');
if (StaffModel::where(['id' => $id])->update([
'name' => $name,
'img' => $img,
'email' => $email,
'sex' => $sex,
'num' => $num,
'post' => $post,
'parent_id' => $parent_id,
'updatetime' => time()
]) == false) {
$this->error('修改失败');
}
$this->success('修改成功');
}
//审核员工成功
public function checkStaffSuccess()
{
$name = input('name', '');
$img = input('img', '');
$email = input('email', '');
$sex = input('sex', 0);
$role = input('role', 0);
$num = input('num', '');
$post = input('post', '');
$mobile = input('mobile', '');
$department_id = input('department_id', 0);
$parent_id = input('parent_id', 0);
$id = input('id', 0, 'intval');
if (StaffModel::where(['id' => $id, 'status' => 0])->find() == false) {
$this->error('待审核员工不存在');
}
if (empty($department_id)) {
$this->error('请选择员工部门!');
}
if (StaffModel::where(['id' => $id])->update([
'name' => $name,
'img' => $img,
'email' => $email,
'sex' => $sex,
'num' => $num,
'role' => $role,
'mobile' => $mobile,
'post' => $post,
'parent_id' => $parent_id,
'department_id' => $department_id,
'status' => 1,
'updatetime' => time()
]) == false) {
$this->error('审核失败');
}
$this->success('审核成功');
}
//审核员工拒绝
public function checkStaffError(){
$id = input('id');
if (StaffModel::where(['id' => $id, 'status' => 0])->find() == false) {
$this->error('待审核员工不存在');
}
if (StaffModel::where(['id' => $id, 'status' => 0])->update(['deletetime' => time()]) == false) {
$this->error('拒绝失败');
}
$this->success('审核成功');
}
//获取员工统计
public function getStaffStatistics()
{
$id = input('id');
if (empty($id)) {
$this->error('员工不存在');
}
$date = input('date', date('Y-m'));
//月底
$endDate = strtotime('+1 month', strtotime(date($date . '-1')));
$date = strtotime($date);
//客户 线索 联系人 合同 回款 跟进次数 处理审批
$leads = Leads::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
])->count();
$customer = Customer::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
])->count();
$contacts = Contacts::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
])->count();
$contract = Contract::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
'check_status' => 2
])->count();
$contract_money = Contract::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
'check_status' => 2
])->sum('money');
$receivables = Receivables::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
'check_status' => 2
])->count();
$receivables_money = Receivables::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
'check_status' => 2
])->sum('money');
$record = Record::where([
'create_staff_id' => $id,
'createtime' => ['between', [$date, $endDate]],
])->count();
$field = Achievement::getMonthField(date('Y-m', $date));
$contractAchievement = Achievement::where([
'year' => date('Y', $date),
'type' => 3,
'obj_id' => $id,
'status' => 1
])->value($field);
$receivablesAchievement = Achievement::where([
'year' => date('Y', $date),
'type' => 3,
'obj_id' => $id,
'status' => 2
])->value($field);
$this->success('请求成功', [
'leads' => $leads,
'customer' => $customer,
'contacts' => $contacts,
'contract' => $contract,
'contract_money' => $contract_money,
'receivables' => $receivables,
'receivables_money' => $receivables_money,
'record' => $record,
'contractAchievement' => $contractAchievement ?: 0,
'receivablesAchievement' => $receivablesAchievement ?: 0,
]);
}
//获取员工所属客户
public function getStaffCustomer()
{
$id = input('id');
$limit = input("limit/d", 10);
$row = StaffModel::get($id);
if (empty($row)) {
$this->error('员工不存在');
}
$where = [];
$where['owner_staff_id'] = $id;
$list = Customer::where($where)->with([
'ownerStaff',
'contacts'
])->field('id,name,next_time,owner_staff_id,level,follow')->order('id desc')->paginate($limit);
$this->success('请求成功', $list);
}
//获取部门列表
public function getDepartment()
{
$this->success('请求成功', StaffDepartment::getDepartmentList());
}
//获取上级列表
public function getParentList()
{
$id = input('id');
if (empty($id)) {
$this->error('参数错误');
}
$this->success('请求成功', StaffModel::getList([$id]));
}
/**
* 获取用户上级IDs
*/
public function getStaffIds()
{
// record 跟进 contract 合同 consume 费用 receivables 回款
$type = input('type');
$remind=Remind::where(['type'=>$type])->find();
if($remind){
$staff = StaffModel::where(['id' => ['in', $remind['staff_ids']]])->field('id,name,img')->select();
$this->success('请求成功', $staff);
}
$pid = StaffModel::where(['id' => $this->auth->id])->value('parent_id');
$pids = [$pid];
$staff = StaffModel::where(['id' => ['in', $pids]])->field('id,name,img')->select();
$this->success('请求成功', $staff);
}
/**
* 获取审批列表
*/
public function getsteplist()
{
// record 跟进 contract 合同 consume 费用 receivables 回款 formapproval_1 审批
$type = input('type');
//获取审批
$data = Flow::getsteplist($type);
if (empty($data)) {
$this->error('无可用审批流,请联系管理员');
}
$this->success('请求成功', $data);
}
/**
* 获取审批详情
*/
public function getstepdetail()
{
// record 跟进 contract 合同 consume 费用 receivables 回款
$type = input('type');
$relation_id=input('relation_id');
$data = Flow::getstepdetail($type,$relation_id);
if (empty($data)) {
$this->error('无可用审批流,请联系管理员');
}
$this->success('请求成功', $data);
}
//禁用账号
public function disable_user()
{
$id = input('id');
$status = 2;
$model = new StaffModel();
$staff = $model->where(['id' => $id])->find();
if (empty($staff)) {
$this->error('员工不存在');
}
if ($model->isUpdate(true)->save(['id' => $id, 'status' => $status])) {
$this->success('操作成功');
}
$this->error('操作失败');
}
/**
* 退出登录
* @ApiMethod (POST)
*/
public function logout()
{
if (!$this->request->isPost()) {
$this->error(__('Invalid parameters'));
}
$this->auth->logout();
$this->success(__('Logout successful'));
}
/**
* 修改密码
*/
public function changepwd()
{
if ($this->request->isPost()) {
$oldpassword = $this->request->post("oldpassword");
$newpassword = $this->request->post("newpassword");
$renewpassword = $this->request->post("renewpassword");
$rule = [
'oldpassword' => 'require|length:6,30',
'newpassword' => 'require|length:6,30',
'renewpassword' => 'require|length:6,30|confirm:newpassword',
];
$msg = [
'renewpassword.confirm' =>'两次输入的密码不一致'
];
$data = [
'oldpassword' => $oldpassword,
'newpassword' => $newpassword,
'renewpassword' => $renewpassword,
];
$field = [
'oldpassword' => '旧密码',
'newpassword' => '新密码',
'renewpassword' => '确认密码'
];
$validate = new Validate($rule, $msg, $field);
$result = $validate->check($data);
if (!$result) {
$this->error(__($validate->getError()));
return false;
}
$ret = $this->auth->changepwd($newpassword, $oldpassword);
if ($ret) {
$this->success('修改密码成功');
} else {
$this->error($this->auth->getError());
}
}
}
//直接体验
public function logintest()
{
$staff = StaffModel::where([])->order('id asc')->find();
if(!$staff){
$this->error('员工不存在');
}
$stafflogin= $this->auth->direct($staff['id']);
if ($stafflogin) {
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Logged in successful'), $data);
} else {
$this->error('登录失败');
}
}
}

325
addons/qingdong/controller/StaffApi.php

@ -0,0 +1,325 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\library\StaffAuth;
use think\Config;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Hook;
use think\Lang;
use think\Loader;
use think\Request;
use think\Response;
use think\Validate;
/**
* API控制器基类
*/
class StaffApi {
/**
* @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 StaffAuth
*/
protected $auth = null;
/**
* 默认响应输出类型,支持json/xml
* @var string
*/
protected $responseType = 'json';
/**
* 构造方法
* @access public
* @param Request $request Request 对象
*/
public function __construct(Request $request = null) {
$this->request = is_null($request) ? Request::instance() : $request;
// 控制器初始化
$this->_initialize();
// 前置操作方法
if ($this->beforeActionList) {
foreach ($this->beforeActionList as $method => $options) {
is_numeric($method) ? $this->beforeAction($options) : $this->beforeAction($method, $options);
}
}
$controllername = strtolower($this->request->controller());
}
/**
* 初始化操作
* @access protected
*/
protected function _initialize() {
//跨域请求检测
check_cors_request();
//移除HTML标签
$this->request->filter('trim,strip_tags,htmlspecialchars');
$this->auth = StaffAuth::instance(['type'=>'Mysqlstaff']);
$modulename = $this->request->module();
$controllername = Loader::parseName($this->request->controller());
$actionname = strtolower($this->request->action());
// token
$token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token')));
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
// 设置当前请求的URI
$this->auth->setRequestUri($path);
// 检测是否需要验证登录
if (!$this->auth->match($this->noNeedLogin)) {
//初始化
$this->auth->init($token);
//检测是否登录
if (!$this->auth->isLogin()) {
$this->error(__('Please login first'), null, 401);
}
if (!$this->auth->match($this->noNeedRight)) {
//检测是否完善用户信息
if (!$this->auth->mobile || !$this->auth->name) {
$this->error('请先完善用户信息', null, 402);
}
//状态错误
if ($this->auth->status != 1) {
$this->error('等待管理员审核', null, 405);
}
}
} else {
// 如果有传递token才验证是否登录状态
if ($token) {
$this->auth->init($token);
}
}
$upload = \app\common\model\Config::upload();
// 上传信息配置后
Hook::listen("upload_config_init", $upload);
Config::set('upload', array_merge(Config::get('upload'), $upload));
// 加载当前控制器语言包
$this->loadlang($controllername);
}
/**
* 加载语言文件
* @param string $name
*/
protected function loadlang($name) {
$name = Loader::parseName($name);
Lang::load(ADDON_PATH . 'qingdong/lang/' . $this->request->langset() . '/' . str_replace('.', '/', $name) . '.php');
}
/**
* 操作成功返回的数据
* @param string $msg 提示信息
* @param mixed $data 要返回的数据
* @param int $code 错误码,默认为1
* @param string $type 输出类型
* @param array $header 发送的 Header 信息
*/
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 = [
'code' => $code,
'msg' => $msg,
'time' => Request::instance()->server('REQUEST_TIME'),
'data' => $data,
];
// 如果未设置类型则自动判断
$type = $type ? $type : ($this->request->param(config('var_jsonp_handler')) ? 'jsonp' : $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();
}
protected function qingdongValidate($params, $class, $scene, $rules = []) {
$validate = validate(str_replace('controller', 'validate', $class));
if (!$validate->check($params, $rules, $scene)) {
return $validate->getError();
}
return true;
}
}

906
addons/qingdong/controller/Statistics.php

@ -0,0 +1,906 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Achievement;
use addons\qingdong\model\Achievement as AchievementModel;
use addons\qingdong\model\ContractRatio;
use addons\qingdong\model\Receivables;
use addons\qingdong\model\Contract;
use addons\qingdong\model\Leads;
use addons\qingdong\model\Customer;
use addons\qingdong\model\ReceivablesPlan;
use addons\qingdong\model\Record;
use addons\qingdong\model\Staff;
/**
* 统计接口
*/
class Statistics extends StaffApi {
protected $noNeedLogin = [];
protected $noNeedRight = [];
/**
*成交排行
*/
public function contractRanding() {
// $date = input('date', date('Y-m'));
$type = input('type', 0);//0 本人及下属 1 仅本人 2 仅下属 3公司
$status=input('status',1);//1 合同 2 回款
$times=input('times','');
$times=explode(',',$times);
if(empty($times)){
$this->error('参数不能为空');
}
$startDate=date("Y-m",strtotime($times[0]));
$endDate=date("Y-m",strtotime($times[1]));
$between=[$times[0],$times[1]];
if($status == 1){
$contracts = Contract::where([
'order_date' => ['between', $between],
'check_status' => 2,
])->group('owner_staff_id')->field('owner_staff_id,sum(money) as money')->order('money desc')->select();
$list = [];
foreach ($contracts as $v) {
$list[$v['owner_staff_id']] = $v['money'];
}
}else{
$receivables = Receivables::where([
'return_time' => ['between', $between],
'check_status' => 2,
])->group('owner_staff_id')->field('owner_staff_id,sum(money) as money')->order('money desc')->select();
$list = [];
foreach ($receivables as $v) {
$list[$v['owner_staff_id']] = $v['money'];
}
}
$data = [];
$staffs = Staff::getList();
foreach ($staffs as $v) {
if (isset($list[$v['id']])) {
$data[$v['id']] = $list[$v['id']];
} else {
$data[$v['id']] = 0;
}
}
arsort($data);
$staffs = Staff::getKeyList();
$result = [];
$i = 1;
$oneMoney = 0;
if ($type == 1) {//本人
$showStaffIds = [$this->auth->id];
} elseif ($type == 2) {//下属
$showStaffIds = Staff::getLowerStaffId();
} elseif ($type == 3) {//公司
$showStaffIds = Staff::getLowerStaffId();
} else {//全部
$showStaffIds = Staff::getMyStaffIds();
}
foreach ($data as $id => $money) {
if ($i == 1) {
$oneMoney = $money;
}
$val = $staffs[$id];
$val['money'] = $money;
$val['ratio'] = ($money && $oneMoney) ? sprintf("%.2f", $money / $oneMoney * 100) : 0;
$val['rank'] = $i;
$i++;
if(in_array($id,$showStaffIds)){
$result[] = $val;
}
}
if (count($result) >= 10) {
$top = array_slice($result, 0, 3);
$bottom = array_slice($result, -3, 3);
$middle = array_slice($result, 3, 4);
$result = array_merge($top, $bottom, $middle);
}
if ($type == 1) {//本人
$showStaffIds = [$this->auth->id];
//业绩目标完成情况
$data = Achievement::getStaffAchievement($startDate,$endDate,$status);
} elseif ($type == 2) {//下属
$showStaffIds = Staff::getLowerStaffId();
//业绩目标完成情况
$data = Achievement::getStaffAchievement($startDate,$endDate,$status);
} elseif ($type == 3) {//公司
$showStaffIds = Staff::getLowerStaffId();
//业绩目标完成情况
$data = Achievement::getCompanyAchievement($startDate,$endDate,$status);
} else {//全部
$showStaffIds = Staff::getMyStaffIds();
//业绩目标完成情况
$data = Achievement::getStaffAchievement($startDate,$endDate,$status);
}
$achievement=$data['achievement']??0;
if($status == 1){
$totalMoneys = Contract::where([
'order_date' => ['between', $between],
'check_status' => 2,
'owner_staff_id' => ['in',$showStaffIds],
])->sum('money');
}else{
$totalMoneys = Receivables::where([
'return_time' => ['between', $between],
'check_status' => 2,
'owner_staff_id' => ['in',$showStaffIds],
])->sum('money');
}
$ratio = ($totalMoneys && intval($achievement)) ? (intval($achievement) == 0) ? 100 : round($totalMoneys / $achievement * 100, 2) : 0;
$data = [
'achievement' => $achievement,
'contract_moneys' => $totalMoneys,
'completion_status' => ($ratio >= 100) ? 1 : 0,//完成状态
'ratio' => $ratio,
'ranking' => $result
];
$this->success('请求成功', $data);
}
/**
* 合同排行 机型排行
*/
public function contractRanking() {
$date = input('date', date('Y-m'));
$type = input('type', 0);//0 本人及下属 1 仅本人 2 仅下属
//月底
$endDate = date('Y-m-d', strtotime('+1 month', strtotime($date . '-1')) - 1);
$contracts = Contract::where([
'order_date' => ['between', [$date . '-1', $endDate]],
'check_status' => 2,
])->group('owner_staff_id')->field('owner_staff_id,count(*) as contract_number')->order('contract_number desc')->select();
$list = [];
foreach ($contracts as $v) {
$list[$v['owner_staff_id']] = $v['contract_number'];
}
$contracts = $list;
$data = [];
$staffs = Staff::getList();
foreach ($staffs as $v) {
if (isset($contracts[$v['id']])) {
$data[$v['id']] = $contracts[$v['id']];
} else {
$data[$v['id']] = 0;
}
}
arsort($data);
$staffs = Staff::getKeyList();
$result = [];
$i = 1;
$oneNumber = 0;
if ($type == 1) {//本人
$showStaffIds = [$this->auth->id];
} elseif ($type == 2) {//下属
$showStaffIds = Staff::getLowerStaffId();
} else {//全部
$showStaffIds = Staff::getMyStaffIds();
}
foreach ($data as $id => $number) {
if ($i == 1) {
$oneNumber = $number;
}
$val = $staffs[$id];
$val['number'] = $number;
$val['ratio'] = $oneNumber ? sprintf("%.2f", $number / $oneNumber * 100) : 0;
$val['rank'] = $i;
$i++;
if(in_array($id,$showStaffIds)){
$result[] = $val;
}
}
if (count($result) >= 10) {
$top = array_slice($result, 0, 3);
$bottom = array_slice($result, -3, 3);
$middle = array_slice($result, 3, 4);
$result = array_merge($top, $bottom, $middle);
}
$this->success('请求成功', $result);
}
/**
* 回款统计
*/
public function receivablesStatistics() {
$type = input('type',0); //0:全部 1:我负责的 2:下属负责的
switch($type){
case 1:
$wheres['owner_staff_id'] = $this->auth->id;
break;
case 2:
$wheres['owner_staff_id'] = array('in',Staff::getLowerStaffId());
break;
default:
$wheres['owner_staff_id'] = array('in',Staff::getMyStaffIds());
break;
}
$contract_moneys = Contract::where(['owner_staff_id' => $this->auth->id, 'check_status' => 2])->sum('money');
$receivables_moneys = Receivables::where($wheres)->where([
'check_status' => 2,
])->sum('money');
$plan_moneys = ReceivablesPlan::where($wheres)->where([
'status' => 0,
])->sum('money');
$no_moneys = $contract_moneys - $receivables_moneys;
$startDate = date('Y-01');
$endDate = date('Y-m');
$plans = ReceivablesPlan::where($wheres)->group('dates')->field('sum(money) as money,FROM_UNIXTIME(UNIX_TIMESTAMP(return_date),"%Y-%m") as dates')->select();
$plans_list = [];
foreach ($plans as $item) {
$plans_list[$item['dates']] = $item['money'];
}
$receivables = Receivables::where($wheres)->group('dates')->field('sum(money) as money,FROM_UNIXTIME(UNIX_TIMESTAMP(return_time),"%Y-%m") as dates')->select();
$receivables_list = [];
foreach ($receivables as $item) {
$receivables_list[$item['dates']] = $item['money'];
}
$data = [];
for ($startDate; strtotime($startDate) <= strtotime($endDate); $startDate = date('Y-m', strtotime($startDate . ' +1 month'))) {
$row = [
'date' => $startDate,
'plan' => $plans_list[$startDate] ?? 0,
'receivables' => $receivables_list[$startDate] ?? 0,
];
$row['no'] = ($row['plan'] - $row['receivables']) > 0 ? $row['plan'] - $row['receivables'] : 0;
$data[] = $row;
}
$this->success('请求成功', [
'contract_moneys' => $contract_moneys,
'receivables_moneys' => $receivables_moneys,
'plan_moneys' => $plan_moneys,
'no_moneys' => $no_moneys,
'data' => $data
]);
}
/**
* 所属员工回款统计
*/
public function staffReceivablesStatistics() {
$ids = Staff::getMyStaffIds();
$contract_moneys = Contract::where([
'owner_staff_id' => ['in', $ids],
'check_status' => 2,
])->sum('money');
$receivables_moneys = Receivables::where([
'owner_staff_id' => ['in', $ids],
'check_status' => 2,
])->sum('money');
$plan_moneys = ReceivablesPlan::where([
'owner_staff_id' => ['in', $ids],
'status' => 0,
])->sum('money');
$no_moneys = $contract_moneys - $receivables_moneys;
$contracts = Contract::where([
'owner_staff_id' => [
'in',
$ids
],
'check_status' => 2,
])->group('owner_staff_id')->field('sum(money) as money,owner_staff_id')->select();
$contracts_list = [];
foreach ($contracts as $item) {
$contracts_list[$item['owner_staff_id']] = $item['money'];
}
$plans = ReceivablesPlan::where([
'owner_staff_id' => [
'in',
$ids
],
'status' => 0,
])->group('owner_staff_id')->field('sum(money) as money,owner_staff_id')->select();
$plans_list = [];
foreach ($plans as $item) {
$plans_list[$item['owner_staff_id']] = $item['money'];
}
$receivables = Receivables::where([
'owner_staff_id' => [
'in',
$ids
],
'check_status' => 2,
])->group('owner_staff_id')->field('sum(money) as money,owner_staff_id')->select();
$receivables_list = [];
foreach ($receivables as $item) {
$receivables_list[$item['owner_staff_id']] = $item['money'];
}
$data = [];
$ids = Staff::getMyStaffIds();
$staffs = Staff::where(['id' => ['in', $ids]])->field('id,name')->select();
foreach ($staffs as $v) {
$row = [
'id' => $v['id'],
'name' => $v['name'],
'contracts' => $contracts_list[$v['id']] ?? 0,
'plan' => $plans_list[$v['id']] ?? 0,
'receivables' => $receivables_list[$v['id']] ?? 0,
];
$row['no'] = ($row['contracts'] - $row['receivables']) > 0 ? $row['contracts'] - $row['receivables'] : 0;
$data[] = $row;
}
$this->success('请求成功', [
'contract_moneys' => $contract_moneys,
'receivables_moneys' => $receivables_moneys,
'plan_moneys' => $plan_moneys,
'no_moneys' => $no_moneys,
'data' => $data
]);
}
/**
* 我的业绩目标完成度
*/
public function staffAchievementStatistics() {
$year = input('year', date('Y'));
$type = input('type', 0);
if ($type == 1) {//本人
$showStaffIds = [$this->auth->id];
$yearAchievement = Achievement::getStaffYearAchievement($year);
} elseif ($type == 2) {//下属
$showStaffIds = Staff::getLowerStaffId();
$yearAchievement = Achievement::getTeamYearAchievement($year);
} elseif ($type == 3) {//公司
$showStaffIds = Staff::getLowerStaffId();
$yearAchievement = Achievement::getCompanyYearAchievement($year);
} else {//全部
$showStaffIds = Staff::getMyStaffIds();
$yearAchievement = Achievement::getTeamYearAchievement($year);
}
$contracts=ContractRatio::where([
'contract.check_status'=>2, 'contract_ratio.staff_id' => ['in',$showStaffIds],
'contract.order_date'=>['like', $year . '%']
])->with(['contract'])->select();
$contracts=collection($contracts)->toArray();
$contractData=[];
foreach ($contracts as $v) {
$order_date = $v['contract']['order_date'];
$month = date('Y-m', strtotime($order_date));
$contractData[$month]['money'][] = $v['ratio_money'];
$contractData[$month]['contract_id'][] = $v['contract_id'];
}
$contracts_list = [];
foreach ($contractData as $month=>$v) {
$contracts_list[$month] = ['money'=>array_sum($v['money']),'count'=>count($v['contract_id'])];
}
$data = [];
foreach ($yearAchievement as $k => $v) {
if ($month = Achievement::getFieldMonth($k)) {
$month = $year . '-' . $month;
$row = [
'month' => $month,
'achievement' => $v,
'money' => isset($contracts_list[$month]) ? $contracts_list[$month]['money'] : 0,
'count' => isset($contracts_list[$month]) ? $contracts_list[$month]['count'] : 0,
];
$row['ratio'] = ($row['money'] && intval($row['achievement'])) ? sprintf("%.2f", $row['money'] / $row['achievement'] * 100) : 0;
$row['unit_price'] = ($row['money'] && $row['count']) ? sprintf("%.2f", $row['money'] / $row['count']) : 0;
$data[] = $row;
}
}
$this->success('请求成功', $data);
}
/**
* 回款数据排行
*/
public function receivablesRanking() {
$year = input('year', date('Y'));
$type = input('type', 0);
if ($type == 1) {//本人
$showStaffIds = [$this->auth->id];
} elseif ($type == 2) {//下属
$showStaffIds = Staff::getLowerStaffId();
} else {//全部
$showStaffIds = Staff::getMyStaffIds();
}
$receivables = Receivables::where([
'check_status' => 2,
'return_time' => ['like', $year . '%'],
])->group('owner_staff_id')->with(['staff'])->order('money desc')->field('owner_staff_id,sum(money) as money,count(*) as count')->select();
$receivablesData = [];
$list = [];
$i=1;
foreach ($receivables as $k => $v) {
$v['ranking'] = $i;
if(in_array($v['owner_staff_id'],$showStaffIds)){
$i++;
$receivablesData[] = $v;
}
$list[$v['owner_staff_id']] = $v['money'];
}
$contracts = $list;
$data = [];
$staffs = Staff::getList();
foreach ($staffs as $v) {
if (isset($contracts[$v['id']])) {
$data[$v['id']] = $contracts[$v['id']];
} else {
$data[$v['id']] = 0;
}
}
arsort($data);
$staffs = Staff::getKeyList();
$result = [];
$i = 1;
$oneNumber = 0;
foreach ($data as $id => $number) {
if ($i == 1) {
$oneNumber = $number;
}
$val = $staffs[$id];
$val['number'] = $number;
$val['ratio'] = $oneNumber ? sprintf("%.2f", $number / $oneNumber * 100) : 0;
$val['rank'] = $i;
if(in_array($id,$showStaffIds)){
$result[] = $val;
$i++;
}
}
if (count($result) >= 10) {
$top = array_slice($result, 0, 3);
$bottom = array_slice($result, -3, 3);
$middle = array_slice($result, 3, 4);
$result = array_merge($top, $bottom, $middle);
}
$this->success('请求成功', ['ranking' => $result, 'data' => $receivablesData]);
}
/**
* 成交数据排行
*/
public function contractMoneyRanking() {
$date = input('year', date('Y'));
$type = input('type', 0);
if ($type == 1) {//本人
$showStaffIds = [$this->auth->id];
} elseif ($type == 2) {//下属
$showStaffIds = Staff::getLowerStaffId();
} else {//全部
$showStaffIds = Staff::getMyStaffIds();
}
$contracts=ContractRatio::where([
'contract.check_status'=>2, 'contract_ratio.staff_id' => ['in',$showStaffIds],
'contract.order_date'=>['like', $date . '%']
])->with(['contract','staff'])->select();
$contracts=collection($contracts)->toArray();
$contractData=[];
foreach ($contracts as $v) {
$contractData[$v['staff_id']]['money'][] = $v['ratio_money'];
$contractData[$v['staff_id']]['contract_id'][] = $v['contract_id'];
$contractData[$v['staff_id']]['staff'] = $v['staff'];
$contractData[$v['staff_id']]['staff_id'] = $v['staff_id'];
}
$receivables = [];
foreach ($contractData as $v) {
$receivables[] = [
'money'=>array_sum($v['money']),
'count'=>count($v['contract_id']),
'staff'=>$v['staff'],
'owner_staff_id'=>$v['staff_id'],
];
}
$this->arraySortByOneField($receivables,'money',SORT_DESC);
$receivablesData = [];
$list = [];
foreach ($receivables as $k => $v) {
$v['ranking'] = $k + 1;
$v['unit_price'] = ($v['money'] && $v['count']) ? sprintf("%.2f", $v['money'] / $v['count']) : 0;
if(in_array($v['owner_staff_id'],$showStaffIds)){
$receivablesData[] = $v;
}
$list[$v['owner_staff_id']] = $v['money'];
}
$contracts = $list;
$data = [];
$staffs = Staff::getList();
foreach ($staffs as $v) {
if (isset($contracts[$v['id']])) {
$data[$v['id']] = $contracts[$v['id']];
} else {
$data[$v['id']] = 0;
}
}
arsort($data);
$staffs = Staff::getKeyList();
$result = [];
$i = 1;
$oneNumber = 0;
foreach ($data as $id => $number) {
if ($i == 1) {
$oneNumber = $number;
}
$val = $staffs[$id];
$val['number'] = $number;
$val['ratio'] = $oneNumber ? sprintf("%.2f", $number / $oneNumber * 100) : 0;
$val['rank'] = $i;
$i++;
if(in_array($id,$showStaffIds)){
$result[] = $val;
}
}
if (count($result) >= 10) {
$top = array_slice($result, 0, 3);
$bottom = array_slice($result, -3, 3);
$middle = array_slice($result, 3, 4);
$result = array_merge($top, $bottom, $middle);
}
$this->success('请求成功', ['ranking' => $result, 'data' => $receivablesData]);
}
/**
* 新增排行
*/
public function newRanking() {
$year = input('date', date('Y'));
$between = [strtotime($year . '-01-01'), strtotime($year.'-1-1 +1 year')];
$betweenC = [date('Y-m-d 00:00:00',strtotime($year . '-01-01')), date('Y-m-d 23:59:59',strtotime($year.'-1-1 +1 year'))];
$customers = Customer::where([
'createtime' => [
'between',
$between
],
'owner_staff_id' => $this->auth->id
])->group('month')->field("FROM_UNIXTIME(createtime,'%Y-%m') as month,count(*) as count")->select();
$customers_list = [];
foreach ($customers as $v) {
$customers_list[$v['month']] = $v['count'];
}
$contracts = Contract::where([
'order_date' => [
'between',
$betweenC
],
'owner_staff_id' => $this->auth->id,
'check_status'=>2
])->group('month')->field('FROM_UNIXTIME(createtime,"%Y-%m") as month,count(*) as count')->select();
$contracts_list = [];
foreach ($contracts as $v) {
$contracts_list[$v['month']] = $v['count'];
}
$leads = Leads::where([
'createtime' => [
'between',
$between
],
'owner_staff_id' => $this->auth->id
])->group('month')->field('FROM_UNIXTIME(createtime,"%Y-%m") as month,count(*) as count')->select();
$leads_list = [];
foreach ($leads as $v) {
$leads_list[$v['month']] = $v['count'];
}
$data = [];
for ($i = 1; $i <= 12; $i++) {
$month = date('Y-m', strtotime($year . '-' . $i));
$data[] = [
'month' => $month,
'customers' => $customers_list[$month] ?? 0,
'contracts' => $contracts_list[$month] ?? 0,
'leads' => $leads_list[$month] ?? 0,
];
}
$this->success('请求成功', $data);
}
/**
* 获取团队新增统计
*/
public function addCustomerStatistics() {
$date = input('date', date('Y-m'));
if(strlen($date) == 4){
$between = [strtotime($date . '-01-01'), strtotime($date.'-1-1 +1 year') - 1];
}else{
$between = [strtotime($date), strtotime('+1 month', strtotime($date)) - 1];
}
$ids = Staff::getMyStaffIds();
$staffs = Staff::where(['id' => ['in', $ids]])->field('id,name,post,img')->select();
$c = Customer::where([
'createtime' => [
'between',
$between
],
'owner_staff_id' => ['in', $ids]
])->group('owner_staff_id')->order('count desc')->field("owner_staff_id,count(*) as count")->select();
$customers = [];
foreach ($c as $v) {
$customers[$v['owner_staff_id']] = $v['count'];
}
$l = Leads::where([
'createtime' => [
'between',
$between
],
'owner_staff_id' => ['in', $ids]
])->group('owner_staff_id')->field("owner_staff_id,count(*) as count")->select();
$leads = [];
foreach ($l as $v) {
$leads[$v['owner_staff_id']] = $v['count'];
}
$t = Contract::where([
'createtime' => [
'between',
$between
],
'owner_staff_id' => ['in', $ids]
])->group('owner_staff_id')->field("owner_staff_id,count(*) as count")->select();
$contracts = [];
foreach ($t as $v) {
$contracts[$v['owner_staff_id']] = $v['count'];
}
$total=[];
$total[0]=[
'name'=>'数据汇总',
'id'=>0,
'leads'=>0,
'customers'=>0,
'contracts'=>0,
];
$sort=[];
foreach ($staffs as $k => $v) {
$v['leads'] = $leads[$v['id']] ?? 0;
$v['customers'] = $customers[$v['id']] ?? 0;
$v['contracts'] = $contracts[$v['id']] ?? 0;
$sort[$v['id']] = $v['leads'] + $v['customers'] + $v['contracts'];
$total[0]['leads'] += $v['leads'];
$total[0]['customers'] += $v['customers'];
$total[0]['contracts'] += $v['contracts'];
$staffs[$v['id']] = $v;
}
arsort($sort);
$result=[];
foreach ($sort as $id=>$v){
$result[]=$staffs[$id];
}
$staffs=array_merge($total,$result);
$this->success('请求成功',$staffs);
}
/**
* 客户新增排行
*/
public function newCustomer() {
$date = input('date', date('Y-m'));
$type = input('type', 0);
if(strlen($date) == 4){
$between = [strtotime($date . '-01-01'), strtotime($date.'-1-1 +1 year') - 1];
}else{
$between = [strtotime($date), strtotime('+1 month', strtotime($date)) - 1];
}
if ($type == 1) {//本人
$ids = [$this->auth->id];
} elseif ($type == 2) {//下属
$ids = Staff::getLowerStaffId();
} else {//全部
$ids = Staff::getMyStaffIds();
}
$c = Customer::where([
'createtime' => [
'between',
$between
],
'owner_staff_id' => ['in', $ids]
])->group('owner_staff_id')->order('count desc')->field("owner_staff_id,count(*) as count")->select();
$customers = [];
foreach ($c as $v) {
$customers[$v['owner_staff_id']] = $v['count'];
}
arsort($customers);
$staffs = Staff::getKeyList();
$result = [];
$i = 1;
$data=[];
foreach ($customers as $id => $number) {
$val = $staffs[$id];
$val['number'] = $number;
$val['rank'] = $i;
$data[]=[
'name'=>$val['name'],
'number'=>$number
];
$i++;
$result[] = $val;
}
$this->success('请求成功',['ranking' => $result, 'data' => $data]);
}
/**
* 客户跟进排行
*/
public function newRecord() {
$date = input('date', date('Y-m'));
$type = input('type', 0);
if(strlen($date) == 4){
$between = [strtotime($date . '-01-01'), strtotime($date.'-1-1 +1 year') - 1];
}else{
$between = [strtotime($date), strtotime('+1 month', strtotime($date)) - 1];
}
if ($type == 1) {//本人
$ids = [$this->auth->id];
} elseif ($type == 2) {//下属
$ids = Staff::getLowerStaffId();
} else {//全部
$ids = Staff::getMyStaffIds();
}
//跟进次数
$r= Record::where([
'create_staff_id' => ['in',$ids],
'relation_type' =>1,
'createtime' => [
'between',
$between
]
])->field("create_staff_id,count(*) as count")->group('create_staff_id')->select();
$records = [];
foreach ($r as $v) {
$records[$v['create_staff_id']] = $v['count'];
}
arsort($records);
$staffs = Staff::getKeyList();
$result = [];
$data = [];
$i = 1;
foreach ($records as $id => $number) {
$val = $staffs[$id];
$val['number'] = $number;
$val['rank'] = $i;
$data[]=[
'name'=>$val['name'],
'number'=>$number
];
$i++;
$result[] = $val;
}
$this->success('请求成功',['ranking' => $result, 'data' => $data]);
}
/**
* 获取业绩详情
*/
public function getAchievementDetail()
{
$year = input('year', date('Y'));
$status = input('status', 1);
$staff_id = input('staff_id', '');
if (empty($staff_id)) {
$this->error('员工不能为空');
}
$ids = $staff_id;
$achievements = AchievementModel::where(['type' => 3, 'obj_id' => ['in', $ids], 'year' => $year, 'status' => $status])
->field('sum(january) as january,sum(february) as february,sum(march) as march,sum(april) as april,sum(may) as may,sum(june) as june,sum(july) as july,sum(august) as august,sum(september) as september,sum(october) as october,sum(november) as november,sum(december) as december,sum(yeartarget) as yeartarget')->find()->toArray();
if ($status == 1) {//合同金额
$contracts = ContractRatio::where([
'contract.check_status' => 2, 'contract_ratio.staff_id' => ['in', $ids],
'contract.order_date' => ['like', $year . '%']
])->with(['contract'])->select();
$contracts = collection($contracts)->toArray();
$contractData = [];
foreach ($contracts as $v) {
$order_date = $v['contract']['order_date'];
$month = date('Y-m', strtotime($order_date));
$contractData[$month]['money'][] = $v['ratio_money'];
$contractData[$month]['contract_id'][] = $v['contract_id'];
}
$list = [];
foreach ($contractData as $month => $v) {
$list[$month] = ['money' => array_sum($v['money']), 'count' => count($v['contract_id'])];
}
} else {
$receivables = Receivables::where([
'owner_staff_id' => ['in', $ids],
'check_status' => 2,
'return_time' => ['like', $year . '%'],
])->group('month')
->field('sum(money) as money,FROM_UNIXTIME(UNIX_TIMESTAMP(return_time),"%Y-%m") as month,count(*) as count')->select();
$list = [];
foreach ($receivables as $v) {
$list[$v['month']] = $v;
}
}
$data = [];
$echartdata = [];
foreach ($achievements as $k => $v) {
if ($month = AchievementModel::getFieldMonth($k)) {
$month = $year . '-' . $month;
$row = [
'month' => $month,
'achievement' => $v ?? 0,
'money' => isset($list[$month]) ? $list[$month]['money'] : 0,
'count' => isset($list[$month]) ? $list[$month]['count'] : 0,
];
$row['ratio'] = ($row['money'] && intval($row['achievement'])) ? sprintf("%.2f", $row['money'] / $row['achievement'] * 100) : 0;
$row['unit_price'] = ($row['money'] && $row['count']) ? sprintf("%.2f", $row['money'] / $row['count']) : 0;
$echartdata['month'][] = $row['month'];
$echartdata['achievement'][] = $row['achievement']??0;
$echartdata['money'][] = $row['money'];
$data[] = $row;
}
}
$money = isset($echartdata['money']) ? array_sum($echartdata['money']) : 0;
$ratio = ($money && intval($achievements['yeartarget'])) ? sprintf("%.2f", $money / $achievements['yeartarget'] * 100) : 0;
$yeartarget = [
'year' => $year,
'money' => $money,
'achievement' => $achievements['yeartarget'] ?? 0,
'ratio' => $ratio
];
$this->success('请求成功', ['data' => $data, 'echartdata' => $echartdata, 'yeartarget' => $yeartarget]);
}
/**
* 排序
* @param $data
* @param $field
* @param int $sort
* @return mixed
*/
public function arraySortByOneField($data, $field, $sort = SORT_ASC)
{
$field = array_column($data, $field);
array_multisort($field, $sort, $data);
return $data;
}
}

55
addons/qingdong/controller/Wx.php

@ -0,0 +1,55 @@
<?php
namespace addons\qingdong\controller;
use addons\qingdong\model\Staff;
use addons\qingdong\model\AdminConfig;
use think\Log;
use WeWork\Crypt\WXBizMsgCrypt;
/**
* * 操作文档:https://doc.fastadmin.net/qingdong
* 软件介绍:https://www.fastadmin.net/store/qingdong.html
* 售后微信:qingdong_crm
* 企业微信接口
*/
class Wx extends StaffApi
{
protected $noNeedLogin = ['userid','template','token'];
protected $noNeedRight = [];
public function _initialize()
{
parent::_initialize();
}
//验证
public function token()
{
$corpId = AdminConfig::getConfigValue('wechat', 'corpid');
$token = '';
$encodingAesKey = '';
Log::write('a---' . json_encode($_GET));
$sVerifyMsgSig = input('msg_signature');
$sVerifyTimeStamp = input('timestamp');
$sVerifyNonce = input('nonce');
$sVerifyEchoStr = input('echostr');
if (empty($sVerifyMsgSig) || empty($sVerifyTimeStamp) || empty($sVerifyNonce) || empty($sVerifyEchoStr)) {
$this->error('参数不正确');
}
$sEchoStr = "";
$wxcpt = new WXBizMsgCrypt($token, $encodingAesKey, $corpId);
$errCode = $wxcpt->VerifyURL($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sVerifyEchoStr, $sEchoStr);
if ($errCode == 0) {
return $sEchoStr;
} else {
return false;
}
}
}

68
addons/qingdong/controller/Wxbizdatacrypt.php

@ -0,0 +1,68 @@
<?php
namespace addons\qingdong\controller;
/**
* 对微信小程序用户加密数据的解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
class Wxbizdatacrypt
{
private $appid;
private $sessionKey;
/**
* 构造函数
* @param $sessionKey string 用户在小程序登录后获取的会话密钥
* @param $appid string 小程序的appid
*/
public function __construct( $appid, $sessionKey)
{
$this->sessionKey = $sessionKey;
$this->appid = $appid;
}
/**
* 检验数据的真实性,并且获取解密后的明文.
* @param $encryptedData string 加密的用户数据
* @param $iv string 与用户数据一同返回的初始向量
* @param $data string 解密后的原文
*
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData( $encryptedData, $iv, &$data )
{
if (strlen($this->sessionKey) != 24) {
return ErrorCode::$IllegalAesKey;
}
$aesKey=base64_decode($this->sessionKey);
if (strlen($iv) != 24) {
return ErrorCode::$IllegalIv;
}
$aesIV=base64_decode($iv);
$aesCipher=base64_decode($encryptedData);
$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
$dataObj=json_decode( $result );
if( $dataObj == NULL )
{
return ErrorCode::$IllegalBuffer;
}
if( $dataObj->watermark->appid != $this->appid )
{
return ErrorCode::$IllegalBuffer;
}
$data = $result;
return ErrorCode::$OK;
}
}

532
addons/qingdong/helper.php

@ -0,0 +1,532 @@
<?php
// 公共助手函数
use Symfony\Component\VarExporter\VarExporter;
/**
* 求两个已知经纬度之间的距离,单位为米
* @param lng1 $ ,lng2 经度
* @param lat1 $ ,lat2 纬度
* @return float 距离,单位米
* @author www.Alixixi.com
*/
function getdistance($lng1, $lat1, $lng2, $lat2)
{
// 将角度转为狐度
$radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度
$radLat2 = deg2rad($lat2);
$radLng1 = deg2rad($lng1);
$radLng2 = deg2rad($lng2);
$a = $radLat1 - $radLat2;
$b = $radLng1 - $radLng2;
$s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
return $s;
}
function float_number($number)
{
$number = intval($number);
$length = strlen(intval($number)); //数字长度
if ($length > 3) { //万单位
//截取前俩为
$str = substr_replace(strstr($number, substr($number, -2), ' '), '.', -1, 0) . "公里";
} else {
return $number . '米';
}
return $str . '米';
}
function build_field_option($name = null, $selected = null,$type = null)
{
//获取选项列表
$fields = \addons\qingdong\model\Field::getField($name,$type);
$html = '<option value="">请选择'.$name.'</option>';
foreach ($fields as $v) {
if ($selected == $v) {
$html .= "<option value='{$v}' selected='selected'>{$v}</option>";
} else {
$html .= "<option value='{$v}'>{$v}</option>";
}
}
return $html;
}
//修改多维数组为一位数组
function modify_array($arr, $field1, $field2)
{
$data = [];
foreach ($arr as $v) {
$data[$v[$field1] ?? ''] = $v[$field2] ?? '';
}
return $data;
}
//显示文件夹
function showdir($path)
{
$dh = opendir($path);//打开目录
$arr = [];
while (($d = readdir($dh)) != false) {
//逐个文件读取,添加!=false条件,是为避免有文件或目录的名称为0
if ($d == '.' || $d == '..') {//判断是否为.或..,默认都会有
continue;
}
if (is_dir($path . '/' . $d)) {//如果为目录
$lowers = showdir($path . '/' . $d);//继续读取该目录下的目录或文件
if ($lowers) {
$arr = array_merge($arr, $lowers);
}
} else {
$arr[] = $path . '/' . $d;
}
}
return $arr;
}
//获取年度列表
function getYears(){
$start=2020;
$years=[];
$toYear=date('Y');
$end=date('Y')+1;
for ($start;$start<=$end;$start++){
if($start == $toYear){
$years[]=[
'id'=>$start,
'name'=>$start.'年',
'selected'=>'selected'
];
}else{
$years[]=[
'id'=>$start,
'name'=>$start.'年',
];
}
}
return $years;
}
///随机字符串,字母+数字
function genRandomString($len,$t=0)
{
$chars = array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z"
);
$chars1= array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z"
);
$chars2 = array(
"1", "2",
"3", "4", "5", "6", "7", "8", "9"
);
$chars3 = array(
"A", "B", "C", "D", "E", "F", "G", "O" ,
"H", "I", "J", "K", "L", "M", "N", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z"
);
$chars4 = array(
"A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "1","2",
"3", "4", "5", "6", "7", "8", "9"
);
if($t==1){
$charsLen = count($chars1) - 1;
shuffle($chars1); // 将数组打乱
$output = "";
for ($i=0; $i<$len; $i++)
{
$output .= $chars1[mt_rand(0, $charsLen)];
}
}elseif($t==2){
$charsLen = count($chars2) - 1;
shuffle($chars2); // 将数组打乱
$output = "";
for ($i=0; $i<$len; $i++)
{
$output .= $chars2[mt_rand(0, $charsLen)];
}
}elseif($t==3){
$charsLen = count($chars3) - 1;
shuffle($chars3); // 将数组打乱
$output = "";
for ($i=0; $i<$len; $i++)
{
$output .= $chars3[mt_rand(0, $charsLen)];
}
}elseif($t==4){
$charsLen = count($chars4) - 1;
shuffle($chars4); // 将数组打乱
$output = "";
for ($i=0; $i<$len; $i++)
{
$output .= $chars4[mt_rand(0, $charsLen)];
}
}else{
$charsLen = count($chars) - 1;
shuffle($chars); // 将数组打乱
$output = "";
for ($i=0; $i<$len; $i++)
{
$output .= $chars[mt_rand(0, $charsLen)];
}
}
return $output;
}
//将表情进行转义 用于存储的时候
function emoji_encode($str){
if(!is_string($str)) return $str;
if(!$str || $str=='undefined') return '';
$text = json_encode($str); //暴露出unicode
$text = preg_replace_callback("/(\\\u[2def][0-9a-f]{3})/i",function($str){
return addslashes($str[0]);
},$text); //将emoji的unicode留下,其他不动,这里的正则比原答案增加了d,因为我发现我很多emoji实际上是\ud开头的,反而暂时没发现有\ue开头。
return json_decode($text);
}
//将表情进行反转义 用于读取的时候
function emoji_decode($str){
$text = json_encode($str); //暴露出unicode
$text = preg_replace_callback('/\\\\\\\\/i',function($str){
return '\\';
},$text); //将两条斜杠变成一条,其他不动
return json_decode($text);
}
//过滤emoji
function filter_Emoji($str)
{
$str = preg_replace_callback( //执行一个正则表达式搜索并且使用一个回调进行替换
'/./u',
function (array $match) {
return strlen($match[0]) >= 4 ? '' : $match[0];
},
$str);
return $str;
}
//获取编号
function get_num($type)
{
return 'R' . date('Ymd') . rand(10000, 99999);
}
if (!function_exists('setTimes')) {
/**
* @param $times
* @param string $type date|datetime|time
* @return array|string
*/
function setTimes($times, $type = 'date')
{
switch ($times) {
case 'today':
$today = date('Y-m-d');
$todayend = date('Y-m-d');
$result = [$today, $todayend];
break;
case 'yesterday':
$yesterday = date('Y-m-d', strtotime('-1 day'));
$result = [$yesterday, $yesterday];
break;
case 'tomorrow':
$tomorrow = date('Y-m-d', strtotime('+1 day'));
$result = [$tomorrow, $tomorrow];
break;
case 'thisweek':
$thisweek_start = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - date("w") + 1, date("Y")));
$thisweek_end = date("Y-m-d", mktime(23, 59, 59, date("m"), date("d") - date("w") + 7, date("Y")));
$result = [$thisweek_start, $thisweek_end];
break;
case 'lastweek':
$lastweek_start = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - date("w") + 1 - 7, date("Y")));
$lastweek_end = date("Y-m-d", mktime(23, 59, 59, date("m"), date("d") - date("w") + 7 - 7, date("Y")));
$result = [$lastweek_start, $lastweek_end];
break;
case 'nextweek':
$lastweek_start = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - date("w") + 1 + 7, date("Y")));
$lastweek_end = date("Y-m-d", mktime(23, 59, 59, date("m"), date("d") - date("w") + 7 + 7, date("Y")));
$result = [$lastweek_start, $lastweek_end];
break;
case 'thismonth':
$thismonth_start = date("Y-m-d", mktime(0, 0, 0, date("m"), 1, date("Y")));
$thismonth_end = date("Y-m-d", mktime(23, 59, 59, date("m"), date("t"), date("Y")));
$result = [$thismonth_start, $thismonth_end];
break;
case 'lastmonth':
$lastmonth_start = date("Y-m-d", mktime(0, 0, 0, date("m") - 1, 1, date("Y")));
$lastmonth_end = date("Y-m-d", mktime(23, 59, 59, date("m"), 0, date("Y")));
$result = [$lastmonth_start, $lastmonth_end];
break;
case 'nextmonth':
$nextmonth_start = date("Y-m-d", mktime(0, 0, 0, date("m") + 1, 1, date("Y")));
$nextmonth_end = date("Y-m-d", mktime(23, 59, 59, date("m") + 1, date("t"), date("Y")));
$result = [$nextmonth_start, $nextmonth_end];
break;
case 'thisquarter':
//本季度未最后一月天数
$getMonthDays = date("t", mktime(0, 0, 0, date('n') + (date('n') - 1) % 3, 1, date("Y")));
//本季度/
$thisquarter_start = date('Y-m-d', mktime(0, 0, 0, date('n') - (date('n') - 1) % 3, 1, date('Y')));
$thisquarter_end = date('Y-m-d', mktime(23, 59, 59, date('n') + (date('n') - 1) % 3, $getMonthDays, date('Y')));
$result = [$thisquarter_start, $thisquarter_end];
break;
case 'lastquarter':
//上季度未最后一月天数
$getMonthDays = date("t", mktime(0, 0, 0, date('n') + (date('n') - 1) % 3 - 3, 1, date("Y")));
$thisquarter_start = date('Y-m-d', mktime(0, 0, 0, date('n') - (date('n') - 1) % 3 - 3, 1, date('Y')));
$thisquarter_end = date('Y-m-d', mktime(23, 59, 59, date('n') + (date('n') - 1) % 3 - 3, $getMonthDays, date('Y')));
$result = [$thisquarter_start, $thisquarter_end];
break;
case 'nextquarter':
//下季度未最后一月天数
$getMonthDays = date("t", mktime(0, 0, 0, date('n') + (date('n') - 1) % 3 + 3, 1, date("Y")));
$thisquarter_start = date('Y-m-d', mktime(0, 0, 0, date('n') - (date('n') - 1) % 3 + 3, 1, date('Y')));
$thisquarter_end = date('Y-m-d', mktime(23, 59, 59, date('n') + (date('n') - 1) % 3 + 3, $getMonthDays, date('Y')));
$result = [$thisquarter_start, $thisquarter_end];
break;
case 'thisyear':
//今年
$thisyear_start = date('Y') . '-1-1';
$thisquarter_end = date('Y') . '-12-31';
$result = [$thisyear_start, $thisquarter_end];
break;
case 'lastyear':
//去年
$lastyear_start = date('Y') . '-1-1';
$lastyear_end = date('Y') . '-12-31';
$result = [$lastyear_start, $lastyear_end];
break;
case 'nextyear':
//下一年
$nextyear_start = date('Y') . '-1-1';
$nextyear_end = date('Y') . '-12-31';
$result = [$nextyear_start, $nextyear_end];
break;
default:
$times = explode(',', $times);
$result = [$times[0] ?? date('Y-m-d'), $times[1] ?? date('Y-m-d')];
break;
}
if ($type == 'date') {
return $result;
} elseif ($type == 'datetime') {
$result[0] = date('Y-m-d H:i:s', strtotime($result[0]));
$result[1] = date('Y-m-d H:i:s', strtotime($result[1]) + 86400 - 1);
return $result;
} elseif ($type == 'time') {
$result[0] =strtotime($result[0]);
$result[1] =strtotime($result[1]) + 86400 - 1;
return $result;
} else {
return $result;
}
}
}
if (!function_exists('export_excel')){
//导出excel
function export_excel($title, $expTableData, $excel = 'export')
{
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename=' . $excel . '.xlsx');
header('Cache-Control: max-age=0');
$obj = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
// 以下内容是excel文件的信息描述信息
$obj->getProperties()->setTitle('导出文件'); //设置标题
$obj->setActiveSheetIndex(0);
$obj->getActiveSheet()->setTitle('导出文件');
/* 循环读取每个单元格的数据 */
$a = 'A';
$currentSheet = $obj->getActiveSheet();
foreach ($title as $key => $value) {
//读取工作表1
// 设置第一行加粗
$obj->getActiveSheet()->getStyle($a . '1')->getFont()->setBold(true);
//这里是设置单元格的内容
$currentSheet->getCell($a . '1')->setValue($value);
$a++;
}
//行数循环
$b = 2;
foreach ($expTableData as $k => $row) {
$a = 'A';
foreach ($row as $key => $value) {
//这里是设置单元格的内容
$currentSheet->getCell($a . $b)->setValue($value);
$a++;
}
$b++;
}
$PHPWriter = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($obj);
$fileName = $excel . date('YmdHis') . '.xlsx';
$file_path = ROOT_PATH . 'public' . '/export/' . date('Y-m-d') . '/' . $fileName;
// 创建文件夹
$path_info = pathinfo($file_path);
if ($path_info['dirname'] && !is_dir($path_info['dirname'])) {
$result = create_dir($path_info['dirname']);
if (false === $result) {
return false;
}
}
$PHPWriter->save($file_path);
$datas['filePath'] = '/' . 'export/' . date('Y-m-d') . '/' . $fileName;
$datas['fileName'] = $fileName;
$datas['size'] = filesize('./' . 'export/' . date('Y-m-d') . '/' . $fileName);
return $datas;
}
}
if (!function_exists('create_dir')){
/**
* 创建文件夹,可以多级创建
* @param string $filename 需要创建的文件夹路径
* @return boolean
*/
function create_dir($filename) {
if (!is_dir($filename)) {
create_dir(dirname($filename));
return mkdir($filename, 0777);
}
return true;
}
}
if (!function_exists('convertAmountToCn')){
/**
* 将数值金额转换为中文大写金额
* @param $amount float 金额(支持到分)
* @param $type int 补整类型,0:到角补整;1:到元补整
* @return mixed 中文大写金额
*/
function convertAmountToCn($amount, $type = 1)
{
// 判断输出的金额是否为数字或数字字符串
if (!is_numeric($amount)) {
return "要转换的金额只能为数字!";
}
// 金额为0,则直接输出"零元整"
if ($amount == 0) {
return "人民币零元整";
}
// 金额不能为负数
if ($amount < 0) {
return "要转换的金额不能为负数!";
}
// 金额不能超过万亿,即12位
if (strlen($amount) > 12) {
return "要转换的金额不能为万亿及更高金额!";
}
// 预定义中文转换的数组
$digital = array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
// 预定义单位转换的数组
$position = array('仟', '佰', '拾', '亿', '仟', '佰', '拾', '万', '仟', '佰', '拾', '元');
// 将金额的数值字符串拆分成数组
$amountArr = explode('.', $amount);
// 将整数位的数值字符串拆分成数组
$integerArr = str_split($amountArr[0], 1);
// 将整数部分替换成大写汉字
$result = '';
$integerArrLength = count($integerArr); // 整数位数组的长度
$positionLength = count($position); // 单位数组的长度
for ($i = 0; $i < $integerArrLength; $i++) {
// 如果数值不为0,则正常转换
if ($integerArr[$i] != 0) {
$result = $result . $digital[$integerArr[$i]] . $position[$positionLength - $integerArrLength + $i];
} else {
// 如果数值为0, 且单位是亿,万,元这三个的时候,则直接显示单位
if (($positionLength - $integerArrLength + $i + 1) % 4 == 0) {
$result = $result . $position[$positionLength - $integerArrLength + $i];
}
}
}
// 如果小数位也要转换
if ($type == 0) {
// 将小数位的数值字符串拆分成数组
$decimalArr = str_split($amountArr[1], 1);
// 将角替换成大写汉字. 如果为0,则不替换
if ($decimalArr[0] != 0) {
$result = $result . $digital[$decimalArr[0]] . '角';
}
// 将分替换成大写汉字. 如果为0,则不替换
if ($decimalArr[1] != 0) {
$result = $result . $digital[$decimalArr[1]] . '分';
}
} else {
$result = $result . '整';
}
return $result;
}
}

10
addons/qingdong/info.ini

@ -0,0 +1,10 @@
name = qingdong
title = 青动CRM
intro = 青动CRM客户关系管理系统
author = qingdong
website = http://www.qingdong.vip
version = 3.1.0
state = 1
url = /addons/qingdong
license = extended
licenseto = 48387

1457
addons/qingdong/install.sql

File diff suppressed because it is too large

3
addons/qingdong/lang/zh-cn.php

@ -0,0 +1,3 @@
<?php
return [];

38
addons/qingdong/lang/zh-cn/staff.php

@ -0,0 +1,38 @@
<?php
return [
'User center' => '会员中心',
'Register' => '注册',
'Login' => '登录',
'Sign up successful' => '注册成功',
'Username can not be empty' => '用户名不能为空',
'Username must be 6 to 30 characters' => '用户名必须6-30个字符',
'Password can not be empty' => '密码不能为空',
'Password must be 6 to 30 characters' => '密码必须6-30个字符',
'Mobile is incorrect' => '手机格式不正确',
'Username already exist' => '用户名已经存在',
'Nickname already exist' => '昵称已经存在',
'Email already exist' => '邮箱已经存在',
'Mobile already exist' => '手机号已经存在',
'Username is incorrect' => '用户名不正确',
'Email is incorrect' => '邮箱不正确',
'Account is locked' => '账户已经被锁定',
'Password is incorrect' => '密码不正确',
'Account is incorrect' => '账户不正确',
'Account not exist' => '账户不存在',
'Account can not be empty' => '账户不能为空',
'Username or password is incorrect' => '用户名或密码不正确',
'You are not logged in' => '你当前还未登录',
'You\'ve logged in, do not login again' => '你已经存在,请不要重复登录',
'Profile' => '个人资料',
'Verify email' => '邮箱验证',
'Change password' => '修改密码',
'Captcha is incorrect' => '验证码不正确',
'Logged in successful' => '登录成功',
'Logout successful' => '退出成功',
'Operation failed' => '操作失败',
'Invalid parameters' => '参数不正确',
'Change password failure' => '修改密码失败',
'Change password successful' => '修改密码成功',
'Reset password successful' => '重置密码成功',
];

100
addons/qingdong/library/Ding.php

@ -0,0 +1,100 @@
<?php
namespace addons\qingdong\library;
use dingding\TopSdk;
use think\Cache;
use think\Log;
use think\Model;
use addons\qingdong\model\AdminConfig;
/**
*
*/
class Ding extends Model
{
public $config;
protected $app;
public function __construct()
{
$this->config = [
];
$sdk=new TopSdk();
return parent::__construct();
}
//获取accessToken
public function getAccessToken()
{
$config = AdminConfig::where(array('type'=>'dingding'))->find();
$tokenRequest = new \OapiGettokenRequest();
$this->app = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_GET, \DingTalkConstant::$FORMAT_JSON);
$accessKey = AdminConfig::where(array('type'=>'dingding','field'=>'ding_key'))->value('value');
$accessSecret = AdminConfig::where(array('type'=>'dingding','field'=>'ding_secret'))->value('value');
$tokenRequest->setAppkey($accessKey);
$tokenRequest->setAppsecret($accessSecret);
$token= $this->app->execute($tokenRequest, null, "https://oapi.dingtalk.com/gettoken");
return $token;
}
//获取部门
public function departmentInfo($access_token=null,$dept_id=null){
$this->app = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST , \DingTalkConstant::$FORMAT_JSON);
$req = new \OapiV2DepartmentListsubRequest();
if($dept_id){
$req->setDeptId($dept_id);
}
$resp = $this->app->execute($req, $access_token, "https://oapi.dingtalk.com/topapi/v2/department/listsub");
return $resp;
}
//获取员工
public function staffInfo($access_token=null,$dept_id=null){
$this->app = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST , \DingTalkConstant::$FORMAT_JSON);
$req = new \OapiUserListsimpleRequest();
$req->setDeptId($dept_id);
$req->setCursor("0");
$req->setSize("80");
$resp = $this->app->execute($req, $access_token, "https://oapi.dingtalk.com/topapi/user/listsimple");
return $resp;
}
//获取员工详情
public function staffInfoDetail($access_token=null,$user_id=null){
$this->app = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST , \DingTalkConstant::$FORMAT_JSON);
$req = new \OapiV2UserGetRequest();
$req->setUserid($user_id);
$resp = $this->app->execute($req, $access_token, "https://oapi.dingtalk.com/topapi/v2/user/get");
return $resp;
}
//批量获取客户
public function customerBatch($access_token=null,$user_id=null){
$this->app = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST , \DingTalkConstant::$FORMAT_JSON);
$req = new \OapiCrmObjectdataCustomerQueryRequest();
$req->setCurrentOperatorUserid($user_id);
$req->setCursor("0");
$req->setPageSize("100");
$resp = $this->app->execute($req, $access_token, "https://oapi.dingtalk.com/topapi/crm/objectdata/customer/query");
return $resp;
}
//批量获取联系人
public function contactsBatch($access_token=null,$user_id=null){
$this->app = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST , \DingTalkConstant::$FORMAT_JSON);
$req = new \OapiCrmObjectdataCustomerQueryRequest();
$req->setCurrentOperatorUserid($user_id);
$req->setCursor("0");
$req->setPageSize("100");
$resp = $this->app->execute($req, $access_token, "https://oapi.dingtalk.com/topapi/crm/objectdata/contact/query");
return $resp;
}
//批量获取跟进记录
public function recordBatch($access_token=null,$user_id=null){
$this->app = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST , \DingTalkConstant::$FORMAT_JSON);
$req = new \OapiCrmObjectdataCustomerQueryRequest();
$req->setCurrentOperatorUserid($user_id);
$req->setCursor("0");
$req->setPageSize("100");
$resp = $this->app->execute($req, $access_token, "https://oapi.dingtalk.com/topapi/crm/objectdata/followrecord/query");
return $resp;
}
}

113
addons/qingdong/library/Ku.php

@ -0,0 +1,113 @@
<?php
namespace addons\qingdong\library;
use addons\qingdong\model\AdminConfig;
use addons\qingdong\model\Contacts;
use addons\qingdong\model\Customer;
use addons\qingdong\model\KuCustomer;
use think\Model;
use fast\Http;
/**
*
*/
class Ku extends Model
{
//客户增加
public function addCustomer($params=null){
$ku = AdminConfig::where(['type'=>AdminConfig::TYPE_KU])->column('field,value');
if(isset($ku) && $ku && $params){
if($ku['status'] == 1 && $ku['account'] && $ku['key']){
$info = KuCustomer::where(array('customer_id'=>$params['customer_id']))->find();
if($info){
return true;
}
$customer = Customer::where(array('id'=>$params['customer_id']))->find();
$url =$ku['url'].'api/kuerp/third/customers/joinCustomers';
$sign = md5('account='.$ku['account'].'&mobile='.$params['mobile'].'&name='.$customer['name'].'key='.$ku['key']);
$data = array(
'account'=>$ku['account'],
'sign'=>$sign,
'request_time'=>time(),
'name'=>$customer['name'],
'mobile'=>$params['mobile'],
'address'=>$customer['address'],
'note'=>$customer['remarks'],
);
$result = $this->http_post($url,$data);
$result = json_decode($result,true);
if($result['code'] == 1){
$ress = array(
'customer_id'=>$params['customer_id'],
'contacts_id'=>$params['contacts_id'],
'ku_id'=>$result['data']['id'],
'code'=>$result['data']['customer_code'],
'createtime'=>time()
);
KuCustomer::create($ress);
}
}
}
return true;
}
//客户修改
public function editCustomer($params=null){
$ku = AdminConfig::where(['type'=>AdminConfig::TYPE_KU])->column('field,value');
if(isset($ku) && $ku && $params){
if($ku['status'] == 1 && $ku['account'] && $ku['key']){
$info = KuCustomer::where(array('customer_id'=>$params['id']))->find();
if(!$info){
return true;
}
$contacts = Contacts::where(array('id'=>$info['contacts_id']))->value('mobile');
$url =$ku['url'].'api/kuerp/third/customers/editCustomers';
$sign = md5('account='.$ku['account'].'&code='.$info['code'].'&mobile='.$contacts.'&name='.$params['name'].'key='.$ku['key']);
$data = array(
'account'=>$ku['account'],
'sign'=>$sign,
'request_time'=>time(),
'code'=>$info['code'],
'name'=>$params['name'],
'mobile'=>$contacts,
'address'=>$params['address'],
);
$result = $this->http_post($url,$data);
$result = json_decode($result,true);
}
}
return true;
}
public function http_post($url,$param,$post_file=false){
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
if (is_string($param) || $post_file) {
$strPOST = $param;
} else {
$aPOST = array();
foreach($param as $key=>$val){
$aPOST[] = $key."=".urlencode($val);
}
$strPOST = join("&", $aPOST);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($oCurl, CURLOPT_POST,true);
curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}
}

95
addons/qingdong/library/PhpWord/Collection/AbstractCollection.php

@ -0,0 +1,95 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Collection;
/**
* Collection abstract class
*
* @since 0.10.0
*/
abstract class AbstractCollection
{
/**
* Items
*
* @var \PhpOffice\PhpWord\Element\AbstractContainer[]
*/
private $items = array();
/**
* Get items
*
* @return \PhpOffice\PhpWord\Element\AbstractContainer[]
*/
public function getItems()
{
return $this->items;
}
/**
* Get item by index
*
* @param int $index
* @return \PhpOffice\PhpWord\Element\AbstractContainer
*/
public function getItem($index)
{
if (array_key_exists($index, $this->items)) {
return $this->items[$index];
}
return null;
}
/**
* Set item.
*
* @param int $index
* @param \PhpOffice\PhpWord\Element\AbstractContainer $item
*/
public function setItem($index, $item)
{
if (array_key_exists($index, $this->items)) {
$this->items[$index] = $item;
}
}
/**
* Add new item
*
* @param \PhpOffice\PhpWord\Element\AbstractContainer $item
* @return int
*/
public function addItem($item)
{
$index = $this->countItems() + 1;
$this->items[$index] = $item;
return $index;
}
/**
* Get item count
*
* @return int
*/
public function countItems()
{
return count($this->items);
}
}

27
addons/qingdong/library/PhpWord/Collection/Bookmarks.php

@ -0,0 +1,27 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Collection;
/**
* Bookmarks collection
*
* @since 0.12.0
*/
class Bookmarks extends AbstractCollection
{
}

27
addons/qingdong/library/PhpWord/Collection/Charts.php

@ -0,0 +1,27 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Collection;
/**
* Charts collection
*
* @since 0.12.0
*/
class Charts extends AbstractCollection
{
}

27
addons/qingdong/library/PhpWord/Collection/Comments.php

@ -0,0 +1,27 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Collection;
/**
* Comments collection
*
* @since 0.12.0
*/
class Comments extends AbstractCollection
{
}

27
addons/qingdong/library/PhpWord/Collection/Endnotes.php

@ -0,0 +1,27 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Collection;
/**
* Endnotes collection
*
* @since 0.10.0
*/
class Endnotes extends AbstractCollection
{
}

27
addons/qingdong/library/PhpWord/Collection/Footnotes.php

@ -0,0 +1,27 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Collection;
/**
* Footnotes collection
*
* @since 0.10.0
*/
class Footnotes extends AbstractCollection
{
}

27
addons/qingdong/library/PhpWord/Collection/Titles.php

@ -0,0 +1,27 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Collection;
/**
* Titles collection
*
* @since 0.10.0
*/
class Titles extends AbstractCollection
{
}

181
addons/qingdong/library/PhpWord/ComplexType/FootnoteProperties.php

@ -0,0 +1,181 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\ComplexType;
use PhpOffice\PhpWord\SimpleType\NumberFormat;
/**
* Footnote properties
*
* @see http://www.datypic.com/sc/ooxml/e-w_footnotePr-1.html
*/
final class FootnoteProperties
{
const RESTART_NUMBER_CONTINUOUS = 'continuous';
const RESTART_NUMBER_EACH_SECTION = 'eachSect';
const RESTART_NUMBER_EACH_PAGE = 'eachPage';
const POSITION_PAGE_BOTTOM = 'pageBottom';
const POSITION_BENEATH_TEXT = 'beneathText';
const POSITION_SECTION_END = 'sectEnd';
const POSITION_DOC_END = 'docEnd';
/**
* Footnote Positioning Location
*
* @var string
*/
private $pos;
/**
* Footnote Numbering Format w:numFmt, one of PhpOffice\PhpWord\SimpleType\NumberFormat
*
* @var string
*/
private $numFmt;
/**
* Footnote and Endnote Numbering Starting Value
*
* @var float
*/
private $numStart;
/**
* Footnote and Endnote Numbering Restart Location
*
* @var string
*/
private $numRestart;
/**
* Get the Footnote Positioning Location
*
* @return string
*/
public function getPos()
{
return $this->pos;
}
/**
* Set the Footnote Positioning Location (pageBottom, beneathText, sectEnd, docEnd)
*
* @param string $pos
* @throws \InvalidArgumentException
* @return self
*/
public function setPos($pos)
{
$position = array(
self::POSITION_PAGE_BOTTOM,
self::POSITION_BENEATH_TEXT,
self::POSITION_SECTION_END,
self::POSITION_DOC_END,
);
if (in_array($pos, $position)) {
$this->pos = $pos;
} else {
throw new \InvalidArgumentException('Invalid value, on of ' . implode(', ', $position) . ' possible');
}
return $this;
}
/**
* Get the Footnote Numbering Format
*
* @return string
*/
public function getNumFmt()
{
return $this->numFmt;
}
/**
* Set the Footnote Numbering Format
*
* @param string $numFmt One of NumberFormat
* @return self
*/
public function setNumFmt($numFmt)
{
NumberFormat::validate($numFmt);
$this->numFmt = $numFmt;
return $this;
}
/**
* Get the Footnote Numbering Format
*
* @return float
*/
public function getNumStart()
{
return $this->numStart;
}
/**
* Set the Footnote Numbering Format
*
* @param float $numStart
* @return self
*/
public function setNumStart($numStart)
{
$this->numStart = $numStart;
return $this;
}
/**
* Get the Footnote and Endnote Numbering Starting Value
*
* @return string
*/
public function getNumRestart()
{
return $this->numRestart;
}
/**
* Set the Footnote and Endnote Numbering Starting Value (continuous, eachSect, eachPage)
*
* @param string $numRestart
* @throws \InvalidArgumentException
* @return self
*/
public function setNumRestart($numRestart)
{
$restartNumbers = array(
self::RESTART_NUMBER_CONTINUOUS,
self::RESTART_NUMBER_EACH_SECTION,
self::RESTART_NUMBER_EACH_PAGE,
);
if (in_array($numRestart, $restartNumbers)) {
$this->numRestart = $numRestart;
} else {
throw new \InvalidArgumentException('Invalid value, on of ' . implode(', ', $restartNumbers) . ' possible');
}
return $this;
}
}

106
addons/qingdong/library/PhpWord/ComplexType/ProofState.php

@ -0,0 +1,106 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\ComplexType;
/**
* Spelling and Grammatical Checking State
*
* @see http://www.datypic.com/sc/ooxml/e-w_proofState-1.html
*/
final class ProofState
{
/**
* Check Completed
*/
const CLEAN = 'clean';
/**
* Check Not Completed
*/
const DIRTY = 'dirty';
/**
* Spell Checking State
*
* @var string
*/
private $spelling;
/**
* Grammatical Checking State
*
* @var string
*/
private $grammar;
/**
* Set the Spell Checking State (dirty or clean)
*
* @param string $spelling
* @throws \InvalidArgumentException
* @return self
*/
public function setSpelling($spelling)
{
if ($spelling == self::CLEAN || $spelling == self::DIRTY) {
$this->spelling = $spelling;
} else {
throw new \InvalidArgumentException('Invalid value, dirty or clean possible');
}
return $this;
}
/**
* Get the Spell Checking State
*
* @return string
*/
public function getSpelling()
{
return $this->spelling;
}
/**
* Set the Grammatical Checking State (dirty or clean)
*
* @param string $grammar
* @throws \InvalidArgumentException
* @return self
*/
public function setGrammar($grammar)
{
if ($grammar == self::CLEAN || $grammar == self::DIRTY) {
$this->grammar = $grammar;
} else {
throw new \InvalidArgumentException('Invalid value, dirty or clean possible');
}
return $this;
}
/**
* Get the Grammatical Checking State
*
* @return string
*/
public function getGrammar()
{
return $this->grammar;
}
}

59
addons/qingdong/library/PhpWord/ComplexType/TblWidth.php

@ -0,0 +1,59 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\ComplexType;
use PhpOffice\PhpWord\SimpleType\TblWidth as TblWidthSimpleType;
/**
* @see http://www.datypic.com/sc/ooxml/t-w_CT_TblWidth.html
*/
final class TblWidth
{
/** @var string */
private $type;
/** @var int */
private $value;
/**
* @param int $value If omitted, then its value shall be assumed to be 0
* @param string $type If omitted, then its value shall be assumed to be dxa
*/
public function __construct($value = 0, $type = TblWidthSimpleType::TWIP)
{
$this->value = $value;
TblWidthSimpleType::validate($type);
$this->type = $type;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @return int
*/
public function getValue()
{
return $this->value;
}
}

166
addons/qingdong/library/PhpWord/ComplexType/TrackChangesView.php

@ -0,0 +1,166 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\ComplexType;
/**
* Visibility of Annotation Types
*
* @see http://www.datypic.com/sc/ooxml/e-w_revisionView-1.html
*/
final class TrackChangesView
{
/**
* Display Visual Indicator Of Markup Area
*
* @var bool
*/
private $markup;
/**
* Display Comments
*
* @var bool
*/
private $comments;
/**
* Display Content Revisions
*
* @var bool
*/
private $insDel;
/**
* Display Formatting Revisions
*
* @var bool
*/
private $formatting;
/**
* Display Ink Annotations
*
* @var bool
*/
private $inkAnnotations;
/**
* Get Display Visual Indicator Of Markup Area
*
* @return bool True if markup is shown
*/
public function hasMarkup()
{
return $this->markup;
}
/**
* Set Display Visual Indicator Of Markup Area
*
* @param bool $markup
* Set to true to show markup
*/
public function setMarkup($markup)
{
$this->markup = $markup === null ? true : $markup;
}
/**
* Get Display Comments
*
* @return bool True if comments are shown
*/
public function hasComments()
{
return $this->comments;
}
/**
* Set Display Comments
*
* @param bool $comments
* Set to true to show comments
*/
public function setComments($comments)
{
$this->comments = $comments === null ? true : $comments;
}
/**
* Get Display Content Revisions
*
* @return bool True if content revisions are shown
*/
public function hasInsDel()
{
return $this->insDel;
}
/**
* Set Display Content Revisions
*
* @param bool $insDel
* Set to true to show content revisions
*/
public function setInsDel($insDel)
{
$this->insDel = $insDel === null ? true : $insDel;
}
/**
* Get Display Formatting Revisions
*
* @return bool True if formatting revisions are shown
*/
public function hasFormatting()
{
return $this->formatting;
}
/**
* Set Display Formatting Revisions
*
* @param bool|null $formatting
* Set to true to show formatting revisions
*/
public function setFormatting($formatting = null)
{
$this->formatting = $formatting === null ? true : $formatting;
}
/**
* Get Display Ink Annotations
*
* @return bool True if ink annotations are shown
*/
public function hasInkAnnotations()
{
return $this->inkAnnotations;
}
/**
* Set Display Ink Annotations
*
* @param bool $inkAnnotations
* Set to true to show ink annotations
*/
public function setInkAnnotations($inkAnnotations)
{
$this->inkAnnotations = $inkAnnotations === null ? true : $inkAnnotations;
}
}

316
addons/qingdong/library/PhpWord/Element/AbstractContainer.php

@ -0,0 +1,316 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Container abstract class
*
* @method Text addText(string $text, mixed $fStyle = null, mixed $pStyle = null)
* @method TextRun addTextRun(mixed $pStyle = null)
* @method Bookmark addBookmark(string $name)
* @method Link addLink(string $target, string $text = null, mixed $fStyle = null, mixed $pStyle = null, boolean $internal = false)
* @method PreserveText addPreserveText(string $text, mixed $fStyle = null, mixed $pStyle = null)
* @method void addTextBreak(int $count = 1, mixed $fStyle = null, mixed $pStyle = null)
* @method ListItem addListItem(string $txt, int $depth = 0, mixed $font = null, mixed $list = null, mixed $para = null)
* @method ListItemRun addListItemRun(int $depth = 0, mixed $listStyle = null, mixed $pStyle = null)
* @method Footnote addFootnote(mixed $pStyle = null)
* @method Endnote addEndnote(mixed $pStyle = null)
* @method CheckBox addCheckBox(string $name, $text, mixed $fStyle = null, mixed $pStyle = null)
* @method Title addTitle(mixed $text, int $depth = 1)
* @method TOC addTOC(mixed $fontStyle = null, mixed $tocStyle = null, int $minDepth = 1, int $maxDepth = 9)
* @method PageBreak addPageBreak()
* @method Table addTable(mixed $style = null)
* @method Image addImage(string $source, mixed $style = null, bool $isWatermark = false, $name = null)
* @method OLEObject addOLEObject(string $source, mixed $style = null)
* @method TextBox addTextBox(mixed $style = null)
* @method Field addField(string $type = null, array $properties = array(), array $options = array(), mixed $text = null)
* @method Line addLine(mixed $lineStyle = null)
* @method Shape addShape(string $type, mixed $style = null)
* @method Chart addChart(string $type, array $categories, array $values, array $style = null, $seriesName = null)
* @method FormField addFormField(string $type, mixed $fStyle = null, mixed $pStyle = null)
* @method SDT addSDT(string $type)
*
* @method \PhpOffice\PhpWord\Element\OLEObject addObject(string $source, mixed $style = null) deprecated, use addOLEObject instead
*
* @since 0.10.0
*/
abstract class AbstractContainer extends AbstractElement
{
/**
* Elements collection
*
* @var \PhpOffice\PhpWord\Element\AbstractElement[]
*/
protected $elements = array();
/**
* Container type Section|Header|Footer|Footnote|Endnote|Cell|TextRun|TextBox|ListItemRun|TrackChange
*
* @var string
*/
protected $container;
/**
* Magic method to catch all 'addElement' variation
*
* This removes addText, addTextRun, etc. When adding new element, we have to
* add the model in the class docblock with `@method`.
*
* Warning: This makes capitalization matters, e.g. addCheckbox or addcheckbox won't work.
*
* @param mixed $function
* @param mixed $args
* @return \PhpOffice\PhpWord\Element\AbstractElement
*/
public function __call($function, $args)
{
$elements = array(
'Text', 'TextRun', 'Bookmark', 'Link', 'PreserveText', 'TextBreak',
'ListItem', 'ListItemRun', 'Table', 'Image', 'Object', 'OLEObject',
'Footnote', 'Endnote', 'CheckBox', 'TextBox', 'Field',
'Line', 'Shape', 'Title', 'TOC', 'PageBreak',
'Chart', 'FormField', 'SDT', 'Comment',
);
$functions = array();
foreach ($elements as $element) {
$functions['add' . strtolower($element)] = $element == 'Object' ? 'OLEObject' : $element;
}
// Run valid `add` command
$function = strtolower($function);
if (isset($functions[$function])) {
$element = $functions[$function];
// Special case for TextBreak
// @todo Remove the `$count` parameter in 1.0.0 to make this element similiar to other elements?
if ($element == 'TextBreak') {
list($count, $fontStyle, $paragraphStyle) = array_pad($args, 3, null);
if ($count === null) {
$count = 1;
}
for ($i = 1; $i <= $count; $i++) {
$this->addElement($element, $fontStyle, $paragraphStyle);
}
} else {
// All other elements
array_unshift($args, $element); // Prepend element name to the beginning of args array
return call_user_func_array(array($this, 'addElement'), $args);
}
}
return null;
}
/**
* Add element
*
* Each element has different number of parameters passed
*
* @param string $elementName
* @return \PhpOffice\PhpWord\Element\AbstractElement
*/
protected function addElement($elementName)
{
$elementClass = __NAMESPACE__ . '\\' . $elementName;
$this->checkValidity($elementName);
// Get arguments
$args = func_get_args();
$withoutP = in_array($this->container, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun', 'Field'));
if ($withoutP && ($elementName == 'Text' || $elementName == 'PreserveText')) {
$args[3] = null; // Remove paragraph style for texts in textrun
}
// Create element using reflection
$reflection = new \ReflectionClass($elementClass);
$elementArgs = $args;
array_shift($elementArgs); // Shift the $elementName off the beginning of array
/** @var \PhpOffice\PhpWord\Element\AbstractElement $element Type hint */
$element = $reflection->newInstanceArgs($elementArgs);
// Set parent container
$element->setParentContainer($this);
$element->setElementIndex($this->countElements() + 1);
$element->setElementId();
$this->elements[] = $element;
return $element;
}
/**
* Get all elements
*
* @return \PhpOffice\PhpWord\Element\AbstractElement[]
*/
public function getElements()
{
return $this->elements;
}
/**
* Returns the element at the requested position
*
* @param int $index
* @return \PhpOffice\PhpWord\Element\AbstractElement|null
*/
public function getElement($index)
{
if (array_key_exists($index, $this->elements)) {
return $this->elements[$index];
}
return null;
}
/**
* Removes the element at requested index
*
* @param int|\PhpOffice\PhpWord\Element\AbstractElement $toRemove
*/
public function removeElement($toRemove)
{
if (is_int($toRemove) && array_key_exists($toRemove, $this->elements)) {
unset($this->elements[$toRemove]);
} elseif ($toRemove instanceof \PhpOffice\PhpWord\Element\AbstractElement) {
foreach ($this->elements as $key => $element) {
if ($element->getElementId() === $toRemove->getElementId()) {
unset($this->elements[$key]);
return;
}
}
}
}
/**
* Count elements
*
* @return int
*/
public function countElements()
{
return count($this->elements);
}
/**
* Check if a method is allowed for the current container
*
* @param string $method
*
* @throws \BadMethodCallException
* @return bool
*/
private function checkValidity($method)
{
$generalContainers = array(
'Section', 'Header', 'Footer', 'Footnote', 'Endnote', 'Cell', 'TextRun', 'TextBox', 'ListItemRun', 'TrackChange',
);
$validContainers = array(
'Text' => $generalContainers,
'Bookmark' => $generalContainers,
'Link' => $generalContainers,
'TextBreak' => $generalContainers,
'Image' => $generalContainers,
'OLEObject' => $generalContainers,
'Field' => $generalContainers,
'Line' => $generalContainers,
'Shape' => $generalContainers,
'FormField' => $generalContainers,
'SDT' => $generalContainers,
'TrackChange' => $generalContainers,
'TextRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox', 'TrackChange', 'ListItemRun'),
'ListItem' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'),
'ListItemRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'),
'Table' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'),
'CheckBox' => array('Section', 'Header', 'Footer', 'Cell', 'TextRun'),
'TextBox' => array('Section', 'Header', 'Footer', 'Cell'),
'Footnote' => array('Section', 'TextRun', 'Cell', 'ListItemRun'),
'Endnote' => array('Section', 'TextRun', 'Cell'),
'PreserveText' => array('Section', 'Header', 'Footer', 'Cell'),
'Title' => array('Section', 'Cell'),
'TOC' => array('Section'),
'PageBreak' => array('Section'),
'Chart' => array('Section', 'Cell'),
);
// Special condition, e.g. preservetext can only exists in cell when
// the cell is located in header or footer
$validSubcontainers = array(
'PreserveText' => array(array('Cell'), array('Header', 'Footer', 'Section')),
'Footnote' => array(array('Cell', 'TextRun'), array('Section')),
'Endnote' => array(array('Cell', 'TextRun'), array('Section')),
);
// Check if a method is valid for current container
if (isset($validContainers[$method])) {
if (!in_array($this->container, $validContainers[$method])) {
throw new \BadMethodCallException("Cannot add {$method} in {$this->container}.");
}
}
// Check if a method is valid for current container, located in other container
if (isset($validSubcontainers[$method])) {
$rules = $validSubcontainers[$method];
$containers = $rules[0];
$allowedDocParts = $rules[1];
foreach ($containers as $container) {
if ($this->container == $container && !in_array($this->getDocPart(), $allowedDocParts)) {
throw new \BadMethodCallException("Cannot add {$method} in {$this->container}.");
}
}
}
return true;
}
/**
* Create textrun element
*
* @deprecated 0.10.0
*
* @param mixed $paragraphStyle
*
* @return \PhpOffice\PhpWord\Element\TextRun
*
* @codeCoverageIgnore
*/
public function createTextRun($paragraphStyle = null)
{
return $this->addTextRun($paragraphStyle);
}
/**
* Create footnote element
*
* @deprecated 0.10.0
*
* @param mixed $paragraphStyle
*
* @return \PhpOffice\PhpWord\Element\Footnote
*
* @codeCoverageIgnore
*/
public function createFootnote($paragraphStyle = null)
{
return $this->addFootnote($paragraphStyle);
}
}

507
addons/qingdong/library/PhpWord/Element/AbstractElement.php

@ -0,0 +1,507 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Media;
use PhpOffice\PhpWord\PhpWord;
/**
* Element abstract class
*
* @since 0.10.0
*/
abstract class AbstractElement
{
/**
* PhpWord object
*
* @var \PhpOffice\PhpWord\PhpWord
*/
protected $phpWord;
/**
* Section Id
*
* @var int
*/
protected $sectionId;
/**
* Document part type: Section|Header|Footer|Footnote|Endnote
*
* Used by textrun and cell container to determine where the element is
* located because it will affect the availability of other element,
* e.g. footnote will not be available when $docPart is header or footer.
*
* @var string
*/
protected $docPart = 'Section';
/**
* Document part Id
*
* For header and footer, this will be = ($sectionId - 1) * 3 + $index
* because the max number of header/footer in every page is 3, i.e.
* AUTO, FIRST, and EVEN (AUTO = ODD)
*
* @var int
*/
protected $docPartId = 1;
/**
* Index of element in the elements collection (start with 1)
*
* @var int
*/
protected $elementIndex = 1;
/**
* Unique Id for element
*
* @var string
*/
protected $elementId;
/**
* Relation Id
*
* @var int
*/
protected $relationId;
/**
* Depth of table container nested level; Primarily used for RTF writer/reader
*
* 0 = Not in a table; 1 = in a table; 2 = in a table inside another table, etc.
*
* @var int
*/
private $nestedLevel = 0;
/**
* A reference to the parent
*
* @var AbstractElement|null
*/
private $parent;
/**
* changed element info
*
* @var TrackChange
*/
private $trackChange;
/**
* Parent container type
*
* @var string
*/
private $parentContainer;
/**
* Has media relation flag; true for Link, Image, and Object
*
* @var bool
*/
protected $mediaRelation = false;
/**
* Is part of collection; true for Title, Footnote, Endnote, Chart, and Comment
*
* @var bool
*/
protected $collectionRelation = false;
/**
* The start position for the linked comment
*
* @var Comment
*/
protected $commentRangeStart;
/**
* The end position for the linked comment
*
* @var Comment
*/
protected $commentRangeEnd;
/**
* Get PhpWord
*
* @return \PhpOffice\PhpWord\PhpWord
*/
public function getPhpWord()
{
return $this->phpWord;
}
/**
* Set PhpWord as reference.
*
* @param \PhpOffice\PhpWord\PhpWord $phpWord
*/
public function setPhpWord(PhpWord $phpWord = null)
{
$this->phpWord = $phpWord;
}
/**
* Get section number
*
* @return int
*/
public function getSectionId()
{
return $this->sectionId;
}
/**
* Set doc part.
*
* @param string $docPart
* @param int $docPartId
*/
public function setDocPart($docPart, $docPartId = 1)
{
$this->docPart = $docPart;
$this->docPartId = $docPartId;
}
/**
* Get doc part
*
* @return string
*/
public function getDocPart()
{
return $this->docPart;
}
/**
* Get doc part Id
*
* @return int
*/
public function getDocPartId()
{
return $this->docPartId;
}
/**
* Return media element (image, object, link) container name
*
* @return string section|headerx|footerx|footnote|endnote
*/
private function getMediaPart()
{
$mediaPart = $this->docPart;
if ($mediaPart == 'Header' || $mediaPart == 'Footer') {
$mediaPart .= $this->docPartId;
}
return strtolower($mediaPart);
}
/**
* Get element index
*
* @return int
*/
public function getElementIndex()
{
return $this->elementIndex;
}
/**
* Set element index.
*
* @param int $value
*/
public function setElementIndex($value)
{
$this->elementIndex = $value;
}
/**
* Get element unique ID
*
* @return string
*/
public function getElementId()
{
return $this->elementId;
}
/**
* Set element unique ID from 6 first digit of md5.
*/
public function setElementId()
{
$this->elementId = substr(md5(rand()), 0, 6);
}
/**
* Get relation Id
*
* @return int
*/
public function getRelationId()
{
return $this->relationId;
}
/**
* Set relation Id.
*
* @param int $value
*/
public function setRelationId($value)
{
$this->relationId = $value;
}
/**
* Get nested level
*
* @return int
*/
public function getNestedLevel()
{
return $this->nestedLevel;
}
/**
* Get comment start
*
* @return Comment
*/
public function getCommentRangeStart()
{
return $this->commentRangeStart;
}
/**
* Set comment start
*
* @param Comment $value
*/
public function setCommentRangeStart(Comment $value)
{
if ($this instanceof Comment) {
throw new \InvalidArgumentException('Cannot set a Comment on a Comment');
}
$this->commentRangeStart = $value;
$this->commentRangeStart->setStartElement($this);
}
/**
* Get comment end
*
* @return Comment
*/
public function getCommentRangeEnd()
{
return $this->commentRangeEnd;
}
/**
* Set comment end
*
* @param Comment $value
*/
public function setCommentRangeEnd(Comment $value)
{
if ($this instanceof Comment) {
throw new \InvalidArgumentException('Cannot set a Comment on a Comment');
}
$this->commentRangeEnd = $value;
$this->commentRangeEnd->setEndElement($this);
}
/**
* Get parent element
*
* @return AbstractElement|null
*/
public function getParent()
{
return $this->parent;
}
/**
* Set parent container
*
* Passed parameter should be a container, except for Table (contain Row) and Row (contain Cell)
*
* @param \PhpOffice\PhpWord\Element\AbstractElement $container
*/
public function setParentContainer(self $container)
{
$this->parentContainer = substr(get_class($container), strrpos(get_class($container), '\\') + 1);
$this->parent = $container;
// Set nested level
$this->nestedLevel = $container->getNestedLevel();
if ($this->parentContainer == 'Cell') {
$this->nestedLevel++;
}
// Set phpword
$this->setPhpWord($container->getPhpWord());
// Set doc part
if (!$this instanceof Footnote) {
$this->setDocPart($container->getDocPart(), $container->getDocPartId());
}
$this->setMediaRelation();
$this->setCollectionRelation();
}
/**
* Set relation Id for media elements (link, image, object; legacy of OOXML)
*
* - Image element needs to be passed to Media object
* - Icon needs to be set for Object element
*/
private function setMediaRelation()
{
if (!$this instanceof Link && !$this instanceof Image && !$this instanceof OLEObject) {
return;
}
$elementName = substr(get_class($this), strrpos(get_class($this), '\\') + 1);
if ($elementName == 'OLEObject') {
$elementName = 'Object';
}
$mediaPart = $this->getMediaPart();
$source = $this->getSource();
$image = null;
if ($this instanceof Image) {
$image = $this;
}
$rId = Media::addElement($mediaPart, strtolower($elementName), $source, $image);
$this->setRelationId($rId);
if ($this instanceof OLEObject) {
$icon = $this->getIcon();
$rId = Media::addElement($mediaPart, 'image', $icon, new Image($icon));
$this->setImageRelationId($rId);
}
}
/**
* Set relation Id for elements that will be registered in the Collection subnamespaces.
*/
private function setCollectionRelation()
{
if ($this->collectionRelation === true && $this->phpWord instanceof PhpWord) {
$elementName = substr(get_class($this), strrpos(get_class($this), '\\') + 1);
$addMethod = "add{$elementName}";
$rId = $this->phpWord->$addMethod($this);
$this->setRelationId($rId);
}
}
/**
* Check if element is located in Section doc part (as opposed to Header/Footer)
*
* @return bool
*/
public function isInSection()
{
return $this->docPart == 'Section';
}
/**
* Set new style value
*
* @param mixed $styleObject Style object
* @param mixed $styleValue Style value
* @param bool $returnObject Always return object
* @return mixed
*/
protected function setNewStyle($styleObject, $styleValue = null, $returnObject = false)
{
if (!is_null($styleValue) && is_array($styleValue)) {
$styleObject->setStyleByArray($styleValue);
$style = $styleObject;
} else {
$style = $returnObject ? $styleObject : $styleValue;
}
return $style;
}
/**
* Sets the trackChange information
*
* @param TrackChange $trackChange
*/
public function setTrackChange(TrackChange $trackChange)
{
$this->trackChange = $trackChange;
}
/**
* Gets the trackChange information
*
* @return TrackChange
*/
public function getTrackChange()
{
return $this->trackChange;
}
/**
* Set changed
*
* @param string $type INSERTED|DELETED
* @param string $author
* @param null|int|\DateTime $date allways in UTC
*/
public function setChangeInfo($type, $author, $date = null)
{
$this->trackChange = new TrackChange($type, $author, $date);
}
/**
* Set enum value
*
* @param string|null $value
* @param string[] $enum
* @param string|null $default
*
* @throws \InvalidArgumentException
* @return string|null
*
* @todo Merge with the same method in AbstractStyle
*/
protected function setEnumVal($value = null, $enum = array(), $default = null)
{
if ($value !== null && trim($value) != '' && !empty($enum) && !in_array($value, $enum)) {
throw new \InvalidArgumentException("Invalid style value: {$value}");
} elseif ($value === null || trim($value) == '') {
$value = $default;
}
return $value;
}
}

60
addons/qingdong/library/PhpWord/Element/Bookmark.php

@ -0,0 +1,60 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Shared\Text as SharedText;
/**
* Bookmark element
*/
class Bookmark extends AbstractElement
{
/**
* Bookmark Name
*
* @var string
*/
private $name;
/**
* Is part of collection
*
* @var bool
*/
protected $collectionRelation = true;
/**
* Create a new Bookmark Element
*
* @param string $name
*/
public function __construct($name = '')
{
$this->name = SharedText::toUTF8($name);
}
/**
* Get Bookmark name
*
* @return string
*/
public function getName()
{
return $this->name;
}
}

77
addons/qingdong/library/PhpWord/Element/Cell.php

@ -0,0 +1,77 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Cell as CellStyle;
/**
* Table cell element
*/
class Cell extends AbstractContainer
{
/**
* @var string Container type
*/
protected $container = 'Cell';
/**
* Cell width
*
* @var int
*/
private $width = null;
/**
* Cell style
*
* @var \PhpOffice\PhpWord\Style\Cell
*/
private $style;
/**
* Create new instance
*
* @param int $width
* @param array|\PhpOffice\PhpWord\Style\Cell $style
*/
public function __construct($width = null, $style = null)
{
$this->width = $width;
$this->style = $this->setNewStyle(new CellStyle(), $style, true);
}
/**
* Get cell style
*
* @return \PhpOffice\PhpWord\Style\Cell
*/
public function getStyle()
{
return $this->style;
}
/**
* Get cell width
*
* @return int
*/
public function getWidth()
{
return $this->width;
}
}

129
addons/qingdong/library/PhpWord/Element/Chart.php

@ -0,0 +1,129 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Chart as ChartStyle;
/**
* Chart element
*
* @since 0.12.0
*/
class Chart extends AbstractElement
{
/**
* Is part of collection
*
* @var bool
*/
protected $collectionRelation = true;
/**
* Type
*
* @var string
*/
private $type = 'pie';
/**
* Series
*
* @var array
*/
private $series = array();
/**
* Chart style
*
* @var \PhpOffice\PhpWord\Style\Chart
*/
private $style;
/**
* Create new instance
*
* @param string $type
* @param array $categories
* @param array $values
* @param array $style
* @param null|mixed $seriesName
*/
public function __construct($type, $categories, $values, $style = null, $seriesName = null)
{
$this->setType($type);
$this->addSeries($categories, $values, $seriesName);
$this->style = $this->setNewStyle(new ChartStyle(), $style, true);
}
/**
* Get type
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Set type.
*
* @param string $value
*/
public function setType($value)
{
$enum = array('pie', 'doughnut', 'line', 'bar', 'stacked_bar', 'percent_stacked_bar', 'column', 'stacked_column', 'percent_stacked_column', 'area', 'radar', 'scatter');
$this->type = $this->setEnumVal($value, $enum, 'pie');
}
/**
* Add series
*
* @param array $categories
* @param array $values
* @param null|mixed $name
*/
public function addSeries($categories, $values, $name = null)
{
$this->series[] = array(
'categories' => $categories,
'values' => $values,
'name' => $name,
);
}
/**
* Get series
*
* @return array
*/
public function getSeries()
{
return $this->series;
}
/**
* Get chart style
*
* @return \PhpOffice\PhpWord\Style\Chart
*/
public function getStyle()
{
return $this->style;
}
}

72
addons/qingdong/library/PhpWord/Element/CheckBox.php

@ -0,0 +1,72 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Shared\Text as SharedText;
/**
* Check box element
*
* @since 0.10.0
*/
class CheckBox extends Text
{
/**
* Name content
*
* @var string
*/
private $name;
/**
* Create new instance
*
* @param string $name
* @param string $text
* @param mixed $fontStyle
* @param mixed $paragraphStyle
*/
public function __construct($name = null, $text = null, $fontStyle = null, $paragraphStyle = null)
{
$this->setName($name);
parent::__construct($text, $fontStyle, $paragraphStyle);
}
/**
* Set name content
*
* @param string $name
* @return self
*/
public function setName($name)
{
$this->name = SharedText::toUTF8($name);
return $this;
}
/**
* Get name content
*
* @return string
*/
public function getName()
{
return $this->name;
}
}

122
addons/qingdong/library/PhpWord/Element/Comment.php

@ -0,0 +1,122 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Comment element
* @see http://datypic.com/sc/ooxml/t-w_CT_Comment.html
*/
class Comment extends TrackChange
{
/**
* Initials
*
* @var string
*/
private $initials;
/**
* The Element where this comment starts
*
* @var AbstractElement
*/
private $startElement;
/**
* The Element where this comment ends
*
* @var AbstractElement
*/
private $endElement;
/**
* Is part of collection
*
* @var bool
*/
protected $collectionRelation = true;
/**
* Create a new Comment Element
*
* @param string $author
* @param null|\DateTime $date
* @param string $initials
*/
public function __construct($author, $date = null, $initials = null)
{
parent::__construct(null, $author, $date);
$this->initials = $initials;
}
/**
* Get Initials
*
* @return string
*/
public function getInitials()
{
return $this->initials;
}
/**
* Sets the element where this comment starts
*
* @param \PhpOffice\PhpWord\Element\AbstractElement $value
*/
public function setStartElement(AbstractElement $value)
{
$this->startElement = $value;
if ($value->getCommentRangeStart() == null) {
$value->setCommentRangeStart($this);
}
}
/**
* Get the element where this comment starts
*
* @return \PhpOffice\PhpWord\Element\AbstractElement
*/
public function getStartElement()
{
return $this->startElement;
}
/**
* Sets the element where this comment ends
*
* @param \PhpOffice\PhpWord\Element\AbstractElement $value
*/
public function setEndElement(AbstractElement $value)
{
$this->endElement = $value;
if ($value->getCommentRangeEnd() == null) {
$value->setCommentRangeEnd($this);
}
}
/**
* Get the element where this comment ends
*
* @return \PhpOffice\PhpWord\Element\AbstractElement
*/
public function getEndElement()
{
return $this->endElement;
}
}

41
addons/qingdong/library/PhpWord/Element/Endnote.php

@ -0,0 +1,41 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Endnote element
*
* @since 0.10.0
*/
class Endnote extends Footnote
{
/**
* @var string Container type
*/
protected $container = 'Endnote';
/**
* Create new instance
*
* @param string|array|\PhpOffice\PhpWord\Style\Paragraph $paragraphStyle
*/
public function __construct($paragraphStyle = null)
{
parent::__construct($paragraphStyle);
}
}

299
addons/qingdong/library/PhpWord/Element/Field.php

@ -0,0 +1,299 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Font;
/**
* Field element
*
* @since 0.11.0
* @see http://www.schemacentral.com/sc/ooxml/t-w_CT_SimpleField.html
*/
class Field extends AbstractElement
{
/**
* Field properties and options. Depending on type, a field can have different properties
* and options
*
* @var array
*/
protected $fieldsArray = array(
'PAGE' => array(
'properties' => array(
'format' => array('Arabic', 'ArabicDash', 'alphabetic', 'ALPHABETIC', 'roman', 'ROMAN'),
),
'options' => array('PreserveFormat'),
),
'NUMPAGES' => array(
'properties' => array(
'format' => array('Arabic', 'ArabicDash', 'CardText', 'DollarText', 'Ordinal', 'OrdText',
'alphabetic', 'ALPHABETIC', 'roman', 'ROMAN', 'Caps', 'FirstCap', 'Lower', 'Upper', ),
'numformat' => array('0', '0,00', '#.##0', '#.##0,00', '€ #.##0,00(€ #.##0,00)', '0%', '0,00%'),
),
'options' => array('PreserveFormat'),
),
'DATE' => array(
'properties' => array(
'dateformat' => array(
/* Generic formats */
'yyyy-MM-dd', 'yyyy-MM', 'MMM-yy', 'MMM-yyyy', 'h:mm am/pm', 'h:mm:ss am/pm', 'HH:mm', 'HH:mm:ss',
/* Day-Month-Year formats */
'dddd d MMMM yyyy', 'd MMMM yyyy', 'd-MMM-yy', 'd MMM. yy',
'd-M-yy', 'd-M-yy h:mm', 'd-M-yy h:mm:ss', 'd-M-yy h:mm am/pm', 'd-M-yy h:mm:ss am/pm', 'd-M-yy HH:mm', 'd-M-yy HH:mm:ss',
'd/M/yy', 'd/M/yy h:mm', 'd/M/yy h:mm:ss', 'd/M/yy h:mm am/pm', 'd/M/yy h:mm:ss am/pm', 'd/M/yy HH:mm', 'd/M/yy HH:mm:ss',
'd-M-yyyy', 'd-M-yyyy h:mm', 'd-M-yyyy h:mm:ss', 'd-M-yyyy h:mm am/pm', 'd-M-yyyy h:mm:ss am/pm', 'd-M-yyyy HH:mm', 'd-M-yyyy HH:mm:ss',
'd/M/yyyy', 'd/M/yyyy h:mm', 'd/M/yyyy h:mm:ss', 'd/M/yyyy h:mm am/pm', 'd/M/yyyy h:mm:ss am/pm', 'd/M/yyyy HH:mm', 'd/M/yyyy HH:mm:ss',
/* Month-Day-Year formats */
'dddd, MMMM d yyyy', 'MMMM d yyyy', 'MMM-d-yy', 'MMM. d yy',
'M-d-yy', 'M-d-yy h:mm', 'M-d-yy h:mm:ss', 'M-d-yy h:mm am/pm', 'M-d-yy h:mm:ss am/pm', 'M-d-yy HH:mm', 'M-d-yy HH:mm:ss',
'M/d/yy', 'M/d/yy h:mm', 'M/d/yy h:mm:ss', 'M/d/yy h:mm am/pm', 'M/d/yy h:mm:ss am/pm', 'M/d/yy HH:mm', 'M/d/yy HH:mm:ss',
'M-d-yyyy', 'M-d-yyyy h:mm', 'M-d-yyyy h:mm:ss', 'M-d-yyyy h:mm am/pm', 'M-d-yyyy h:mm:ss am/pm', 'M-d-yyyy HH:mm', 'M-d-yyyy HH:mm:ss',
'M/d/yyyy', 'M/d/yyyy h:mm', 'M/d/yyyy h:mm:ss', 'M/d/yyyy h:mm am/pm', 'M/d/yyyy h:mm:ss am/pm', 'M/d/yyyy HH:mm', 'M/d/yyyy HH:mm:ss',
),
),
'options' => array('PreserveFormat', 'LunarCalendar', 'SakaEraCalendar', 'LastUsedFormat'),
),
'MACROBUTTON' => array(
'properties' => array('macroname' => ''),
),
'XE' => array(
'properties' => array(),
'options' => array('Bold', 'Italic'),
),
'INDEX' => array(
'properties' => array(),
'options' => array('PreserveFormat'),
),
'STYLEREF' => array(
'properties' => array('StyleIdentifier' => ''),
'options' => array('PreserveFormat'),
),
);
/**
* Field type
*
* @var string
*/
protected $type;
/**
* Field text
*
* @var TextRun|string
*/
protected $text;
/**
* Field properties
*
* @var array
*/
protected $properties = array();
/**
* Field options
*
* @var array
*/
protected $options = array();
/**
* Font style
*
* @var string|\PhpOffice\PhpWord\Style\Font
*/
protected $fontStyle;
/**
* Set Font style
*
* @param string|array|\PhpOffice\PhpWord\Style\Font $style
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function setFontStyle($style = null)
{
if ($style instanceof Font) {
$this->fontStyle = $style;
} elseif (is_array($style)) {
$this->fontStyle = new Font('text');
$this->fontStyle->setStyleByArray($style);
} elseif (null === $style) {
$this->fontStyle = null;
} else {
$this->fontStyle = $style;
}
return $this->fontStyle;
}
/**
* Get Font style
*
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function getFontStyle()
{
return $this->fontStyle;
}
/**
* Create a new Field Element
*
* @param string $type
* @param array $properties
* @param array $options
* @param TextRun|string|null $text
* @param string|array|\PhpOffice\PhpWord\Style\Font $fontStyle
*/
public function __construct($type = null, $properties = array(), $options = array(), $text = null, $fontStyle = null)
{
$this->setType($type);
$this->setProperties($properties);
$this->setOptions($options);
$this->setText($text);
$this->setFontStyle($fontStyle);
}
/**
* Set Field type
*
* @param string $type
*
* @throws \InvalidArgumentException
* @return string
*/
public function setType($type = null)
{
if (isset($type)) {
if (isset($this->fieldsArray[$type])) {
$this->type = $type;
} else {
throw new \InvalidArgumentException("Invalid type '$type'");
}
}
return $this->type;
}
/**
* Get Field type
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Set Field properties
*
* @param array $properties
*
* @throws \InvalidArgumentException
* @return self
*/
public function setProperties($properties = array())
{
if (is_array($properties)) {
foreach (array_keys($properties) as $propkey) {
if (!(isset($this->fieldsArray[$this->type]['properties'][$propkey]))) {
throw new \InvalidArgumentException("Invalid property '$propkey'");
}
}
$this->properties = array_merge($this->properties, $properties);
}
return $this->properties;
}
/**
* Get Field properties
*
* @return array
*/
public function getProperties()
{
return $this->properties;
}
/**
* Set Field options
*
* @param array $options
*
* @throws \InvalidArgumentException
* @return self
*/
public function setOptions($options = array())
{
if (is_array($options)) {
foreach (array_keys($options) as $optionkey) {
if (!(isset($this->fieldsArray[$this->type]['options'][$optionkey])) && substr($optionkey, 0, 1) !== '\\') {
throw new \InvalidArgumentException("Invalid option '$optionkey', possible values are " . implode(', ', $this->fieldsArray[$this->type]['options']));
}
}
$this->options = array_merge($this->options, $options);
}
return $this->options;
}
/**
* Get Field properties
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Set Field text
*
* @param string|TextRun $text
*
* @throws \InvalidArgumentException
* @return null|string|TextRun
*/
public function setText($text = null)
{
if (isset($text)) {
if (is_string($text) || $text instanceof TextRun) {
$this->text = $text;
} else {
throw new \InvalidArgumentException('Invalid text');
}
}
return $this->text;
}
/**
* Get Field text
*
* @return string|TextRun
*/
public function getText()
{
return $this->text;
}
}

116
addons/qingdong/library/PhpWord/Element/Footer.php

@ -0,0 +1,116 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Footer element
*/
class Footer extends AbstractContainer
{
/**
* Header/footer types constants
*
* @var string
* @see http://www.datypic.com/sc/ooxml/t-w_ST_HdrFtr.html Header or Footer Type
*/
const AUTO = 'default'; // default and odd pages
const FIRST = 'first';
const EVEN = 'even';
/**
* @var string Container type
*/
protected $container = 'Footer';
/**
* Header type
*
* @var string
*/
protected $type = self::AUTO;
/**
* Create new instance
*
* @param int $sectionId
* @param int $containerId
* @param string $type
*/
public function __construct($sectionId, $containerId = 1, $type = self::AUTO)
{
$this->sectionId = $sectionId;
$this->setType($type);
$this->setDocPart($this->container, ($sectionId - 1) * 3 + $containerId);
}
/**
* Set type.
*
* @since 0.10.0
*
* @param string $value
*/
public function setType($value = self::AUTO)
{
if (!in_array($value, array(self::AUTO, self::FIRST, self::EVEN))) {
$value = self::AUTO;
}
$this->type = $value;
}
/**
* Get type
*
* @return string
* @since 0.10.0
*/
public function getType()
{
return $this->type;
}
/**
* Reset type to default
*
* @return string
*/
public function resetType()
{
return $this->type = self::AUTO;
}
/**
* First page only header
*
* @return string
*/
public function firstPage()
{
return $this->type = self::FIRST;
}
/**
* Even numbered pages only
*
* @return string
*/
public function evenPage()
{
return $this->type = self::EVEN;
}
}

89
addons/qingdong/library/PhpWord/Element/Footnote.php

@ -0,0 +1,89 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Paragraph;
class Footnote extends AbstractContainer
{
/**
* @var string Container type
*/
protected $container = 'Footnote';
/**
* Paragraph style
*
* @var string|\PhpOffice\PhpWord\Style\Paragraph
*/
protected $paragraphStyle;
/**
* Is part of collection
*
* @var bool
*/
protected $collectionRelation = true;
/**
* Create new instance
*
* @param string|array|\PhpOffice\PhpWord\Style\Paragraph $paragraphStyle
*/
public function __construct($paragraphStyle = null)
{
$this->paragraphStyle = $this->setNewStyle(new Paragraph(), $paragraphStyle);
$this->setDocPart($this->container);
}
/**
* Get paragraph style
*
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function getParagraphStyle()
{
return $this->paragraphStyle;
}
/**
* Get Footnote Reference ID
*
* @deprecated 0.10.0
* @codeCoverageIgnore
*
* @return int
*/
public function getReferenceId()
{
return $this->getRelationId();
}
/**
* Set Footnote Reference ID
*
* @deprecated 0.10.0
* @codeCoverageIgnore
*
* @param int $rId
*/
public function setReferenceId($rId)
{
$this->setRelationId($rId);
}
}

195
addons/qingdong/library/PhpWord/Element/FormField.php

@ -0,0 +1,195 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Form field element
*
* @since 0.12.0
* @see http://www.datypic.com/sc/ooxml/t-w_CT_FFData.html
*/
class FormField extends Text
{
/**
* Form field type: textinput|checkbox|dropdown
*
* @var string
*/
private $type = 'textinput';
/**
* Form field name
*
* @var string|bool|int
*/
private $name;
/**
* Default value
*
* - TextInput: string
* - CheckBox: bool
* - DropDown: int Index of entries (zero based)
*
* @var string|bool|int
*/
private $default;
/**
* Value
*
* @var string|bool|int
*/
private $value;
/**
* Dropdown entries
*
* @var array
*/
private $entries = array();
/**
* Create new instance
*
* @param string $type
* @param mixed $fontStyle
* @param mixed $paragraphStyle
*/
public function __construct($type, $fontStyle = null, $paragraphStyle = null)
{
parent::__construct(null, $fontStyle, $paragraphStyle);
$this->setType($type);
}
/**
* Get type
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Set type
*
* @param string $value
* @return self
*/
public function setType($value)
{
$enum = array('textinput', 'checkbox', 'dropdown');
$this->type = $this->setEnumVal($value, $enum, $this->type);
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set name
*
* @param string|bool|int $value
* @return self
*/
public function setName($value)
{
$this->name = $value;
return $this;
}
/**
* Get default
*
* @return string|bool|int
*/
public function getDefault()
{
return $this->default;
}
/**
* Set default
*
* @param string|bool|int $value
* @return self
*/
public function setDefault($value)
{
$this->default = $value;
return $this;
}
/**
* Get value
*
* @return string|bool|int
*/
public function getValue()
{
return $this->value;
}
/**
* Set value
*
* @param string|bool|int $value
* @return self
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get entries
*
* @return array
*/
public function getEntries()
{
return $this->entries;
}
/**
* Set entries
*
* @param array $value
* @return self
*/
public function setEntries($value)
{
$this->entries = $value;
return $this;
}
}

41
addons/qingdong/library/PhpWord/Element/Header.php

@ -0,0 +1,41 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Header element
*/
class Header extends Footer
{
/**
* @var string Container type
*/
protected $container = 'Header';
/**
* Add a Watermark Element
*
* @param string $src
* @param mixed $style
* @return Image
*/
public function addWatermark($src, $style = null)
{
return $this->addImage($src, $style, true);
}
}

602
addons/qingdong/library/PhpWord/Element/Image.php

@ -0,0 +1,602 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Exception\CreateTemporaryFileException;
use PhpOffice\PhpWord\Exception\InvalidImageException;
use PhpOffice\PhpWord\Exception\UnsupportedImageTypeException;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Shared\ZipArchive;
use PhpOffice\PhpWord\Style\Image as ImageStyle;
/**
* Image element
*/
class Image extends AbstractElement
{
/**
* Image source type constants
*/
const SOURCE_LOCAL = 'local'; // Local images
const SOURCE_GD = 'gd'; // Generated using GD
const SOURCE_ARCHIVE = 'archive'; // Image in archives zip://$archive#$image
const SOURCE_STRING = 'string'; // Image from string
/**
* Image source
*
* @var string
*/
private $source;
/**
* Source type: local|gd|archive
*
* @var string
*/
private $sourceType;
/**
* Image style
*
* @var ImageStyle
*/
private $style;
/**
* Is watermark
*
* @var bool
*/
private $watermark;
/**
* Name of image
*
* @var string
*/
private $name;
/**
* Image type
*
* @var string
*/
private $imageType;
/**
* Image create function
*
* @var string
*/
private $imageCreateFunc;
/**
* Image function
*
* @var string
*/
private $imageFunc;
/**
* Image extension
*
* @var string
*/
private $imageExtension;
/**
* Is memory image
*
* @var bool
*/
private $memoryImage;
/**
* Image target file name
*
* @var string
*/
private $target;
/**
* Image media index
*
* @var int
*/
private $mediaIndex;
/**
* Has media relation flag; true for Link, Image, and Object
*
* @var bool
*/
protected $mediaRelation = true;
/**
* Create new image element
*
* @param string $source
* @param mixed $style
* @param bool $watermark
* @param string $name
*
* @throws \PhpOffice\PhpWord\Exception\InvalidImageException
* @throws \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException
*/
public function __construct($source, $style = null, $watermark = false, $name = null)
{
$this->source = $source;
$this->style = $this->setNewStyle(new ImageStyle(), $style, true);
$this->setIsWatermark($watermark);
$this->setName($name);
$this->checkImage();
}
/**
* Get Image style
*
* @return ImageStyle
*/
public function getStyle()
{
return $this->style;
}
/**
* Get image source
*
* @return string
*/
public function getSource()
{
return $this->source;
}
/**
* Get image source type
*
* @return string
*/
public function getSourceType()
{
return $this->sourceType;
}
/**
* Sets the image name
*
* @param string $value
*/
public function setName($value)
{
$this->name = $value;
}
/**
* Get image name
*
* @return null|string
*/
public function getName()
{
return $this->name;
}
/**
* Get image media ID
*
* @return string
*/
public function getMediaId()
{
return md5($this->source);
}
/**
* Get is watermark
*
* @return bool
*/
public function isWatermark()
{
return $this->watermark;
}
/**
* Set is watermark
*
* @param bool $value
*/
public function setIsWatermark($value)
{
$this->watermark = $value;
}
/**
* Get image type
*
* @return string
*/
public function getImageType()
{
return $this->imageType;
}
/**
* Get image create function
*
* @return string
*/
public function getImageCreateFunction()
{
return $this->imageCreateFunc;
}
/**
* Get image function
*
* @return string
*/
public function getImageFunction()
{
return $this->imageFunc;
}
/**
* Get image extension
*
* @return string
*/
public function getImageExtension()
{
return $this->imageExtension;
}
/**
* Get is memory image
*
* @return bool
*/
public function isMemImage()
{
return $this->memoryImage;
}
/**
* Get target file name
*
* @return string
*/
public function getTarget()
{
return $this->target;
}
/**
* Set target file name.
*
* @param string $value
*/
public function setTarget($value)
{
$this->target = $value;
}
/**
* Get media index
*
* @return int
*/
public function getMediaIndex()
{
return $this->mediaIndex;
}
/**
* Set media index.
*
* @param int $value
*/
public function setMediaIndex($value)
{
$this->mediaIndex = $value;
}
/**
* Get image string data
*
* @param bool $base64
* @return string|null
* @since 0.11.0
*/
public function getImageStringData($base64 = false)
{
$source = $this->source;
$actualSource = null;
$imageBinary = null;
$imageData = null;
$isTemp = false;
// Get actual source from archive image or other source
// Return null if not found
if ($this->sourceType == self::SOURCE_ARCHIVE) {
$source = substr($source, 6);
list($zipFilename, $imageFilename) = explode('#', $source);
$zip = new ZipArchive();
if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename) !== false) {
$isTemp = true;
$zip->extractTo(Settings::getTempDir(), $imageFilename);
$actualSource = Settings::getTempDir() . DIRECTORY_SEPARATOR . $imageFilename;
}
}
$zip->close();
} else {
$actualSource = $source;
}
// Can't find any case where $actualSource = null hasn't captured by
// preceding exceptions. Please uncomment when you find the case and
// put the case into Element\ImageTest.
// if ($actualSource === null) {
// return null;
// }
// Read image binary data and convert to hex/base64 string
if ($this->sourceType == self::SOURCE_GD) {
$imageResource = call_user_func($this->imageCreateFunc, $actualSource);
if ($this->imageType === 'image/png') {
// PNG images need to preserve alpha channel information
imagesavealpha($imageResource, true);
}
ob_start();
call_user_func($this->imageFunc, $imageResource);
$imageBinary = ob_get_contents();
ob_end_clean();
} elseif ($this->sourceType == self::SOURCE_STRING) {
$imageBinary = $this->source;
} else {
$fileHandle = fopen($actualSource, 'rb', false);
if ($fileHandle !== false) {
$imageBinary = fread($fileHandle, filesize($actualSource));
fclose($fileHandle);
}
}
if ($imageBinary !== null) {
if ($base64) {
$imageData = chunk_split(base64_encode($imageBinary));
} else {
$imageData = chunk_split(bin2hex($imageBinary));
}
}
// Delete temporary file if necessary
if ($isTemp === true) {
@unlink($actualSource);
}
return $imageData;
}
/**
* Check memory image, supported type, image functions, and proportional width/height.
*
* @throws \PhpOffice\PhpWord\Exception\InvalidImageException
* @throws \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException
*/
private function checkImage()
{
$this->setSourceType();
// Check image data
if ($this->sourceType == self::SOURCE_ARCHIVE) {
$imageData = $this->getArchiveImageSize($this->source);
} elseif ($this->sourceType == self::SOURCE_STRING) {
$imageData = $this->getStringImageSize($this->source);
} else {
$imageData = @getimagesize($this->source);
}
if (!is_array($imageData)) {
throw new InvalidImageException(sprintf('Invalid image: %s', $this->source));
}
list($actualWidth, $actualHeight, $imageType) = $imageData;
// Check image type support
$supportedTypes = array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG);
if ($this->sourceType != self::SOURCE_GD && $this->sourceType != self::SOURCE_STRING) {
$supportedTypes = array_merge($supportedTypes, array(IMAGETYPE_BMP, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM));
}
if (!in_array($imageType, $supportedTypes)) {
throw new UnsupportedImageTypeException();
}
// Define image functions
$this->imageType = image_type_to_mime_type($imageType);
$this->setFunctions();
$this->setProportionalSize($actualWidth, $actualHeight);
}
/**
* Set source type.
*/
private function setSourceType()
{
if (stripos(strrev($this->source), strrev('.php')) === 0) {
$this->memoryImage = true;
$this->sourceType = self::SOURCE_GD;
} elseif (strpos($this->source, 'zip://') !== false) {
$this->memoryImage = false;
$this->sourceType = self::SOURCE_ARCHIVE;
} elseif (filter_var($this->source, FILTER_VALIDATE_URL) !== false) {
$this->memoryImage = true;
if (strpos($this->source, 'https') === 0) {
$fileContent = file_get_contents($this->source);
$this->source = $fileContent;
$this->sourceType = self::SOURCE_STRING;
} else {
$this->sourceType = self::SOURCE_GD;
}
} elseif ((strpos($this->source, chr(0)) === false) && @file_exists($this->source)) {
$this->memoryImage = false;
$this->sourceType = self::SOURCE_LOCAL;
} else {
$this->memoryImage = true;
$this->sourceType = self::SOURCE_STRING;
}
}
/**
* Get image size from archive
*
* @since 0.12.0 Throws CreateTemporaryFileException.
*
* @param string $source
*
* @throws \PhpOffice\PhpWord\Exception\CreateTemporaryFileException
*
* @return array|null
*/
private function getArchiveImageSize($source)
{
$imageData = null;
$source = substr($source, 6);
list($zipFilename, $imageFilename) = explode('#', $source);
$tempFilename = tempnam(Settings::getTempDir(), 'PHPWordImage');
if (false === $tempFilename) {
throw new CreateTemporaryFileException(); // @codeCoverageIgnore
}
$zip = new ZipArchive();
if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename) !== false) {
$imageContent = $zip->getFromName($imageFilename);
if ($imageContent !== false) {
file_put_contents($tempFilename, $imageContent);
$imageData = getimagesize($tempFilename);
unlink($tempFilename);
}
}
$zip->close();
}
return $imageData;
}
/**
* get image size from string
*
* @param string $source
*
* @codeCoverageIgnore this method is just a replacement for getimagesizefromstring which exists only as of PHP 5.4
*/
private function getStringImageSize($source)
{
$result = false;
if (!function_exists('getimagesizefromstring')) {
$uri = 'data://application/octet-stream;base64,' . base64_encode($source);
$result = @getimagesize($uri);
} else {
$result = @getimagesizefromstring($source);
}
return $result;
}
/**
* Set image functions and extensions.
*/
private function setFunctions()
{
switch ($this->imageType) {
case 'image/png':
$this->imageCreateFunc = $this->sourceType == self::SOURCE_STRING ? 'imagecreatefromstring' : 'imagecreatefrompng';
$this->imageFunc = 'imagepng';
$this->imageExtension = 'png';
break;
case 'image/gif':
$this->imageCreateFunc = $this->sourceType == self::SOURCE_STRING ? 'imagecreatefromstring' : 'imagecreatefromgif';
$this->imageFunc = 'imagegif';
$this->imageExtension = 'gif';
break;
case 'image/jpeg':
case 'image/jpg':
$this->imageCreateFunc = $this->sourceType == self::SOURCE_STRING ? 'imagecreatefromstring' : 'imagecreatefromjpeg';
$this->imageFunc = 'imagejpeg';
$this->imageExtension = 'jpg';
break;
case 'image/bmp':
case 'image/x-ms-bmp':
$this->imageType = 'image/bmp';
$this->imageExtension = 'bmp';
break;
case 'image/tiff':
$this->imageExtension = 'tif';
break;
}
}
/**
* Set proportional width/height if one dimension not available.
*
* @param int $actualWidth
* @param int $actualHeight
*/
private function setProportionalSize($actualWidth, $actualHeight)
{
$styleWidth = $this->style->getWidth();
$styleHeight = $this->style->getHeight();
if (!($styleWidth && $styleHeight)) {
if ($styleWidth == null && $styleHeight == null) {
$this->style->setWidth($actualWidth);
$this->style->setHeight($actualHeight);
} elseif ($styleWidth) {
$this->style->setHeight($actualHeight * ($styleWidth / $actualWidth));
} else {
$this->style->setWidth($actualWidth * ($styleHeight / $actualHeight));
}
}
}
/**
* Get is watermark
*
* @deprecated 0.10.0
*
* @codeCoverageIgnore
*/
public function getIsWatermark()
{
return $this->isWatermark();
}
/**
* Get is memory image
*
* @deprecated 0.10.0
*
* @codeCoverageIgnore
*/
public function getIsMemImage()
{
return $this->isMemImage();
}
}

53
addons/qingdong/library/PhpWord/Element/Line.php

@ -0,0 +1,53 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Line as LineStyle;
/**
* Line element
*/
class Line extends AbstractElement
{
/**
* Line style
*
* @var \PhpOffice\PhpWord\Style\Line
*/
private $style;
/**
* Create new line element
*
* @param mixed $style
*/
public function __construct($style = null)
{
$this->style = $this->setNewStyle(new LineStyle(), $style);
}
/**
* Get line style
*
* @return \PhpOffice\PhpWord\Style\Line
*/
public function getStyle()
{
return $this->style;
}
}

180
addons/qingdong/library/PhpWord/Element/Link.php

@ -0,0 +1,180 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Shared\Text as SharedText;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
/**
* Link element
*/
class Link extends AbstractElement
{
/**
* Link source
*
* @var string
*/
private $source;
/**
* Link text
*
* @var string
*/
private $text;
/**
* Font style
*
* @var string|\PhpOffice\PhpWord\Style\Font
*/
private $fontStyle;
/**
* Paragraph style
*
* @var string|\PhpOffice\PhpWord\Style\Paragraph
*/
private $paragraphStyle;
/**
* Has media relation flag; true for Link, Image, and Object
*
* @var bool
*/
protected $mediaRelation = true;
/**
* Has internal flag - anchor to internal bookmark
*
* @var bool
*/
protected $internal = false;
/**
* Create a new Link Element
*
* @param string $source
* @param string $text
* @param mixed $fontStyle
* @param mixed $paragraphStyle
* @param bool $internal
*/
public function __construct($source, $text = null, $fontStyle = null, $paragraphStyle = null, $internal = false)
{
$this->source = SharedText::toUTF8($source);
$this->text = is_null($text) ? $this->source : SharedText::toUTF8($text);
$this->fontStyle = $this->setNewStyle(new Font('text'), $fontStyle);
$this->paragraphStyle = $this->setNewStyle(new Paragraph(), $paragraphStyle);
$this->internal = $internal;
}
/**
* Get link source
*
* @return string
*/
public function getSource()
{
return $this->source;
}
/**
* Get link text
*
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* Get Text style
*
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function getFontStyle()
{
return $this->fontStyle;
}
/**
* Get Paragraph style
*
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function getParagraphStyle()
{
return $this->paragraphStyle;
}
/**
* Get link target
*
* @deprecated 0.12.0
*
* @return string
*
* @codeCoverageIgnore
*/
public function getTarget()
{
return $this->source;
}
/**
* Get Link source
*
* @deprecated 0.10.0
*
* @return string
*
* @codeCoverageIgnore
*/
public function getLinkSrc()
{
return $this->getSource();
}
/**
* Get Link name
*
* @deprecated 0.10.0
*
* @return string
*
* @codeCoverageIgnore
*/
public function getLinkName()
{
return $this->getText();
}
/**
* is internal
*
* @return bool
*/
public function isInternal()
{
return $this->internal;
}
}

111
addons/qingdong/library/PhpWord/Element/ListItem.php

@ -0,0 +1,111 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Shared\Text as SharedText;
use PhpOffice\PhpWord\Style\ListItem as ListItemStyle;
/**
* List item element
*/
class ListItem extends AbstractElement
{
/**
* Element style
*
* @var \PhpOffice\PhpWord\Style\ListItem
*/
private $style;
/**
* Text object
*
* @var \PhpOffice\PhpWord\Element\Text
*/
private $textObject;
/**
* Depth
*
* @var int
*/
private $depth;
/**
* Create a new ListItem
*
* @param string $text
* @param int $depth
* @param mixed $fontStyle
* @param array|string|null $listStyle
* @param mixed $paragraphStyle
*/
public function __construct($text, $depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null)
{
$this->textObject = new Text(SharedText::toUTF8($text), $fontStyle, $paragraphStyle);
$this->depth = $depth;
// Version >= 0.10.0 will pass numbering style name. Older version will use old method
if (!is_null($listStyle) && is_string($listStyle)) {
$this->style = new ListItemStyle($listStyle); // @codeCoverageIgnore
} else {
$this->style = $this->setNewStyle(new ListItemStyle(), $listStyle, true);
}
}
/**
* Get style
*
* @return \PhpOffice\PhpWord\Style\ListItem
*/
public function getStyle()
{
return $this->style;
}
/**
* Get Text object
*
* @return \PhpOffice\PhpWord\Element\Text
*/
public function getTextObject()
{
return $this->textObject;
}
/**
* Get depth
*
* @return int
*/
public function getDepth()
{
return $this->depth;
}
/**
* Get text
*
* @return string
* @since 0.11.0
*/
public function getText()
{
return $this->textObject->getText();
}
}

85
addons/qingdong/library/PhpWord/Element/ListItemRun.php

@ -0,0 +1,85 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\ListItem as ListItemStyle;
/**
* List item element
*/
class ListItemRun extends TextRun
{
/**
* @var string Container type
*/
protected $container = 'ListItemRun';
/**
* ListItem Style
*
* @var \PhpOffice\PhpWord\Style\ListItem
*/
private $style;
/**
* ListItem Depth
*
* @var int
*/
private $depth;
/**
* Create a new ListItem
*
* @param int $depth
* @param array|string|null $listStyle
* @param mixed $paragraphStyle
*/
public function __construct($depth = 0, $listStyle = null, $paragraphStyle = null)
{
$this->depth = $depth;
// Version >= 0.10.0 will pass numbering style name. Older version will use old method
if (!is_null($listStyle) && is_string($listStyle)) {
$this->style = new ListItemStyle($listStyle);
} else {
$this->style = $this->setNewStyle(new ListItemStyle(), $listStyle, true);
}
parent::__construct($paragraphStyle);
}
/**
* Get ListItem style.
*
* @return \PhpOffice\PhpWord\Style\ListItem
*/
public function getStyle()
{
return $this->style;
}
/**
* Get ListItem depth.
*
* @return int
*/
public function getDepth()
{
return $this->depth;
}
}

169
addons/qingdong/library/PhpWord/Element/OLEObject.php

@ -0,0 +1,169 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Exception\InvalidObjectException;
use PhpOffice\PhpWord\Style\Image as ImageStyle;
/**
* OLEObject element
*/
class OLEObject extends AbstractElement
{
/**
* Ole-Object Src
*
* @var string
*/
private $source;
/**
* Image Style
*
* @var \PhpOffice\PhpWord\Style\Image
*/
private $style;
/**
* Icon
*
* @var string
*/
private $icon;
/**
* Image Relation ID
*
* @var int
*/
private $imageRelationId;
/**
* Has media relation flag; true for Link, Image, and Object
*
* @var bool
*/
protected $mediaRelation = true;
/**
* Create a new Ole-Object Element
*
* @param string $source
* @param mixed $style
*
* @throws \PhpOffice\PhpWord\Exception\InvalidObjectException
*/
public function __construct($source, $style = null)
{
$supportedTypes = array('xls', 'doc', 'ppt', 'xlsx', 'docx', 'pptx');
$pathInfo = pathinfo($source);
if (file_exists($source) && in_array($pathInfo['extension'], $supportedTypes)) {
$ext = $pathInfo['extension'];
if (strlen($ext) == 4 && strtolower(substr($ext, -1)) == 'x') {
$ext = substr($ext, 0, -1);
}
$this->source = $source;
$this->style = $this->setNewStyle(new ImageStyle(), $style, true);
$this->icon = realpath(__DIR__ . "/../resources/{$ext}.png");
return;
}
throw new InvalidObjectException();
}
/**
* Get object source
*
* @return string
*/
public function getSource()
{
return $this->source;
}
/**
* Get object style
*
* @return \PhpOffice\PhpWord\Style\Image
*/
public function getStyle()
{
return $this->style;
}
/**
* Get object icon
*
* @return string
*/
public function getIcon()
{
return $this->icon;
}
/**
* Get image relation ID
*
* @return int
*/
public function getImageRelationId()
{
return $this->imageRelationId;
}
/**
* Set Image Relation ID.
*
* @param int $rId
*/
public function setImageRelationId($rId)
{
$this->imageRelationId = $rId;
}
/**
* Get Object ID
*
* @deprecated 0.10.0
*
* @return int
*
* @codeCoverageIgnore
*/
public function getObjectId()
{
return $this->relationId + 1325353440;
}
/**
* Set Object ID
*
* @deprecated 0.10.0
*
* @param int $objId
*
* @codeCoverageIgnore
*/
public function setObjectId($objId)
{
$this->relationId = $objId;
}
}

31
addons/qingdong/library/PhpWord/Element/PageBreak.php

@ -0,0 +1,31 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Page break element
*/
class PageBreak extends AbstractElement
{
/**
* Create new page break
*/
public function __construct()
{
}
}

98
addons/qingdong/library/PhpWord/Element/PreserveText.php

@ -0,0 +1,98 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Shared\Text as SharedText;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
/**
* Preserve text/field element
*/
class PreserveText extends AbstractElement
{
/**
* Text content
*
* @var string|array
*/
private $text;
/**
* Text style
*
* @var string|\PhpOffice\PhpWord\Style\Font
*/
private $fontStyle;
/**
* Paragraph style
*
* @var string|\PhpOffice\PhpWord\Style\Paragraph
*/
private $paragraphStyle;
/**
* Create a new Preserve Text Element
*
* @param string $text
* @param mixed $fontStyle
* @param mixed $paragraphStyle
*/
public function __construct($text = null, $fontStyle = null, $paragraphStyle = null)
{
$this->fontStyle = $this->setNewStyle(new Font('text'), $fontStyle);
$this->paragraphStyle = $this->setNewStyle(new Paragraph(), $paragraphStyle);
$this->text = SharedText::toUTF8($text);
$matches = preg_split('/({.*?})/', $this->text, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
if (isset($matches[0])) {
$this->text = $matches;
}
}
/**
* Get Text style
*
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function getFontStyle()
{
return $this->fontStyle;
}
/**
* Get Paragraph style
*
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function getParagraphStyle()
{
return $this->paragraphStyle;
}
/**
* Get Text content
*
* @return string|array
*/
public function getText()
{
return $this->text;
}
}

107
addons/qingdong/library/PhpWord/Element/Row.php

@ -0,0 +1,107 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Row as RowStyle;
/**
* Table row element
*
* @since 0.8.0
*/
class Row extends AbstractElement
{
/**
* Row height
*
* @var int
*/
private $height = null;
/**
* Row style
*
* @var \PhpOffice\PhpWord\Style\Row
*/
private $style;
/**
* Row cells
*
* @var \PhpOffice\PhpWord\Element\Cell[]
*/
private $cells = array();
/**
* Create a new table row
*
* @param int $height
* @param mixed $style
*/
public function __construct($height = null, $style = null)
{
$this->height = $height;
$this->style = $this->setNewStyle(new RowStyle(), $style, true);
}
/**
* Add a cell
*
* @param int $width
* @param mixed $style
* @return \PhpOffice\PhpWord\Element\Cell
*/
public function addCell($width = null, $style = null)
{
$cell = new Cell($width, $style);
$cell->setParentContainer($this);
$this->cells[] = $cell;
return $cell;
}
/**
* Get all cells
*
* @return \PhpOffice\PhpWord\Element\Cell[]
*/
public function getCells()
{
return $this->cells;
}
/**
* Get row style
*
* @return \PhpOffice\PhpWord\Style\Row
*/
public function getStyle()
{
return $this->style;
}
/**
* Get row height
*
* @return int
*/
public function getHeight()
{
return $this->height;
}
}

190
addons/qingdong/library/PhpWord/Element/SDT.php

@ -0,0 +1,190 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* Structured document tag (SDT) element
*
* @since 0.12.0
*/
class SDT extends Text
{
/**
* Form field type: comboBox|dropDownList|date
*
* @var string
*/
private $type;
/**
* Value
*
* @var string|bool|int
*/
private $value;
/**
* CheckBox/DropDown list entries
*
* @var array
*/
private $listItems = array();
/**
* Alias
*
* @var string
*/
private $alias;
/**
* Tag
*
* @var string
*/
private $tag;
/**
* Create new instance
*
* @param string $type
* @param mixed $fontStyle
* @param mixed $paragraphStyle
*/
public function __construct($type, $fontStyle = null, $paragraphStyle = null)
{
parent::__construct(null, $fontStyle, $paragraphStyle);
$this->setType($type);
}
/**
* Get type
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Set type
*
* @param string $value
* @return self
*/
public function setType($value)
{
$enum = array('plainText', 'comboBox', 'dropDownList', 'date');
$this->type = $this->setEnumVal($value, $enum, 'comboBox');
return $this;
}
/**
* Get value
*
* @return string|bool|int
*/
public function getValue()
{
return $this->value;
}
/**
* Set value
*
* @param string|bool|int $value
* @return self
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get listItems
*
* @return array
*/
public function getListItems()
{
return $this->listItems;
}
/**
* Set listItems
*
* @param array $value
* @return self
*/
public function setListItems($value)
{
$this->listItems = $value;
return $this;
}
/**
* Get tag
*
* @return string
*/
public function getTag()
{
return $this->tag;
}
/**
* Set tag
*
* @param string $tag
* @return self
*/
public function setTag($tag)
{
$this->tag = $tag;
return $this;
}
/**
* Get alias
*
* @return string
*/
public function getAlias()
{
return $this->alias;
}
/**
* Set alias
*
* @param string $alias
* @return self
*/
public function setAlias($alias)
{
$this->alias = $alias;
return $this;
}
}

307
addons/qingdong/library/PhpWord/Element/Section.php

@ -0,0 +1,307 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\ComplexType\FootnoteProperties;
use PhpOffice\PhpWord\Style\Section as SectionStyle;
class Section extends AbstractContainer
{
/**
* @var string Container type
*/
protected $container = 'Section';
/**
* Section style
*
* @var \PhpOffice\PhpWord\Style\Section
*/
private $style;
/**
* Section headers, indexed from 1, not zero
*
* @var Header[]
*/
private $headers = array();
/**
* Section footers, indexed from 1, not zero
*
* @var Footer[]
*/
private $footers = array();
/**
* The properties for the footnote of this section
*
* @var FootnoteProperties
*/
private $footnoteProperties;
/**
* Create new instance
*
* @param int $sectionCount
* @param null|array|\PhpOffice\PhpWord\Style $style
*/
public function __construct($sectionCount, $style = null)
{
$this->sectionId = $sectionCount;
$this->setDocPart($this->container, $this->sectionId);
if (null === $style) {
$style = new SectionStyle();
}
$this->style = $this->setNewStyle(new SectionStyle(), $style);
}
/**
* Set section style.
*
* @param array $style
*/
public function setStyle($style = null)
{
if (!is_null($style) && is_array($style)) {
$this->style->setStyleByArray($style);
}
}
/**
* Get section style
*
* @return \PhpOffice\PhpWord\Style\Section
*/
public function getStyle()
{
return $this->style;
}
/**
* Add header
*
* @since 0.10.0
*
* @param string $type
*
* @return Header
*/
public function addHeader($type = Header::AUTO)
{
return $this->addHeaderFooter($type, true);
}
/**
* Add footer
*
* @since 0.10.0
*
* @param string $type
*
* @return Footer
*/
public function addFooter($type = Header::AUTO)
{
return $this->addHeaderFooter($type, false);
}
/**
* Get header elements
*
* @return Header[]
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Get footer elements
*
* @return Footer[]
*/
public function getFooters()
{
return $this->footers;
}
/**
* Get the footnote properties
*
* @return FootnoteProperties
*/
public function getFootnoteProperties()
{
return $this->footnoteProperties;
}
/**
* Get the footnote properties
*
* @deprecated Use the `getFootnoteProperties` method instead
*
* @return FootnoteProperties
*
* @codeCoverageIgnore
*/
public function getFootnotePropoperties()
{
return $this->footnoteProperties;
}
/**
* Set the footnote properties
*
* @param FootnoteProperties $footnoteProperties
*/
public function setFootnoteProperties(FootnoteProperties $footnoteProperties = null)
{
$this->footnoteProperties = $footnoteProperties;
}
/**
* Is there a header for this section that is for the first page only?
*
* If any of the Header instances have a type of Header::FIRST then this method returns true.
* False otherwise.
*
* @return bool
*/
public function hasDifferentFirstPage()
{
foreach ($this->headers as $header) {
if ($header->getType() == Header::FIRST) {
return true;
}
}
foreach ($this->footers as $footer) {
if ($footer->getType() == Header::FIRST) {
return true;
}
}
return false;
}
/**
* Add header/footer
*
* @since 0.10.0
*
* @param string $type
* @param bool $header
*
* @throws \Exception
*
* @return Header|Footer
*/
private function addHeaderFooter($type = Header::AUTO, $header = true)
{
$containerClass = substr(get_class($this), 0, strrpos(get_class($this), '\\')) . '\\' .
($header ? 'Header' : 'Footer');
$collectionArray = $header ? 'headers' : 'footers';
$collection = &$this->$collectionArray;
if (in_array($type, array(Header::AUTO, Header::FIRST, Header::EVEN))) {
$index = count($collection);
/** @var \PhpOffice\PhpWord\Element\AbstractContainer $container Type hint */
$container = new $containerClass($this->sectionId, ++$index, $type);
$container->setPhpWord($this->phpWord);
$collection[$index] = $container;
return $container;
}
throw new \Exception('Invalid header/footer type.');
}
/**
* Set section style
*
* @deprecated 0.12.0
*
* @param array $settings
*
* @codeCoverageIgnore
*/
public function setSettings($settings = null)
{
$this->setStyle($settings);
}
/**
* Get section style
*
* @deprecated 0.12.0
*
* @return \PhpOffice\PhpWord\Style\Section
*
* @codeCoverageIgnore
*/
public function getSettings()
{
return $this->getStyle();
}
/**
* Create header
*
* @deprecated 0.10.0
*
* @return Header
*
* @codeCoverageIgnore
*/
public function createHeader()
{
return $this->addHeader();
}
/**
* Create footer
*
* @deprecated 0.10.0
*
* @return Footer
*
* @codeCoverageIgnore
*/
public function createFooter()
{
return $this->addFooter();
}
/**
* Get footer
*
* @deprecated 0.10.0
*
* @return Footer
*
* @codeCoverageIgnore
*/
public function getFooter()
{
if (empty($this->footers)) {
return null;
}
return $this->footers[1];
}
}

88
addons/qingdong/library/PhpWord/Element/Shape.php

@ -0,0 +1,88 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Shape as ShapeStyle;
/**
* Shape element
*
* @since 0.12.0
*/
class Shape extends AbstractElement
{
/**
* Shape type arc|curve|line|polyline|rect|oval
*
* @var string
*/
private $type;
/**
* Shape style
*
* @var \PhpOffice\PhpWord\Style\Shape
*/
private $style;
/**
* Create new instance
*
* @param string $type
* @param mixed $style
*/
public function __construct($type, $style = null)
{
$this->setType($type);
$this->style = $this->setNewStyle(new ShapeStyle(), $style);
}
/**
* Get type
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Set pattern
*
* @param string $value
* @return self
*/
public function setType($value = null)
{
$enum = array('arc', 'curve', 'line', 'polyline', 'rect', 'oval');
$this->type = $this->setEnumVal($value, $enum, null);
return $this;
}
/**
* Get shape style
*
* @return \PhpOffice\PhpWord\Style\Shape
*/
public function getStyle()
{
return $this->style;
}
}

169
addons/qingdong/library/PhpWord/Element/TOC.php

@ -0,0 +1,169 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\TOC as TOCStyle;
/**
* Table of contents
*/
class TOC extends AbstractElement
{
/**
* TOC style
*
* @var \PhpOffice\PhpWord\Style\TOC
*/
private $TOCStyle;
/**
* Font style
*
* @var \PhpOffice\PhpWord\Style\Font|string
*/
private $fontStyle;
/**
* Min title depth to show
*
* @var int
*/
private $minDepth = 1;
/**
* Max title depth to show
*
* @var int
*/
private $maxDepth = 9;
/**
* Create a new Table-of-Contents Element
*
* @param mixed $fontStyle
* @param array $tocStyle
* @param int $minDepth
* @param int $maxDepth
*/
public function __construct($fontStyle = null, $tocStyle = null, $minDepth = 1, $maxDepth = 9)
{
$this->TOCStyle = new TOCStyle();
if (!is_null($tocStyle) && is_array($tocStyle)) {
$this->TOCStyle->setStyleByArray($tocStyle);
}
if (!is_null($fontStyle) && is_array($fontStyle)) {
$this->fontStyle = new Font();
$this->fontStyle->setStyleByArray($fontStyle);
} else {
$this->fontStyle = $fontStyle;
}
$this->minDepth = $minDepth;
$this->maxDepth = $maxDepth;
}
/**
* Get all titles
*
* @return array
*/
public function getTitles()
{
if (!$this->phpWord instanceof PhpWord) {
return array();
}
$titles = $this->phpWord->getTitles()->getItems();
foreach ($titles as $i => $title) {
/** @var \PhpOffice\PhpWord\Element\Title $title Type hint */
$depth = $title->getDepth();
if ($this->minDepth > $depth) {
unset($titles[$i]);
}
if (($this->maxDepth != 0) && ($this->maxDepth < $depth)) {
unset($titles[$i]);
}
}
return $titles;
}
/**
* Get TOC Style
*
* @return \PhpOffice\PhpWord\Style\TOC
*/
public function getStyleTOC()
{
return $this->TOCStyle;
}
/**
* Get Font Style
*
* @return \PhpOffice\PhpWord\Style\Font|string
*/
public function getStyleFont()
{
return $this->fontStyle;
}
/**
* Set max depth.
*
* @param int $value
*/
public function setMaxDepth($value)
{
$this->maxDepth = $value;
}
/**
* Get Max Depth
*
* @return int Max depth of titles
*/
public function getMaxDepth()
{
return $this->maxDepth;
}
/**
* Set min depth.
*
* @param int $value
*/
public function setMinDepth($value)
{
$this->minDepth = $value;
}
/**
* Get Min Depth
*
* @return int Min depth of titles
*/
public function getMinDepth()
{
return $this->minDepth;
}
}

174
addons/qingdong/library/PhpWord/Element/Table.php

@ -0,0 +1,174 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Table as TableStyle;
/**
* Table element
*/
class Table extends AbstractElement
{
/**
* Table style
*
* @var \PhpOffice\PhpWord\Style\Table
*/
private $style;
/**
* Table rows
*
* @var \PhpOffice\PhpWord\Element\Row[]
*/
private $rows = array();
/**
* Table width
*
* @var int
*/
private $width = null;
/**
* Create a new table
*
* @param mixed $style
*/
public function __construct($style = null)
{
$this->style = $this->setNewStyle(new TableStyle(), $style);
}
/**
* Add a row
*
* @param int $height
* @param mixed $style
* @return \PhpOffice\PhpWord\Element\Row
*/
public function addRow($height = null, $style = null)
{
$row = new Row($height, $style);
$row->setParentContainer($this);
$this->rows[] = $row;
return $row;
}
/**
* Add a cell
*
* @param int $width
* @param mixed $style
* @return \PhpOffice\PhpWord\Element\Cell
*/
public function addCell($width = null, $style = null)
{
$index = count($this->rows) - 1;
$row = $this->rows[$index];
$cell = $row->addCell($width, $style);
return $cell;
}
/**
* Get all rows
*
* @return \PhpOffice\PhpWord\Element\Row[]
*/
public function getRows()
{
return $this->rows;
}
/**
* Get table style
*
* @return \PhpOffice\PhpWord\Style\Table
*/
public function getStyle()
{
return $this->style;
}
/**
* Get table width
*
* @return int
*/
public function getWidth()
{
return $this->width;
}
/**
* Set table width.
*
* @param int $width
*/
public function setWidth($width)
{
$this->width = $width;
}
/**
* Get column count
*
* @return int
*/
public function countColumns()
{
$columnCount = 0;
$rowCount = count($this->rows);
for ($i = 0; $i < $rowCount; $i++) {
/** @var \PhpOffice\PhpWord\Element\Row $row Type hint */
$row = $this->rows[$i];
$cellCount = count($row->getCells());
if ($columnCount < $cellCount) {
$columnCount = $cellCount;
}
}
return $columnCount;
}
/**
* The first declared cell width for each column
*
* @return int[]
*/
public function findFirstDefinedCellWidths()
{
$cellWidths = array();
foreach ($this->rows as $row) {
$cells = $row->getCells();
if (count($cells) <= count($cellWidths)) {
continue;
}
$cellWidths = array();
foreach ($cells as $cell) {
$cellWidths[] = $cell->getWidth();
}
}
return $cellWidths;
}
}

153
addons/qingdong/library/PhpWord/Element/Text.php

@ -0,0 +1,153 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Shared\Text as SharedText;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
/**
* Text element
*/
class Text extends AbstractElement
{
/**
* Text content
*
* @var string
*/
protected $text;
/**
* Text style
*
* @var string|\PhpOffice\PhpWord\Style\Font
*/
protected $fontStyle;
/**
* Paragraph style
*
* @var string|\PhpOffice\PhpWord\Style\Paragraph
*/
protected $paragraphStyle;
/**
* Create a new Text Element
*
* @param string $text
* @param mixed $fontStyle
* @param mixed $paragraphStyle
*/
public function __construct($text = null, $fontStyle = null, $paragraphStyle = null)
{
$this->setText($text);
$paragraphStyle = $this->setParagraphStyle($paragraphStyle);
$this->setFontStyle($fontStyle, $paragraphStyle);
}
/**
* Set Text style
*
* @param string|array|\PhpOffice\PhpWord\Style\Font $style
* @param string|array|\PhpOffice\PhpWord\Style\Paragraph $paragraphStyle
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function setFontStyle($style = null, $paragraphStyle = null)
{
if ($style instanceof Font) {
$this->fontStyle = $style;
$this->setParagraphStyle($paragraphStyle);
} elseif (is_array($style)) {
$this->fontStyle = new Font('text', $paragraphStyle);
$this->fontStyle->setStyleByArray($style);
} elseif (null === $style) {
$this->fontStyle = new Font('text', $paragraphStyle);
} else {
$this->fontStyle = $style;
$this->setParagraphStyle($paragraphStyle);
}
return $this->fontStyle;
}
/**
* Get Text style
*
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function getFontStyle()
{
return $this->fontStyle;
}
/**
* Set Paragraph style
*
* @param string|array|\PhpOffice\PhpWord\Style\Paragraph $style
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function setParagraphStyle($style = null)
{
if (is_array($style)) {
$this->paragraphStyle = new Paragraph();
$this->paragraphStyle->setStyleByArray($style);
} elseif ($style instanceof Paragraph) {
$this->paragraphStyle = $style;
} elseif (null === $style) {
$this->paragraphStyle = new Paragraph();
} else {
$this->paragraphStyle = $style;
}
return $this->paragraphStyle;
}
/**
* Get Paragraph style
*
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function getParagraphStyle()
{
return $this->paragraphStyle;
}
/**
* Set text content
*
* @param string $text
* @return self
*/
public function setText($text)
{
$this->text = SharedText::toUTF8($text);
return $this;
}
/**
* Get Text content
*
* @return string
*/
public function getText()
{
return $this->text;
}
}

60
addons/qingdong/library/PhpWord/Element/TextBox.php

@ -0,0 +1,60 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\TextBox as TextBoxStyle;
/**
* TextBox element
*
* @since 0.11.0
*/
class TextBox extends AbstractContainer
{
/**
* @var string Container type
*/
protected $container = 'TextBox';
/**
* TextBox style
*
* @var \PhpOffice\PhpWord\Style\TextBox
*/
private $style;
/**
* Create a new textbox
*
* @param mixed $style
*/
public function __construct($style = null)
{
$this->style = $this->setNewStyle(new TextBoxStyle(), $style);
}
/**
* Get textbox style
*
* @return \PhpOffice\PhpWord\Style\TextBox
*/
public function getStyle()
{
return $this->style;
}
}

130
addons/qingdong/library/PhpWord/Element/TextBreak.php

@ -0,0 +1,130 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
/**
* Text break element
*/
class TextBreak extends AbstractElement
{
/**
* Paragraph style
*
* @var string|\PhpOffice\PhpWord\Style\Paragraph
*/
private $paragraphStyle = null;
/**
* Text style
*
* @var string|\PhpOffice\PhpWord\Style\Font
*/
private $fontStyle = null;
/**
* Create a new TextBreak Element
*
* @param mixed $fontStyle
* @param mixed $paragraphStyle
*/
public function __construct($fontStyle = null, $paragraphStyle = null)
{
if (!is_null($paragraphStyle)) {
$paragraphStyle = $this->setParagraphStyle($paragraphStyle);
}
if (!is_null($fontStyle)) {
$this->setFontStyle($fontStyle, $paragraphStyle);
}
}
/**
* Set Text style
*
* @param mixed $style
* @param mixed $paragraphStyle
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function setFontStyle($style = null, $paragraphStyle = null)
{
if ($style instanceof Font) {
$this->fontStyle = $style;
$this->setParagraphStyle($paragraphStyle);
} elseif (is_array($style)) {
$this->fontStyle = new Font('text', $paragraphStyle);
$this->fontStyle->setStyleByArray($style);
} else {
$this->fontStyle = $style;
$this->setParagraphStyle($paragraphStyle);
}
return $this->fontStyle;
}
/**
* Get Text style
*
* @return string|\PhpOffice\PhpWord\Style\Font
*/
public function getFontStyle()
{
return $this->fontStyle;
}
/**
* Set Paragraph style
*
* @param string|array|\PhpOffice\PhpWord\Style\Paragraph $style
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function setParagraphStyle($style = null)
{
if (is_array($style)) {
$this->paragraphStyle = new Paragraph();
$this->paragraphStyle->setStyleByArray($style);
} elseif ($style instanceof Paragraph) {
$this->paragraphStyle = $style;
} else {
$this->paragraphStyle = $style;
}
return $this->paragraphStyle;
}
/**
* Get Paragraph style
*
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function getParagraphStyle()
{
return $this->paragraphStyle;
}
/**
* Has font/paragraph style defined
*
* @return bool
*/
public function hasStyle()
{
return !is_null($this->fontStyle) || !is_null($this->paragraphStyle);
}
}

80
addons/qingdong/library/PhpWord/Element/TextRun.php

@ -0,0 +1,80 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Style\Paragraph;
/**
* Textrun/paragraph element
*/
class TextRun extends AbstractContainer
{
/**
* @var string Container type
*/
protected $container = 'TextRun';
/**
* Paragraph style
*
* @var string|\PhpOffice\PhpWord\Style\Paragraph
*/
protected $paragraphStyle;
/**
* Create new instance
*
* @param string|array|\PhpOffice\PhpWord\Style\Paragraph $paragraphStyle
*/
public function __construct($paragraphStyle = null)
{
$this->paragraphStyle = $this->setParagraphStyle($paragraphStyle);
}
/**
* Get Paragraph style
*
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function getParagraphStyle()
{
return $this->paragraphStyle;
}
/**
* Set Paragraph style
*
* @param string|array|\PhpOffice\PhpWord\Style\Paragraph $style
* @return string|\PhpOffice\PhpWord\Style\Paragraph
*/
public function setParagraphStyle($style = null)
{
if (is_array($style)) {
$this->paragraphStyle = new Paragraph();
$this->paragraphStyle->setStyleByArray($style);
} elseif ($style instanceof Paragraph) {
$this->paragraphStyle = $style;
} elseif (null === $style) {
$this->paragraphStyle = new Paragraph();
} else {
$this->paragraphStyle = $style;
}
return $this->paragraphStyle;
}
}

108
addons/qingdong/library/PhpWord/Element/Title.php

@ -0,0 +1,108 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Shared\Text as SharedText;
use PhpOffice\PhpWord\Style;
/**
* Title element
*/
class Title extends AbstractElement
{
/**
* Title Text content
*
* @var string|TextRun
*/
private $text;
/**
* Title depth
*
* @var int
*/
private $depth = 1;
/**
* Name of the heading style, e.g. 'Heading1'
*
* @var string
*/
private $style;
/**
* Is part of collection
*
* @var bool
*/
protected $collectionRelation = true;
/**
* Create a new Title Element
*
* @param string|TextRun $text
* @param int $depth
*/
public function __construct($text, $depth = 1)
{
if (is_string($text)) {
$this->text = SharedText::toUTF8($text);
} elseif ($text instanceof TextRun) {
$this->text = $text;
} else {
throw new \InvalidArgumentException('Invalid text, should be a string or a TextRun');
}
$this->depth = $depth;
$styleName = $depth === 0 ? 'Title' : "Heading_{$this->depth}";
if (array_key_exists($styleName, Style::getStyles())) {
$this->style = str_replace('_', '', $styleName);
}
}
/**
* Get Title Text content
*
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* Get depth
*
* @return int
*/
public function getDepth()
{
return $this->depth;
}
/**
* Get Title style
*
* @return string
*/
public function getStyle()
{
return $this->style;
}
}

101
addons/qingdong/library/PhpWord/Element/TrackChange.php

@ -0,0 +1,101 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Element;
/**
* TrackChange element
* @see http://datypic.com/sc/ooxml/t-w_CT_TrackChange.html
* @see http://datypic.com/sc/ooxml/t-w_CT_RunTrackChange.html
*/
class TrackChange extends AbstractContainer
{
const INSERTED = 'INSERTED';
const DELETED = 'DELETED';
/**
* @var string Container type
*/
protected $container = 'TrackChange';
/**
* The type of change, (insert or delete), not applicable for PhpOffice\PhpWord\Element\Comment
*
* @var string
*/
private $changeType;
/**
* Author
*
* @var string
*/
private $author;
/**
* Date
*
* @var \DateTime
*/
private $date;
/**
* Create a new TrackChange Element
*
* @param string $changeType
* @param string $author
* @param null|int|bool|\DateTime $date
*/
public function __construct($changeType = null, $author = null, $date = null)
{
$this->changeType = $changeType;
$this->author = $author;
if ($date !== null && $date !== false) {
$this->date = ($date instanceof \DateTime) ? $date : new \DateTime('@' . $date);
}
}
/**
* Get TrackChange Author
*
* @return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* Get TrackChange Date
*
* @return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Get the Change type
*
* @return string
*/
public function getChangeType()
{
return $this->changeType;
}
}

46
addons/qingdong/library/PhpWord/Escaper/AbstractEscaper.php

@ -0,0 +1,46 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Escaper;
/**
* @since 0.13.0
*
* @codeCoverageIgnore
*/
abstract class AbstractEscaper implements EscaperInterface
{
/**
* @param string $input
*
* @return string
*/
abstract protected function escapeSingleValue($input);
public function escape($input)
{
if (is_array($input)) {
foreach ($input as &$item) {
$item = $this->escapeSingleValue($item);
}
} else {
$input = $this->escapeSingleValue($input);
}
return $input;
}
}

33
addons/qingdong/library/PhpWord/Escaper/EscaperInterface.php

@ -0,0 +1,33 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Escaper;
/**
* @since 0.13.0
*
* @codeCoverageIgnore
*/
interface EscaperInterface
{
/**
* @param mixed $input
*
* @return mixed
*/
public function escape($input);
}

33
addons/qingdong/library/PhpWord/Escaper/RegExp.php

@ -0,0 +1,33 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Escaper;
/**
* @since 0.13.0
*
* @codeCoverageIgnore
*/
class RegExp extends AbstractEscaper
{
const REG_EXP_DELIMITER = '/';
protected function escapeSingleValue($input)
{
return self::REG_EXP_DELIMITER . preg_quote($input, self::REG_EXP_DELIMITER) . self::REG_EXP_DELIMITER . 'u';
}
}

97
addons/qingdong/library/PhpWord/Escaper/Rtf.php

@ -0,0 +1,97 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Escaper;
/**
* @since 0.13.0
*
* @codeCoverageIgnore
*/
class Rtf extends AbstractEscaper
{
protected function escapeAsciiCharacter($code)
{
if ($code == 9) {
return '{\\tab}';
}
if (0x20 > $code || $code >= 0x80) {
return '{\\u' . $code . '}';
}
if ($code == 123 || $code == 125 || $code == 92) { // open or close brace or backslash
return '\\' . chr($code);
}
return chr($code);
}
protected function escapeMultibyteCharacter($code)
{
return '\\uc0{\\u' . $code . '}';
}
/**
* @see http://www.randomchaos.com/documents/?source=php_and_unicode
* @param string $input
*/
protected function escapeSingleValue($input)
{
$escapedValue = '';
$numberOfBytes = 1;
$bytes = array();
for ($i = 0; $i < strlen($input); ++$i) {
$character = $input[$i];
$asciiCode = ord($character);
if ($asciiCode < 128) {
$escapedValue .= $this->escapeAsciiCharacter($asciiCode);
} else {
if (0 == count($bytes)) {
if ($asciiCode < 224) {
$numberOfBytes = 2;
} elseif ($asciiCode < 240) {
$numberOfBytes = 3;
} elseif ($asciiCode < 248) {
$numberOfBytes = 4;
}
}
$bytes[] = $asciiCode;
if ($numberOfBytes == count($bytes)) {
if (4 == $numberOfBytes) {
$multibyteCode = ($bytes[0] % 8) * 262144 + ($bytes[1] % 64) * 4096 + ($bytes[2] % 64) * 64 + ($bytes[3] % 64);
} elseif (3 == $numberOfBytes) {
$multibyteCode = ($bytes[0] % 16) * 4096 + ($bytes[1] % 64) * 64 + ($bytes[2] % 64);
} else {
$multibyteCode = ($bytes[0] % 32) * 64 + ($bytes[1] % 64);
}
if (65279 != $multibyteCode) {
$escapedValue .= $multibyteCode < 128 ? $this->escapeAsciiCharacter($multibyteCode) : $this->escapeMultibyteCharacter($multibyteCode);
}
$numberOfBytes = 1;
$bytes = array();
}
}
}
return $escapedValue;
}
}

32
addons/qingdong/library/PhpWord/Escaper/Xml.php

@ -0,0 +1,32 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Escaper;
/**
* @since 0.13.0
*
* @codeCoverageIgnore
*/
class Xml extends AbstractEscaper
{
protected function escapeSingleValue($input)
{
// todo: omit encoding parameter after migration onto PHP 5.4
return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}
}

39
addons/qingdong/library/PhpWord/Exception/CopyFileException.php

@ -0,0 +1,39 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Exception;
/**
* @since 0.12.0
*/
final class CopyFileException extends Exception
{
/**
* @param string $source The fully qualified source file name
* @param string $destination The fully qualified destination file name
* @param int $code The user defined exception code
* @param \Exception $previous The previous exception used for the exception chaining
*/
final public function __construct($source, $destination, $code = 0, \Exception $previous = null)
{
parent::__construct(
sprintf('Could not copy \'%s\' file to \'%s\'.', $source, $destination),
$code,
$previous
);
}
}

37
addons/qingdong/library/PhpWord/Exception/CreateTemporaryFileException.php

@ -0,0 +1,37 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Exception;
/**
* @since 0.12.0
*/
final class CreateTemporaryFileException extends Exception
{
/**
* @param int $code The user defined exception code
* @param \Exception $previous The previous exception used for the exception chaining
*/
final public function __construct($code = 0, \Exception $previous = null)
{
parent::__construct(
'Could not create a temporary file with unique name in the specified directory.',
$code,
$previous
);
}
}

25
addons/qingdong/library/PhpWord/Exception/Exception.php

@ -0,0 +1,25 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Exception;
/**
* General exception
*/
class Exception extends \Exception
{
}

25
addons/qingdong/library/PhpWord/Exception/InvalidImageException.php

@ -0,0 +1,25 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Exception;
/**
* Exception used for when an image is not found
*/
class InvalidImageException extends Exception
{
}

25
addons/qingdong/library/PhpWord/Exception/InvalidObjectException.php

@ -0,0 +1,25 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Exception;
/**
* Exception used for when an image is not found
*/
class InvalidObjectException extends Exception
{
}

27
addons/qingdong/library/PhpWord/Exception/InvalidStyleException.php

@ -0,0 +1,27 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Exception;
use InvalidArgumentException;
/**
* Exception used for when a style value is invalid
*/
class InvalidStyleException extends InvalidArgumentException
{
}

25
addons/qingdong/library/PhpWord/Exception/UnsupportedImageTypeException.php

@ -0,0 +1,25 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Exception;
/**
* Exception used for when an image type is unsupported
*/
class UnsupportedImageTypeException extends Exception
{
}

108
addons/qingdong/library/PhpWord/IOFactory.php

@ -0,0 +1,108 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2018 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Reader\ReaderInterface;
use PhpOffice\PhpWord\Writer\WriterInterface;
abstract class IOFactory
{
/**
* Create new writer
*
* @param PhpWord $phpWord
* @param string $name
*
* @throws \PhpOffice\PhpWord\Exception\Exception
*
* @return WriterInterface
*/
public static function createWriter(PhpWord $phpWord, $name = 'Word2007')
{
if ($name !== 'WriterInterface' && !in_array($name, array('ODText', 'RTF', 'Word2007', 'HTML', 'PDF'), true)) {
throw new Exception("\"{$name}\" is not a valid writer.");
}
$fqName = "PhpOffice\\PhpWord\\Writer\\{$name}";
return new $fqName($phpWord);
}
/**
* Create new reader
*
* @param string $name
*
* @throws Exception
*
* @return ReaderInterface
*/
public static function createReader($name = 'Word2007')
{
return self::createObject('Reader', $name);
}
/**
* Create new object
*
* @param string $type
* @param string $name
* @param \PhpOffice\PhpWord\PhpWord $phpWord
*
* @throws \PhpOffice\PhpWord\Exception\Exception
*
* @return \PhpOffice\PhpWord\Writer\WriterInterface|\PhpOffice\PhpWord\Reader\ReaderInterface
*/
private static function createObject($type, $name, $phpWord = null)
{
$class = "PhpOffice\\PhpWord\\{$type}\\{$name}";
if (class_exists($class) && self::isConcreteClass($class)) {
return new $class($phpWord);
}
throw new Exception("\"{$name}\" is not a valid {$type}.");
}
/**
* Loads PhpWord from file
*
* @param string $filename The name of the file
* @param string $readerName
* @return \PhpOffice\PhpWord\PhpWord $phpWord
*/
public static function load($filename, $readerName = 'Word2007')
{
/** @var \PhpOffice\PhpWord\Reader\ReaderInterface $reader */
$reader = self::createReader($readerName);
return $reader->load($filename);
}
/**
* Check if it's a concrete class (not abstract nor interface)
*
* @param string $class
* @return bool
*/
private static function isConcreteClass($class)
{
$reflection = new \ReflectionClass($class);
return !$reflection->isAbstract() && !$reflection->isInterface();
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save