Aucune description
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

ShopProduct.php 84KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940
  1. <?php
  2. /**
  3. * 易优CMS
  4. * ============================================================================
  5. * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
  6. * 网站地址: http://www.eyoucms.com
  7. * ----------------------------------------------------------------------------
  8. * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
  9. * ============================================================================
  10. * Author: 易而优团队 by 小虎哥 <1105415366@qq.com>
  11. * Date: 2018-4-3
  12. */
  13. namespace app\admin\controller;
  14. use think\Page;
  15. use think\Db;
  16. use app\common\logic\ArctypeLogic;
  17. use app\admin\logic\ProductLogic;
  18. use app\admin\logic\ProductSpecLogic; // 用于商品规格逻辑功能处理
  19. use app\admin\logic\ShopLogic;
  20. class ShopProduct extends Base
  21. {
  22. // 模型标识
  23. public $nid = 'product';
  24. // 模型ID
  25. public $channeltype = '';
  26. // 表单类型
  27. public $attrInputTypeArr = array();
  28. public $ShopLogic;
  29. public function _initialize()
  30. {
  31. parent::_initialize();
  32. $this->ShopLogic = new ShopLogic;
  33. if (!preg_match('/^attrlist_/i', ACTION_NAME) && !preg_match('/^attribute_/i', ACTION_NAME) && !preg_match('/^ajax_/i', ACTION_NAME)) {
  34. $this->language_access(); // 多语言功能操作权限
  35. }
  36. $channeltype_list = config('global.channeltype_list');
  37. $this->channeltype = $channeltype_list[$this->nid];
  38. empty($this->channeltype) && $this->channeltype = 2;
  39. $this->attrInputTypeArr = config('global.attr_input_type_arr');
  40. $this->assign('nid', $this->nid);
  41. $this->assign('channeltype', $this->channeltype);
  42. // 商城产品参数表
  43. $this->shop_product_attrlist_db = Db::name('shop_product_attrlist');
  44. // 规格业务层
  45. $this->productSpecLogic = new ProductSpecLogic;
  46. // 列出营销功能里已使用的模块
  47. $marketFunc = $this->ShopLogic->marketLogic();
  48. $this->assign('marketFunc', $marketFunc);
  49. // 返回页面
  50. $this->callback_url = url('ShopProduct/index', ['lang' => $this->admin_lang]);
  51. $this->assign('callback_url', $this->callback_url);
  52. }
  53. /**
  54. * 商品列表
  55. */
  56. public function index()
  57. {
  58. $assign_data = [];
  59. $condition = [
  60. 'a.merchant_id' => 0
  61. ];
  62. // 获取到所有GET参数
  63. $param = input('param.');
  64. $typeid = input('typeid/d', 0);
  65. // 搜索、筛选查询条件处理
  66. foreach (['keywords', 'typeid', 'flag', 'is_release','province_id','city_id','area_id','arcrank'] as $key) {
  67. if ($key == 'typeid' && empty($param['typeid'])) {
  68. $typeids = Db::name('arctype')->where('current_channel', $this->channeltype)->column('id');
  69. $condition['a.typeid'] = array('IN', $typeids);
  70. }
  71. if (isset($param[$key]) && $param[$key] !== '') {
  72. if ($key == 'keywords') {
  73. $keywords = $param[$key];
  74. $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
  75. } else if ($key == 'typeid') {
  76. $typeid = $param[$key];
  77. $hasRow = model('Arctype')->getHasChildren($typeid);
  78. $typeids = get_arr_column($hasRow, 'id');
  79. // 权限控制 by 小虎哥
  80. $admin_info = session('admin_info');
  81. if (0 < intval($admin_info['role_id'])) {
  82. $auth_role_info = $admin_info['auth_role_info'];
  83. if (!empty($typeid) && !empty($auth_role_info) && !empty($auth_role_info['permission']['arctype'])) {
  84. $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
  85. }
  86. }
  87. $condition['a.typeid'] = array('IN', $typeids);
  88. } else if ($key == 'flag') {
  89. if ('is_release' == $param[$key]) {
  90. $condition['a.users_id'] = array('gt', 0);
  91. } else {
  92. $FlagNew = $param[$key];
  93. $condition['a.'.$param[$key]] = array('eq', 1);
  94. }
  95. } else if (in_array($key, ['province_id','city_id','area_id'])) {
  96. if (!empty($param['area_id'])) {
  97. $condition['a.area_id'] = $param['area_id'];
  98. } else if (!empty($param['city_id'])) {
  99. $condition['a.city_id'] = $param['city_id'];
  100. } else if (!empty($param['province_id'])) {
  101. $condition['a.province_id'] = $param['province_id'];
  102. }
  103. } else if ($key == 'arcrank' && !empty($param[$key])) {
  104. if (1 === intval($param[$key])) {
  105. $condition['a.arcrank'] = ['egt', 0];
  106. } else if (-1 === intval($param[$key])) {
  107. $condition['a.arcrank'] = ['eq', -1];
  108. }
  109. } else {
  110. $condition['a.'.$key] = array('eq', $param[$key]);
  111. }
  112. }
  113. }
  114. // 权限控制 by 小虎哥
  115. $admin_info = session('admin_info');
  116. if (0 < intval($admin_info['role_id'])) {
  117. $auth_role_info = $admin_info['auth_role_info'];
  118. if (!empty($auth_role_info) && isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
  119. $condition['a.admin_id'] = $admin_info['admin_id'];
  120. }
  121. }
  122. // 时间检索条件
  123. $begin = strtotime(input('add_time_begin'));
  124. $end = strtotime(input('add_time_end'));
  125. if ($begin > 0 && $end > 0) {
  126. $condition['a.add_time'] = array('between', "$begin, $end");
  127. } else if ($begin > 0) {
  128. $condition['a.add_time'] = array('egt', $begin);
  129. } else if ($end > 0) {
  130. $condition['a.add_time'] = array('elt', $end);
  131. }
  132. // 必要条件
  133. $condition['a.channel'] = array('eq', $this->channeltype);
  134. $condition['a.lang'] = array('eq', $this->admin_lang);
  135. $condition['a.is_del'] = array('eq', 0);
  136. $conditionNew = "(a.users_id = 0 OR (a.users_id > 0 AND a.arcrank >= 0))";
  137. // 自定义排序
  138. $orderby = input('param.orderby/s');
  139. $orderway = input('param.orderway/s');
  140. if (!empty($orderby) && !empty($orderway)) {
  141. $orderby = "a.{$orderby} {$orderway}, a.aid desc";
  142. } else {
  143. $orderby = "a.aid desc";
  144. }
  145. // 数据查询,搜索出主键ID的值
  146. $SqlQuery = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->fetchSql()->count('aid');
  147. $count = Db::name('sql_cache_table')->where(['sql_md5'=>md5($SqlQuery)])->getField('sql_result');
  148. $count = ($count < 0) ? 0 : $count;
  149. if (empty($count)) {
  150. $count = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->count('aid');
  151. /*添加查询执行语句到mysql缓存表*/
  152. $SqlCacheTable = [
  153. 'sql_name' => '|product|' . $this->channeltype . '|',
  154. 'sql_result' => $count,
  155. 'sql_md5' => md5($SqlQuery),
  156. 'sql_query' => $SqlQuery,
  157. 'add_time' => getTime(),
  158. 'update_time' => getTime(),
  159. ];
  160. if (!empty($FlagNew)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $FlagNew . '|';
  161. if (!empty($typeid)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $typeid . '|';
  162. if (!empty($keywords)) $SqlCacheTable['sql_name'] = '|product|keywords|';
  163. Db::name('sql_cache_table')->insertGetId($SqlCacheTable);
  164. /*END*/
  165. }
  166. $Page = new Page($count, config('paginate.list_rows'));
  167. $list = [];
  168. if (!empty($count)) {
  169. $limit = $count > config('paginate.list_rows') ? $Page->firstRow.','.$Page->listRows : $count;
  170. $list = Db::name('archives')
  171. ->field("a.aid")
  172. ->alias('a')
  173. ->where($condition)
  174. ->where($conditionNew)
  175. ->order($orderby)
  176. ->limit($limit)
  177. ->getAllWithIndex('aid');
  178. if (!empty($list)) {
  179. $aids = array_keys($list);
  180. $fields = "b.*, a.*, a.aid as aid";
  181. $row = Db::name('archives')
  182. ->field($fields)
  183. ->alias('a')
  184. ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
  185. ->where('a.aid', 'in', $aids)
  186. ->getAllWithIndex('aid');
  187. // 查询商品是否开启规格
  188. $goodsSpecArr = Db::name('product_spec_value')->field('aid, value_id')->where('aid', 'in', $aids)->select();
  189. $goodsSpecArr = group_same_key($goodsSpecArr, 'aid');
  190. // 处理商品信息
  191. foreach ($list as $key => $val) {
  192. $row[$val['aid']]['arcurl'] = get_arcurl($row[$val['aid']]);
  193. $row[$val['aid']]['litpic'] = handle_subdir_pic($row[$val['aid']]['litpic']);
  194. $row[$val['aid']]['goodsSpec'] = $goodsSpecArr[$val['aid']] ? count($goodsSpecArr[$val['aid']]) : 0;
  195. $list[$key] = $row[$val['aid']];
  196. }
  197. }
  198. }
  199. $assign_data['page'] = $Page->show();
  200. $assign_data['list'] = $list;
  201. $assign_data['pager'] = $Page;
  202. $assign_data['typeid'] = $typeid;
  203. $assign_data['tab'] = input('param.tab/d', 3);// 选项卡
  204. $assign_data['arctype_html'] = allow_release_arctype($typeid, array($this->channeltype)); // 允许发布文档列表的栏目
  205. $assign_data['arctype_info'] = $typeid > 0 ? Db::name('arctype')->field('typename')->find($typeid) : [];// 当前栏目信息
  206. // 是否存在产品模型的栏目
  207. $where = ['current_channel' => 2, 'is_del' => 0, 'lang' => get_current_lang()];
  208. $assign_data['is_product_arctype'] = Db::name('arctype')->where($where)->count();
  209. $this->assign($assign_data);
  210. // 返回页面
  211. $callback_url = url('ShopProduct/index', ['lang' => $this->admin_lang, 'typeid' => $typeid]);
  212. $this->assign('callback_url', $callback_url);
  213. return $this->fetch();
  214. }
  215. /**
  216. * 添加
  217. */
  218. public function add()
  219. {
  220. $admin_info = session('admin_info');
  221. $auth_role_info = $admin_info['auth_role_info'];
  222. $this->assign('auth_role_info', $auth_role_info);
  223. $this->assign('admin_info', $admin_info);
  224. if (IS_POST) {
  225. $post = input('post.');
  226. model('Archives')->editor_auto_210607($post);
  227. /* 处理TAG标签 */
  228. if (!empty($post['tags_new'])) {
  229. $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
  230. unset($post['tags_new']);
  231. }
  232. $post['tags'] = explode(',', $post['tags']);
  233. $post['tags'] = array_unique($post['tags']);
  234. $post['tags'] = implode(',', $post['tags']);
  235. /* END */
  236. $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
  237. // 根据标题自动提取相关的关键字
  238. $seo_keywords = $post['seo_keywords'];
  239. if (!empty($seo_keywords)) {
  240. $seo_keywords = str_replace(',', ',', $seo_keywords);
  241. } else {
  242. // $seo_keywords = get_split_word($post['title'], $content);
  243. }
  244. // 自动获取内容第一张图片作为封面图
  245. if (empty($post['litpic'])) {
  246. $post['litpic'] = get_html_first_imgurl($content);
  247. }
  248. /*是否有封面图*/
  249. if (empty($post['litpic'])) {
  250. $is_litpic = 0; // 无封面图
  251. } else {
  252. $is_litpic = 1; // 有封面图
  253. }
  254. // SEO描述
  255. $seo_description = '';
  256. if (empty($post['seo_description']) && !empty($content)) {
  257. $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
  258. } else {
  259. $seo_description = $post['seo_description'];
  260. }
  261. // 外部链接跳转
  262. $jumplinks = '';
  263. $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
  264. if (intval($is_jump) > 0) {
  265. $jumplinks = $post['jumplinks'];
  266. }
  267. // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
  268. if ($post['type_tempview'] == $post['tempview']) {
  269. unset($post['type_tempview']);
  270. unset($post['tempview']);
  271. }
  272. //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
  273. $htmlfilename = trim($post['htmlfilename']);
  274. if (!empty($htmlfilename)) {
  275. $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
  276. // $htmlfilename = strtolower($htmlfilename);
  277. //判断是否存在相同的自定义文件名
  278. $map = [
  279. 'htmlfilename' => $htmlfilename,
  280. 'lang' => $this->admin_lang,
  281. ];
  282. if (!empty($post['typeid'])) {
  283. $map['typeid'] = array('eq', $post['typeid']);
  284. }
  285. $filenameCount = Db::name('archives')->where($map)->count();
  286. if (!empty($filenameCount)) {
  287. $this->error("同栏目下,自定义文件名已存在!");
  288. } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
  289. $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
  290. }
  291. } else {
  292. // 处理外贸链接
  293. if (is_dir('./weapp/Waimao/')) {
  294. $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
  295. $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'add', $this->globalConfig);
  296. }
  297. }
  298. $post['htmlfilename'] = $htmlfilename;
  299. // 产品类型
  300. if (!empty($post['prom_type'])) {
  301. if ($post['prom_type_vir'] == 2) {
  302. $post['netdisk_url'] = trim($post['netdisk_url']);
  303. if (empty($post['netdisk_url'])) {
  304. $this->error("网盘地址不能为空!");
  305. }
  306. $post['prom_type'] = 2;
  307. } else if ($post['prom_type_vir'] == 3) {
  308. $post['text_content'] = trim($post['text_content']);
  309. if (empty($post['text_content'])) {
  310. $this->error("虚拟文本内容不能为空!");
  311. }
  312. $post['prom_type'] = 3;
  313. }
  314. }
  315. //做自动通过审核判断
  316. if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
  317. $post['arcrank'] = -1;
  318. }
  319. // 副栏目
  320. if (isset($post['stypeid'])) {
  321. $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
  322. $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
  323. $post['stypeid'] = trim($post['stypeid'], ',');
  324. $post['stypeid'] = str_replace(",{$post['typeid']},", ',', ",{$post['stypeid']},");
  325. $post['stypeid'] = trim($post['stypeid'], ',');
  326. }
  327. // 虚拟销量和总虚拟销量
  328. $post['virtual_sales'] = empty($post['virtual_sales']) ? 0 : intval($post['virtual_sales']);
  329. if (!empty($post['spec_type']) && $post['spec_type'] == 2) { // 多规格
  330. $sales_all = 0;
  331. $post['virtual_sales'] = 0; // 多规格不加上虚拟销量
  332. foreach ($post['spec_sales'] as $key => $val) {
  333. $sales_all += intval($val['spec_sales_num']); // + $post['virtual_sales'];
  334. }
  335. } else { // 单规格
  336. $sales_all = $post['virtual_sales'];
  337. }
  338. // --存储数据
  339. $newData = array(
  340. 'typeid' => empty($post['typeid']) ? 0 : $post['typeid'],
  341. 'channel' => $this->channeltype,
  342. 'is_b' => empty($post['is_b']) ? 0 : $post['is_b'],
  343. 'is_head' => empty($post['is_head']) ? 0 : $post['is_head'],
  344. 'is_special' => empty($post['is_special']) ? 0 : $post['is_special'],
  345. 'is_recom' => empty($post['is_recom']) ? 0 : $post['is_recom'],
  346. 'is_roll' => empty($post['is_roll']) ? 0 : $post['is_roll'],
  347. 'is_slide' => empty($post['is_slide']) ? 0 : $post['is_slide'],
  348. 'is_diyattr' => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
  349. 'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
  350. 'editor_img_clear_link' => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
  351. 'is_jump' => $is_jump,
  352. 'is_litpic' => $is_litpic,
  353. 'jumplinks' => $jumplinks,
  354. 'origin' => empty($post['origin']) ? '网络' : $post['origin'],
  355. 'seo_keywords' => $seo_keywords,
  356. 'seo_description' => $seo_description,
  357. 'admin_id' => session('admin_info.admin_id'),
  358. 'sales_all' => $sales_all,
  359. 'stock_show' => empty($post['stock_show']) ? 0 : $post['stock_show'],
  360. 'users_price' => empty($post['users_price']) ? 0 : floatval($post['users_price']),
  361. 'crossed_price' => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
  362. 'lang' => $this->admin_lang,
  363. 'sort_order' => 100,
  364. 'add_time' => getTime(),
  365. 'update_time' => getTime(),
  366. );
  367. $post['logistics_type'] = !empty($post['logistics_type']) && 0 === intval($post['prom_type']) ? implode(',', $post['logistics_type']) : 0;
  368. $data = array_merge($post, $newData);
  369. // if (!empty($post['param_type']) && 2 == $post['param_type']) {
  370. // $data['attrlist_id'] = 0;
  371. // }
  372. if (2 === intval($post['spec_type'])) {
  373. $data['stock_show'] = 1;
  374. $data['users_discount_type'] = 0;
  375. }
  376. // dump($data);exit;
  377. $aid = Db::name('archives')->insertGetId($data);
  378. $_POST['aid'] = $aid;
  379. if (!empty($aid)) {
  380. // 单规格 且 选择指定会员级别 则 执行
  381. if (1 === intval($post['spec_type']) && 1 === intval($post['users_discount_type'])) {
  382. model('ShopPublicHandle')->saveUsersDiscountPriceList($post['users_discount'], $aid);
  383. }
  384. // ---------后置操作
  385. model('Product')->afterSave($aid, $data, 'add', true);
  386. // 添加查询执行语句到mysql缓存表
  387. model('SqlCacheTable')->InsertSqlCacheTable();
  388. // 若选择多规格选项,则添加产品规格
  389. if (!empty($post['spec_type']) && 2 === intval($post['spec_type'])) {
  390. // 更新规格名称数据
  391. $data['aid'] = $aid;
  392. model('ProductSpecData')->ProducSpecNameEditSave($data, 'add');
  393. // 更新规格值及金额数据
  394. model('ProductSpecValue')->ProducSpecValueEditSave($data, 'add');
  395. // model('ProductSpecPreset')->ProductSpecInsertAll($aid, $data);
  396. }
  397. // 若选择自定义参数则执行
  398. if (!empty($post['attr_name']) && !empty($post['attr_value'])) {
  399. // 新增商品参数
  400. $attrName = !empty($post['attr_name']) ? $post['attr_name'] : [];
  401. $attrValue = !empty($post['attr_value']) ? $post['attr_value'] : [];
  402. $sortOrder = !empty($post['sort_order']) ? $post['sort_order'] : 100;
  403. $productAttribute = $productAttr = [];
  404. $time = getTime();
  405. foreach ($attrName as $key => $value) {
  406. if (!empty($value)) {
  407. $productAttribute = [
  408. 'aid' => $aid,
  409. 'attr_name' => trim($value),
  410. 'attr_values' => '',
  411. 'sort_order' => 100,//intval($sortOrder[$key]),
  412. 'lang' => $this->admin_lang,
  413. 'is_custom' => 1,
  414. 'add_time' => $time,
  415. 'update_time' => $time,
  416. ];
  417. $attrID = Db::name('shop_product_attribute')->insertGetId($productAttribute);
  418. if (!empty($attrValue[$key])) {
  419. $productAttr = [
  420. 'aid' => $aid,
  421. 'attr_id' => $attrID,
  422. 'attr_value' => $attrValue[$key],
  423. 'is_custom' => 1,
  424. 'sort_order' => intval($sortOrder[$key]),
  425. 'add_time' => $time,
  426. 'update_time' => $time,
  427. ];
  428. Db::name('shop_product_attr')->insertGetId($productAttr);
  429. }
  430. }
  431. }
  432. }
  433. adminLog('新增产品:' . $data['title']);
  434. // 虚拟商品保存
  435. if (!empty($post['prom_type']) && in_array($post['prom_type'], [2, 3])) {
  436. model('ProductNetdisk')->saveProductNetdisk($aid, $data);
  437. }
  438. // 生成静态页面代码
  439. $successData = [
  440. 'aid' => $aid,
  441. 'tid' => $post['typeid'],
  442. ];
  443. $this->success("操作成功!", url('ShopProduct/index'), $successData);
  444. }
  445. $this->error("操作失败!");
  446. }
  447. $typeid = input('param.typeid/d', 0);
  448. $assign_data['typeid'] = $typeid; // 栏目ID
  449. $firstrun = input('param.firstrun/d', 0);
  450. if (empty($typeid) && !empty($firstrun)) {
  451. $typeid = Db::name('arctype')->where(['current_channel'=>2,'status'=>1,'is_del'=>0,'lang'=>$this->admin_lang])->order('parent_id asc, sort_order asc, id asc')->value('id');
  452. $url = url('ShopProduct/add', ['typeid'=>$typeid]);
  453. $this->redirect($url);
  454. exit;
  455. }
  456. // 栏目信息
  457. $arctypeInfo = Db::name('arctype')->find($typeid);
  458. // 允许发布文档列表的栏目
  459. $assign_data['arctype_html'] = allow_release_arctype($typeid, array($this->channeltype));
  460. // 可控制的字段列表
  461. $assign_data['ifcontrolRow'] = Db::name('channelfield')->field('id,name')->where([
  462. 'channel_id' => $this->channeltype,
  463. 'ifmain' => 1,
  464. 'ifeditable' => 1,
  465. 'ifcontrol' => 0,
  466. 'status' => 1,
  467. ])->getAllWithIndex('name');
  468. // 阅读权限
  469. $assign_data['arcrank_list'] = get_arcrank_list();
  470. // 产品参数
  471. $assign_data['canshu'] = $this->ajax_get_attr_input($typeid);
  472. // 模板列表
  473. $archivesLogic = new \app\admin\logic\ArchivesLogic;
  474. $assign_data['templateList'] = $archivesLogic->getTemplateList($this->nid);
  475. // 默认模板文件
  476. $tempview = 'view_' . $this->nid . '.' . config('template.view_suffix');
  477. !empty($arctypeInfo['tempview']) && $tempview = $arctypeInfo['tempview'];
  478. $assign_data['tempview'] = $tempview;
  479. // 商城配置
  480. $shopConfig = getUsersConfigData('shop');
  481. $assign_data['shopConfig'] = $shopConfig;
  482. // 商品规格
  483. if (isset($shopConfig['shop_open_spec']) && 1 === intval($shopConfig['shop_open_spec'])) {
  484. // 删除商品添加时产生的废弃规格
  485. $del_spec = session('del_spec') ? session('del_spec') : [];
  486. if (!empty($del_spec)) {
  487. $del_spec = array_unique($del_spec);
  488. $where = [
  489. 'spec_mark_id' => ['IN', $del_spec]
  490. ];
  491. Db::name('product_spec_data_handle')->where($where)->delete(true);
  492. $where = [
  493. 'aid' => session('handleAID')
  494. ];
  495. Db::name('product_spec_value_handle')->where($where)->delete(true);
  496. // 清除 session
  497. session('del_spec', null);
  498. }
  499. // 清除处理表的aid
  500. session('handleAID', 0);
  501. // 预设值名称
  502. $assign_data['preset_value'] = Db::name('product_spec_preset')->where('lang', $this->admin_lang)->field('preset_id, preset_mark_id, preset_name')->group('preset_mark_id')->order('preset_mark_id desc')->select();
  503. // 读取规格预设库最大参数标记ID
  504. $maxPresetMarkID = $assign_data['preset_value'][0]['preset_mark_id'];
  505. $assign_data['maxPresetMarkID'] = $maxPresetMarkID + 1;
  506. }
  507. // 商品参数列表
  508. $where = [
  509. 'status' => 1,
  510. 'is_del' => 0,
  511. 'lang' => $this->admin_lang,
  512. ];
  513. $assign_data['AttrList'] = $this->shop_product_attrlist_db->where($where)->order('sort_order asc, list_id asc')->select();
  514. // 最大参数属性ID值 +1
  515. $maxAttrID = Db::name('shop_product_attribute')->max('attr_id');
  516. $assign_data['maxAttrID'] = ++$maxAttrID;
  517. // URL模式
  518. $tpcache = config('tpcache');
  519. $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
  520. // 文档默认浏览量
  521. $globalConfig = tpCache('global');
  522. if (isset($globalConfig['other_arcclick']) && 0 <= $globalConfig['other_arcclick']) {
  523. $arcclick_arr = explode("|", $globalConfig['other_arcclick']);
  524. if (count($arcclick_arr) > 1) {
  525. $assign_data['rand_arcclick'] = mt_rand($arcclick_arr[0], $arcclick_arr[1]);
  526. } else {
  527. $assign_data['rand_arcclick'] = intval($arcclick_arr[0]);
  528. }
  529. } else {
  530. $arcclick_config['other_arcclick'] = '500|1000';
  531. tpCache('other', $arcclick_config);
  532. $assign_data['rand_arcclick'] = mt_rand(500, 1000);
  533. }
  534. // 文档属性
  535. $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
  536. $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
  537. $assign_data['channelRow'] = $channelRow;
  538. // 来源列表
  539. $system_originlist = tpSetting('system.system_originlist');
  540. $system_originlist = json_decode($system_originlist, true);
  541. $system_originlist = !empty($system_originlist) ? $system_originlist : [];
  542. $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
  543. $assign_data['system_originlist_0'] = !empty($system_originlist) ? $system_originlist[0] : "";
  544. // 多站点,当用站点域名访问后台,发布文档自动选择当前所属区域
  545. model('Citysite')->auto_location_select($assign_data);
  546. // 获取核销插件数据
  547. $assign_data['weappVerify'] = model('ShopPublicHandle')->getWeappVerifyInfo();
  548. $this->assign($assign_data);
  549. return $this->fetch();
  550. }
  551. /**
  552. * 编辑
  553. */
  554. public function edit()
  555. {
  556. $admin_info = session('admin_info');
  557. $auth_role_info = $admin_info['auth_role_info'];
  558. $this->assign('auth_role_info', $auth_role_info);
  559. $this->assign('admin_info', $admin_info);
  560. if (IS_POST) {
  561. $post = input('post.');
  562. model('Archives')->editor_auto_210607($post);
  563. $post['aid'] = intval($post['aid']);
  564. /* 处理TAG标签 */
  565. if (!empty($post['tags_new'])) {
  566. $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
  567. unset($post['tags_new']);
  568. }
  569. $post['tags'] = explode(',', $post['tags']);
  570. $post['tags'] = array_unique($post['tags']);
  571. $post['tags'] = implode(',', $post['tags']);
  572. /* END */
  573. $typeid = input('post.typeid/d', 0);
  574. $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
  575. // 根据标题自动提取相关的关键字
  576. $seo_keywords = $post['seo_keywords'];
  577. if (!empty($seo_keywords)) {
  578. $seo_keywords = str_replace(',', ',', $seo_keywords);
  579. } else {
  580. // $seo_keywords = get_split_word($post['title'], $content);
  581. }
  582. // 自动获取内容第一张图片作为封面图
  583. if (empty($post['litpic'])) {
  584. $post['litpic'] = get_html_first_imgurl($content);
  585. }
  586. /*是否有封面图*/
  587. if (empty($post['litpic'])) {
  588. $is_litpic = 0; // 无封面图
  589. } else {
  590. $is_litpic = !empty($post['is_litpic']) ? $post['is_litpic'] : 0; // 有封面图
  591. }
  592. // 勾选后SEO描述将随正文内容更新
  593. $basic_update_seo_description = empty($post['basic_update_seo_description']) ? 0 : 1;
  594. if (is_language()) {
  595. $langRow = \think\Db::name('language')->order('id asc')
  596. ->cache(true, EYOUCMS_CACHE_TIME, 'language')
  597. ->select();
  598. foreach ($langRow as $key => $val) {
  599. tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description], $val['mark']);
  600. }
  601. } else {
  602. tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description]);
  603. }
  604. /*--end*/
  605. // SEO描述
  606. $seo_description = '';
  607. if (!empty($basic_update_seo_description) || empty($post['seo_description'])) {
  608. $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
  609. } else {
  610. $seo_description = $post['seo_description'];
  611. }
  612. // --外部链接
  613. $jumplinks = '';
  614. $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
  615. if (intval($is_jump) > 0) {
  616. $jumplinks = $post['jumplinks'];
  617. }
  618. // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
  619. if ($post['type_tempview'] == $post['tempview']) {
  620. unset($post['type_tempview']);
  621. unset($post['tempview']);
  622. }
  623. // 产品类型
  624. if (!empty($post['prom_type']) && !in_array($post['prom_type'],[0,4])) {
  625. if ($post['prom_type_vir'] == 2) {
  626. $post['netdisk_url'] = trim($post['netdisk_url']);
  627. if (empty($post['netdisk_url'])) {
  628. $this->error("网盘地址不能为空!");
  629. }
  630. $post['prom_type'] = 2;
  631. } else if ($post['prom_type_vir'] == 3) {
  632. $post['text_content'] = trim($post['text_content']);
  633. if (empty($post['text_content'])) {
  634. $this->error("虚拟文本内容不能为空!");
  635. }
  636. $post['prom_type'] = 3;
  637. }
  638. }
  639. //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
  640. $htmlfilename = trim($post['htmlfilename']);
  641. if (!empty($htmlfilename)) {
  642. $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
  643. // $htmlfilename = strtolower($htmlfilename);
  644. //判断是否存在相同的自定义文件名
  645. $map = [
  646. 'aid' => ['NEQ', $post['aid']],
  647. 'htmlfilename' => $htmlfilename,
  648. 'lang' => $this->admin_lang,
  649. ];
  650. if (!empty($post['typeid'])) {
  651. $map['typeid'] = array('eq', $post['typeid']);
  652. }
  653. $filenameCount = Db::name('archives')->where($map)->count();
  654. if (!empty($filenameCount)) {
  655. $this->error("同栏目下,自定义文件名已存在!");
  656. } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
  657. $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
  658. }
  659. } else {
  660. // 处理外贸链接
  661. if (is_dir('./weapp/Waimao/')) {
  662. $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
  663. $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'edit', $this->globalConfig);
  664. }
  665. }
  666. $post['htmlfilename'] = $htmlfilename;
  667. // 同步栏目切换模型之后的文档模型
  668. $channel = Db::name('arctype')->where(['id' => $typeid])->getField('current_channel');
  669. //做未通过审核文档不允许修改文档状态操作
  670. if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
  671. $old_archives_arcrank = Db::name('archives')->where(['aid' => $post['aid']])->getField("arcrank");
  672. if ($old_archives_arcrank < 0) {
  673. unset($post['arcrank']);
  674. }
  675. }
  676. // 副栏目
  677. if (isset($post['stypeid'])) {
  678. $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
  679. $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
  680. $post['stypeid'] = trim($post['stypeid'], ',');
  681. $post['stypeid'] = str_replace(",{$typeid},", ',', ",{$post['stypeid']},");
  682. $post['stypeid'] = trim($post['stypeid'], ',');
  683. }
  684. // 虚拟销量和总虚拟销量
  685. $post['virtual_sales'] = empty($post['virtual_sales']) ? 0 : intval($post['virtual_sales']);
  686. if (!empty($post['spec_type']) && $post['spec_type'] == 2) { // 多规格
  687. $sales_all = 0;
  688. $post['virtual_sales'] = 0; // 多规格不加上虚拟销量
  689. foreach ($post['spec_sales'] as $key => $val) {
  690. $sales_all += intval($val['spec_sales_num']); // + $post['virtual_sales'];
  691. }
  692. } else { // 单规格
  693. $sales_all = $post['virtual_sales'];
  694. }
  695. // --存储数据
  696. $newData = array(
  697. 'typeid' => $typeid,
  698. 'channel' => $channel,
  699. 'is_b' => empty($post['is_b']) ? 0 : $post['is_b'],
  700. 'is_head' => empty($post['is_head']) ? 0 : $post['is_head'],
  701. 'is_special' => empty($post['is_special']) ? 0 : $post['is_special'],
  702. 'is_recom' => empty($post['is_recom']) ? 0 : $post['is_recom'],
  703. 'is_roll' => empty($post['is_roll']) ? 0 : $post['is_roll'],
  704. 'is_slide' => empty($post['is_slide']) ? 0 : $post['is_slide'],
  705. 'is_diyattr' => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
  706. 'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
  707. 'editor_img_clear_link' => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
  708. 'is_jump' => $is_jump,
  709. 'is_litpic' => $is_litpic,
  710. 'jumplinks' => $jumplinks,
  711. 'seo_keywords' => $seo_keywords,
  712. 'seo_description' => $seo_description,
  713. 'sales_all' => $sales_all,
  714. 'stock_show' => empty($post['stock_show']) ? 0 : $post['stock_show'],
  715. 'users_price' => empty($post['users_price']) ? 0 : floatval($post['users_price']),
  716. 'crossed_price' => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
  717. // 'add_time' => strtotime($post['add_time']),
  718. 'update_time' => getTime(),
  719. );
  720. $post['logistics_type'] = !empty($post['logistics_type']) && 0 === intval($post['prom_type']) ? implode(',', $post['logistics_type']) : 0;
  721. $data = array_merge($post, $newData);
  722. // if (!empty($post['param_type']) && 2 == $post['param_type']) {
  723. // $data['attrlist_id'] = 0;
  724. // }
  725. // 更新商品信息
  726. $where = [
  727. 'aid' => $data['aid'],
  728. 'lang' => $this->admin_lang,
  729. ];
  730. if (2 === intval($post['spec_type'])) {
  731. $data['stock_show'] = 1;
  732. $data['users_discount_type'] = 0;
  733. }
  734. $result = Db::name('archives')->where($where)->update($data);
  735. if (!empty($result)) {
  736. // 单规格 且 选择指定会员级别 则 执行
  737. if (1 === intval($post['spec_type']) && 1 === intval($post['users_discount_type'])) {
  738. model('ShopPublicHandle')->saveUsersDiscountPriceList($post['users_discount'], $data['aid']);
  739. }
  740. // ---------后置操作
  741. model('Product')->afterSave($data['aid'], $data, 'edit', true);
  742. // 虚拟商品保存
  743. if (!empty($post['prom_type']) && in_array($post['prom_type'], [2, 3])) {
  744. model('ProductNetdisk')->saveProductNetdisk($data['aid'], $data);
  745. }
  746. // 若选择单规格则清理多规格数据
  747. if (!empty($post['spec_type']) && 1 == $post['spec_type']) {
  748. // 产品规格数据表
  749. Db::name("product_spec_data")->where('aid', $data['aid'])->delete();
  750. // 产品多规格组装表
  751. Db::name("product_spec_value")->where('aid', $data['aid'])->delete();
  752. // 产品规格数据处理表
  753. Db::name("product_spec_data_handle")->where('aid', $data['aid'])->delete();
  754. }
  755. // 若选择多规格选项,则添加产品规格
  756. else if (!empty($post['spec_type']) && 2 == $post['spec_type']) {
  757. // 更新规格名称数据
  758. model('ProductSpecData')->ProducSpecNameEditSave($data);
  759. // 更新规格值及金额数据
  760. model('ProductSpecValue')->ProducSpecValueEditSave($data);
  761. }
  762. // 若选择自定义参数则执行
  763. if (!empty($post['attr_name']) && !empty($post['attr_value'])) {
  764. // 新增商品参数
  765. $attrName = !empty($post['attr_name']) ? $post['attr_name'] : [];
  766. $attrValue = !empty($post['attr_value']) ? $post['attr_value'] : [];
  767. $sortOrder = !empty($post['sort_order']) ? $post['sort_order'] : 100;
  768. $productAttribute = $productAttr = [];
  769. $time = getTime();
  770. foreach ($attrName as $key => $value) {
  771. if (!empty($value)) {
  772. $productAttribute = [
  773. 'aid' => $post['aid'],
  774. 'attr_name' => trim($value),
  775. 'attr_values' => '',
  776. 'sort_order' => 100,//intval($sortOrder[$key]),
  777. 'lang' => $this->admin_lang,
  778. 'is_custom' => 1,
  779. 'add_time' => $time,
  780. 'update_time' => $time,
  781. ];
  782. $attrID = Db::name('shop_product_attribute')->insertGetId($productAttribute);
  783. if (!empty($attrValue[$key])) {
  784. $productAttr = [
  785. 'aid' => $post['aid'],
  786. 'attr_id' => $attrID,
  787. 'attr_value' => $attrValue[$key],
  788. 'is_custom' => 1,
  789. 'sort_order' => intval($sortOrder[$key]),
  790. 'add_time' => $time,
  791. 'update_time' => $time,
  792. ];
  793. Db::name('shop_product_attr')->insertGetId($productAttr);
  794. }
  795. }
  796. }
  797. }
  798. // 删除指定的商品参数
  799. if (!empty($post['del_attr_id'])) {
  800. $delAttrID = explode(',', $post['del_attr_id']);
  801. $where = [
  802. 'is_custom' => 1,
  803. 'attr_id' => ['IN', $delAttrID]
  804. ];
  805. Db::name('shop_product_attr')->where($where)->delete(true);
  806. Db::name('shop_product_attribute')->where($where)->delete(true);
  807. }
  808. adminLog('编辑产品:' . $data['title']);
  809. // 系统商品操作时,积分商品的被动处理
  810. model('ShopPublicHandle')->pointsGoodsPassiveHandle([$data['aid']]);
  811. // 生成静态页面代码
  812. $successData = [
  813. 'aid' => $data['aid'],
  814. 'tid' => $typeid,
  815. ];
  816. $this->success("操作成功!", url('ShopProduct/index'), $successData);
  817. }
  818. $this->error("操作失败!");
  819. }
  820. $assign_data = array();
  821. $id = input('id/d', 0);
  822. $info = model('Product')->getInfo($id);
  823. if (empty($info)) $this->error('数据不存在,请联系管理员!');
  824. // 获取规格数据信息
  825. // 包含:SpecSelectName、HtmlTable、spec_mark_id_arr、preset_value
  826. $assign_data = model('ProductSpecData')->GetProductSpecData($id);
  827. // 兼容采集没有归属栏目的文档
  828. if (empty($info['channel'])) {
  829. $channelRow = Db::name('channeltype')->field('id as channel')->where('id', $this->channeltype)->find();
  830. $info = array_merge($info, $channelRow);
  831. }
  832. // 栏目ID及栏目信息
  833. $typeid = $info['typeid'];
  834. $assign_data['typeid'] = $typeid;
  835. $arctypeInfo = Db::name('arctype')->find($typeid);
  836. $info['channel'] = $arctypeInfo['current_channel'];
  837. $info['litpic'] = handle_subdir_pic($info['litpic']);
  838. // 副栏目
  839. $stypeid_arr = [];
  840. if (!empty($info['stypeid'])) {
  841. $info['stypeid'] = trim($info['stypeid'], ',');
  842. $stypeid_arr = Db::name('arctype')->field('id,typename')->where(['id'=>['IN', $info['stypeid']],'is_del'=>0])->select();
  843. }
  844. $assign_data['stypeid_arr'] = $stypeid_arr;
  845. // SEO描述
  846. // if (!empty($info['seo_description'])) {
  847. // $info['seo_description'] = @msubstr(checkStrHtml($info['seo_description']), 0, config('global.arc_seo_description_length'), false);
  848. // }
  849. // 物流支持类型
  850. $info['logistics_type'] = isset($info['logistics_type']) ? explode(',', $info['logistics_type']) : [];
  851. $assign_data['field'] = $info;
  852. // 产品相册
  853. $proimg_list = model('ProductImg')->getProImg($id);
  854. foreach ($proimg_list as $key => $val) {
  855. $proimg_list[$key]['image_url'] = handle_subdir_pic($val['image_url']); // 支持子目录
  856. }
  857. $assign_data['proimg_list'] = $proimg_list;
  858. // 允许发布文档列表的栏目,文档所在模型以栏目所在模型为主,兼容切换模型之后的数据编辑
  859. $assign_data['arctype_html'] = allow_release_arctype($typeid, array($info['channel']));
  860. // 可控制的主表字段列表
  861. $assign_data['ifcontrolRow'] = Db::name('channelfield')->field('id,name')->where([
  862. 'channel_id' => $this->channeltype,
  863. 'ifmain' => 1,
  864. 'ifeditable' => 1,
  865. 'ifcontrol' => 0,
  866. 'status' => 1,
  867. ])->getAllWithIndex('name');
  868. // 虚拟商品内容读取
  869. $assign_data['netdisk'] = Db::name("product_netdisk")->where('aid', $id)->find();
  870. // 阅读权限
  871. $assign_data['arcrank_list'] = get_arcrank_list();
  872. // 模板列表
  873. $archivesLogic = new \app\admin\logic\ArchivesLogic;
  874. $templateList = $archivesLogic->getTemplateList($this->nid);
  875. $assign_data['templateList'] = $templateList;
  876. // 默认模板文件
  877. $tempview = $info['tempview'];
  878. empty($tempview) && $tempview = $arctypeInfo['tempview'];
  879. $assign_data['tempview'] = $tempview;
  880. // 商城配置
  881. $shopConfig = getUsersConfigData('shop');
  882. $assign_data['shopConfig'] = $shopConfig;
  883. // URL模式
  884. $tpcache = config('tpcache');
  885. $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
  886. // 商品参数列表
  887. $where = [
  888. 'status' => 1,
  889. 'is_del' => 0,
  890. 'lang' => $this->admin_lang,
  891. ];
  892. $assign_data['AttrList'] = $this->shop_product_attrlist_db->where($where)->order('sort_order asc, list_id asc')->select();
  893. // 商品参数值
  894. $assign_data['canshu'] = $assign_data['customParam'] = '';
  895. if (!empty($info['attrlist_id'])) {
  896. $assign_data['canshu'] = $this->ajax_get_shop_attr_input($typeid, $id, $info['attrlist_id']);
  897. }
  898. // 自定义参数
  899. $where = [
  900. 'a.is_custom' => 1,
  901. 'b.is_custom' => 1,
  902. 'a.aid' => $info['aid'],
  903. ];
  904. $field = 'a.*, b.attr_name';
  905. $order = 'a.sort_order asc, b.attr_id sac, a.product_attr_id asc';
  906. $productAttr = Db::name('shop_product_attr')
  907. ->alias('a')
  908. ->where($where)
  909. ->field($field)
  910. ->order($order)
  911. ->join('__SHOP_PRODUCT_ATTRIBUTE__ b', 'a.attr_id = b.attr_id', 'LEFT')
  912. ->select();
  913. $assign_data['customParam'] = $productAttr;
  914. $delAttrID = get_arr_column($productAttr, 'attr_id');
  915. $assign_data['delAttrID'] = !empty($delAttrID) ? implode(',', $delAttrID) : '';
  916. // 最大参数属性ID值 +1
  917. $maxAttrID = Db::name('shop_product_attribute')->max('attr_id');
  918. $maxAttrID++;
  919. $assign_data['maxAttrID'] = $maxAttrID;
  920. // 文档属性
  921. $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
  922. $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
  923. $assign_data['channelRow'] = $channelRow;
  924. // 来源列表
  925. $system_originlist = tpSetting('system.system_originlist');
  926. $system_originlist = json_decode($system_originlist, true);
  927. $system_originlist = !empty($system_originlist) ? $system_originlist : [];
  928. $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
  929. // 获取核销插件数据
  930. $assign_data['weappVerify'] = model('ShopPublicHandle')->getWeappVerifyInfo();
  931. // dump($assign_data);exit;
  932. $this->assign($assign_data);
  933. return $this->fetch();
  934. }
  935. /**
  936. * 删除
  937. */
  938. public function del()
  939. {
  940. if (IS_POST) {
  941. $archivesLogic = new \app\admin\logic\ArchivesLogic;
  942. $archivesLogic->del([], 0, 'product');
  943. }
  944. }
  945. /**
  946. * 删除商品相册图
  947. */
  948. public function del_proimg()
  949. {
  950. if (IS_POST) {
  951. $filename= input('filename/s');
  952. $aid = input('aid/d');
  953. if (!empty($filename) && !empty($aid)) {
  954. Db::name('product_img')->where('image_url','like','%'.$filename)->where('aid',$aid)->delete();
  955. }
  956. }
  957. }
  958. public function goods_spec_detection()
  959. {
  960. if (IS_AJAX_POST) {
  961. $post = input('post.');
  962. // 验证规格名
  963. $result = 0;
  964. foreach ($post['spec_mark_id'] as $key => $value) {
  965. if (empty($value['spec_name'])) $result = 1;
  966. }
  967. !empty($result) && $this->error('请完善规格名');
  968. // 验证规格值
  969. $result = 0;
  970. foreach ($post['spec_value_id'] as $key => $value) {
  971. if (empty($value['spec_value'])) $result = 1;
  972. }
  973. !empty($result) && $this->error('请完善规格值');
  974. // 验证规格价
  975. $result = 0;
  976. foreach ($post['spec_price'] as $key => $value) {
  977. if (empty($value['users_price']) || 0 >= floatval($value['users_price'])) $result = 1;
  978. }
  979. !empty($result) && $this->error('请完善规格价');
  980. $this->success('验证成功');
  981. }
  982. }
  983. public function goods_quick_edit()
  984. {
  985. if (IS_AJAX_POST) {
  986. $post = input('post.');
  987. if (empty($post['aid']) || !isset($post['openSpec'])) $this->error('数据异常,刷新重试');
  988. // 更新商品表数据
  989. $where = [
  990. 'aid' => intval($post['aid']),
  991. 'lang' => $this->admin_lang,
  992. ];
  993. $update = [
  994. 'stock_show' => empty($post['stock_show']) ? 0 : intval($post['stock_show']),
  995. 'stock_count' => empty($post['stock_count']) ? 0 : intval($post['stock_count']),
  996. 'users_price' => empty($post['users_price']) ? 0 : floatval($post['users_price']),
  997. 'users_discount_type' => empty($post['users_discount_type']) ? 0 : intval($post['users_discount_type']),
  998. 'update_time' => getTime(),
  999. ];
  1000. $update = array_merge($post, $update);
  1001. $result = Db::name('archives')->where($where)->update($update);
  1002. // 后续处理
  1003. if (!empty($result)) {
  1004. // 已开启规格的商品处理
  1005. if (1 === intval($update['openSpec'])) {
  1006. // 更新规格值及金额数据
  1007. model('ProductSpecValue')->ProducSpecValueEditSave($update, 'edit');
  1008. }
  1009. // 未开启规格的商品处理
  1010. else if (0 === intval($update['openSpec']) && 1 === intval($update['users_discount_type'])) {
  1011. // 选择指定会员级别执行
  1012. model('ShopPublicHandle')->saveUsersDiscountPriceList($update['users_discount'], $update['aid']);
  1013. }
  1014. // 系统商品操作时,积分商品的被动处理
  1015. model('ShopPublicHandle')->pointsGoodsPassiveHandle([$update['aid']]);
  1016. // 成功返回结束
  1017. $this->success("操作成功");
  1018. }
  1019. // 失败返回结束
  1020. $this->error("操作失败");
  1021. }
  1022. // 查询商品信息
  1023. $aid = input('param.aid/d', 0);
  1024. $where = [
  1025. 'aid' => intval($aid),
  1026. ];
  1027. $field = 'aid, title, users_price, stock_count, stock_show, virtual_sales, users_discount_type';
  1028. $goods = Db::name('archives')->field($field)->where($where)->find();
  1029. $this->assign('goods', $goods);
  1030. // 查询商品的规格信息
  1031. $where = [
  1032. 'aid' => intval($aid),
  1033. 'spec_is_select' => 1,
  1034. ];
  1035. $field = 'spec_mark_id, spec_value_id';
  1036. // $order = 'spec_mark_id asc, spec_value_id asc, spec_id asc';
  1037. $order = 'spec_value_id asc, spec_id asc';
  1038. $spec = Db::name('product_spec_data')->where($where)->field($field)->order($order)->select();
  1039. $openSpec = 0;
  1040. $htmlTable = '';
  1041. if (!empty($spec)) {
  1042. $openSpec = 1;
  1043. // 处理规格数组
  1044. $specArray = [];
  1045. foreach ($spec as $key => $value) {
  1046. $specArray[$value['spec_mark_id']][] = $value['spec_value_id'];
  1047. }
  1048. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($specArray, $aid, true);
  1049. }
  1050. $this->assign('openSpec', $openSpec);
  1051. $this->assign('htmlTable', $htmlTable);
  1052. // 商城配置
  1053. $this->assign('shopConfig', getUsersConfigData('shop'));
  1054. return $this->fetch();
  1055. }
  1056. public function goodsSpecImage()
  1057. {
  1058. if (IS_AJAX_POST) {
  1059. // 规格图片路径
  1060. $aid = input('param.aid/d', 0);
  1061. if (empty($aid)) $aid = session('handleAID');
  1062. $action = input('param.action/s', '');
  1063. $checked = input('param.checked/d', 0);
  1064. $spec_image = input('param.spec_image/s', '');
  1065. $spec_mark_id = input('param.spec_mark_id/d', 0);
  1066. $spec_value_id = input('param.spec_value_id/d', 0);
  1067. if ('open' == $action) {
  1068. // 更新同一类所有规格值为开启规格图片
  1069. $where = [
  1070. 'spec_is_select' => 1,
  1071. 'aid' => intval($aid),
  1072. 'spec_mark_id' => intval($spec_mark_id),
  1073. ];
  1074. $update = [
  1075. 'open_image' => intval($checked),
  1076. 'update_time' => getTime(),
  1077. ];
  1078. $result = Db::name('product_spec_data_handle')->where($where)->update($update);
  1079. if (!empty($result)) $this->success("操作成功");
  1080. } else {
  1081. $where = [
  1082. 'spec_is_select' => 1,
  1083. 'aid' => intval($aid),
  1084. 'spec_mark_id' => intval($spec_mark_id),
  1085. 'spec_value_id' => intval($spec_value_id),
  1086. ];
  1087. $update = [
  1088. 'spec_image' => $spec_image,
  1089. 'update_time' => getTime(),
  1090. ];
  1091. $result = Db::name('product_spec_data_handle')->where($where)->update($update);
  1092. if (!empty($result)) $this->success("操作成功");
  1093. }
  1094. }
  1095. $this->error("操作失败");
  1096. }
  1097. // 初始化规格信息
  1098. public function initialization_spec()
  1099. {
  1100. if (IS_AJAX_POST) {
  1101. $initialization = input('post.initialization');
  1102. // 刷新或重新进入产品添加页则清除关于产品session
  1103. if (!empty($initialization)) {
  1104. // session('handleAID', 0);
  1105. session('del_spec', null);
  1106. session('spec_arr', null);
  1107. $this->success('初始化完成');
  1108. }
  1109. }
  1110. }
  1111. // 添加商品自定义规格并返回规格表格
  1112. public function add_product_custom_spec()
  1113. {
  1114. if (IS_AJAX_POST) {
  1115. $post = input('post.');
  1116. // 添加自定义规格
  1117. $resultArray = $this->productSpecLogic->addProductCustomSpec($post);
  1118. if (!empty($resultArray['errorMsg'])) $this->error($resultArray['errorMsg']);
  1119. // 获取已选规格进行HTML代码拼装
  1120. if (!empty($post['aid'])) {
  1121. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray['spec_array'], $post['aid']);
  1122. } else {
  1123. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray['spec_array']);
  1124. }
  1125. // 返回数据
  1126. if (in_array($post['action'], ['specName', 'specValue'])) {
  1127. $specData = $this->productSpecLogic->getProductSpecValueOption($resultArray['spec_mark_id'], $post);
  1128. }
  1129. $returnData = [
  1130. 'htmlTable' => !empty($htmlTable) ? $htmlTable : ' ',
  1131. 'spec_name' => !empty($specData['spec_name']) ? $specData['spec_name'] : '',
  1132. 'spec_value' => !empty($specData['spec_value']) ? $specData['spec_value'] : '',
  1133. 'spec_mark_id' => !empty($resultArray['spec_mark_id']) ? $resultArray['spec_mark_id'] : 0,
  1134. 'spec_value_id' => !empty($resultArray['spec_value_id']) ? $resultArray['spec_value_id'] : 0,
  1135. 'spec_value_option' => !empty($specData['spec_value_option']) ? $specData['spec_value_option'] : '',
  1136. 'spec_mark_id_arr' => !empty($resultArray['spec_mark_id_arr']) ? $resultArray['spec_mark_id_arr'] : 0,
  1137. 'preset_name_option' => !empty($specData['preset_name_option']) ? $specData['preset_name_option'] : '',
  1138. ];
  1139. $this->success('加载成功!', null, $returnData);
  1140. }
  1141. }
  1142. // 添加自定义规格名称并返回规格表
  1143. public function add_product_custom_spec_name()
  1144. {
  1145. if (IS_AJAX_POST) {
  1146. $post = input('post.');
  1147. // 添加自定义规格名称
  1148. $resultArray = $this->productSpecLogic->addProductCustomSpecName($post);
  1149. if (!empty($resultArray['errorMsg'])) $this->error($resultArray['errorMsg']);
  1150. // 获取已选规格进行HTML代码拼装
  1151. if (!empty($post['aid'])) {
  1152. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray, $post['aid']);
  1153. } else {
  1154. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray);
  1155. }
  1156. // 返回数据
  1157. $returnData = [
  1158. 'htmlTable' => !empty($htmlTable) ? $htmlTable : ' ',
  1159. ];
  1160. $this->success('加载成功!', null, $returnData);
  1161. }
  1162. }
  1163. // 添加自定义规格值并返回规格表
  1164. public function add_product_custom_spec_value()
  1165. {
  1166. if (IS_AJAX_POST) {
  1167. $post = input('post.');
  1168. // 添加自定义规格值
  1169. $resultArray = $this->productSpecLogic->addProductCustomSpecValue($post);
  1170. if (!empty($resultArray['errorMsg'])) $this->error($resultArray['errorMsg']);
  1171. // 获取已选规格进行HTML代码拼装
  1172. if (!empty($post['aid'])) {
  1173. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray, $post['aid']);
  1174. } else {
  1175. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray);
  1176. }
  1177. // 返回数据
  1178. $returnData = [
  1179. 'htmlTable' => !empty($htmlTable) ? $htmlTable : ' ',
  1180. ];
  1181. $this->success('加载成功!', null, $returnData);
  1182. }
  1183. }
  1184. // 删除商品自定义规格并返回规格表格
  1185. public function del_product_custom_spec()
  1186. {
  1187. if (IS_AJAX_POST) {
  1188. $post = input('post.');
  1189. // 删除自定义规格
  1190. $resultArray = $this->productSpecLogic->delProductCustomSpec($post);
  1191. // 获取已选规格进行HTML代码拼装
  1192. if (!empty($post['aid'])) {
  1193. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray, $post['aid']);
  1194. } else {
  1195. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($resultArray);
  1196. }
  1197. if (in_array($post['del'], ['specName', 'specValue'])) {
  1198. $specData = $this->productSpecLogic->getProductSpecValueOption(0, $post);
  1199. }
  1200. // 返回数据
  1201. $returnData = [
  1202. 'htmlTable' => !empty($htmlTable) ? $htmlTable : ' ',
  1203. 'spec_value_option' => !empty($specData['spec_value_option']) ? $specData['spec_value_option'] : '',
  1204. 'preset_name_option' => !empty($specData['preset_name_option']) ? $specData['preset_name_option'] : '',
  1205. ];
  1206. $this->success('加载成功!', null, $returnData);
  1207. }
  1208. }
  1209. public function edit_product_spec_price()
  1210. {
  1211. if (IS_AJAX_POST) {
  1212. $post = input('post.');
  1213. $result = model('ProductSpecValueHandle')->editProductSpecPrice($post);
  1214. if (!empty($result)) {
  1215. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($result['resultArray'], $result['aid']);
  1216. $this->success('操作成功', null, $htmlTable);
  1217. } else {
  1218. $this->error('数据异常,刷新重试');
  1219. }
  1220. }
  1221. }
  1222. // 获取会员折扣价格模板
  1223. public function get_users_discount_price_tpl()
  1224. {
  1225. if (IS_AJAX_POST) {
  1226. // 产品ID
  1227. $aid = input('post.aid/d', 0);
  1228. // 产品单价
  1229. $users_price = input('post.users_price/f', 0);
  1230. // 获取会员折扣价格模板
  1231. $result = model('ShopPublicHandle')->getUsersDiscountPriceTpl($aid, $users_price);
  1232. // 如果存在错误则返回提示
  1233. if (isset($result['code']) && 0 === intval($result['code'])) $this->error($result['data']);
  1234. // 返回数据
  1235. $this->success('加载成功!', null, $result['data']);
  1236. }
  1237. }
  1238. // 选中规格名称值,追加html到页面展示
  1239. public function spec_value_select()
  1240. {
  1241. if (IS_AJAX_POST) {
  1242. $post = input('post.');
  1243. // Post 数据
  1244. $aid = !empty($post['aid']) ? $post['aid'] : 0;
  1245. $spec_mark_id = !empty($post['spec_mark_id']) ? $post['spec_mark_id'] : 0;
  1246. $spec_value_id = !empty($post['spec_value_id']) ? $post['spec_value_id'] : 0;
  1247. if (empty($aid) || empty($spec_mark_id) || empty($spec_value_id)) $this->error('操作异常,请刷新重试...');
  1248. $spec_array = [];
  1249. // 执行更新
  1250. $where = [
  1251. 'aid' => $aid,
  1252. 'spec_mark_id' => $spec_mark_id,
  1253. 'spec_value_id' => $spec_value_id,
  1254. ];
  1255. $update = [
  1256. 'spec_is_select' => 1,
  1257. 'update_time' => getTime()
  1258. ];
  1259. $Value = Db::name('product_spec_data_handle')->where($where)->getField('spec_value');
  1260. $isResult = Db::name('product_spec_data_handle')->where($where)->update($update);
  1261. if (!empty($isResult)) {
  1262. // 仅ID信息,二维数组形式
  1263. $where = [
  1264. 'aid' => $aid,
  1265. 'spec_is_select' => 1,
  1266. ];
  1267. $order = 'spec_value_id asc, spec_id asc, spec_mark_id asc';
  1268. $data = Db::name('product_spec_data_handle')->field('spec_mark_id, spec_value_id')->where($where)->order($order)->select();
  1269. if (!empty($data)) {
  1270. foreach ($data as $key => $value) {
  1271. $spec_array[$value['spec_mark_id']][] = $value['spec_value_id'];
  1272. }
  1273. }
  1274. }
  1275. // 剔除已选择的规格值查询未选择的规格值组装成下拉返回
  1276. $notInPresetID = !empty($spec_array[$specMarkID]) ? $spec_array[$specMarkID] : [];
  1277. $where = [
  1278. 'aid' => $aid,
  1279. 'spec_is_select' => 0,
  1280. 'spec_mark_id' => ['IN', $spec_mark_id],
  1281. ];
  1282. if (!empty($notInPresetID)) $where['spec_value_id'] = ['NOT IN', $notInPresetID];
  1283. $specData = Db::name('product_spec_data_handle')->where($where)->order('spec_value_id asc')->select();
  1284. // 拼装下拉选项
  1285. $Option = '<option value="0">选择规格值</option>';
  1286. if (!empty($specData)) {
  1287. foreach ($specData as $value) {
  1288. $Option .= "<option value='{$value['spec_value_id']}'>{$value['spec_value']}</option>";
  1289. }
  1290. }
  1291. $htmlTable = $this->productSpecLogic->SpecAssemblyEdit($spec_array, $aid);
  1292. // 返回数据
  1293. $returnHtml = [
  1294. 'Value' => $Value,
  1295. 'Option' => $Option,
  1296. 'htmlTable' => $htmlTable
  1297. ];
  1298. $this->success('加载成功!', null, $returnHtml);
  1299. }
  1300. }
  1301. // 商品属性列表
  1302. public function attrlist_index()
  1303. {
  1304. // 查询条件
  1305. $Where = [];
  1306. $keywords = input('keywords/s');
  1307. if (!empty($keywords)) $Where['list_name'] = ['LIKE', "%{$keywords}%"];
  1308. $Where['lang'] = $this->admin_lang;
  1309. $Where['is_del'] = 0;
  1310. // 分页
  1311. $count = $this->shop_product_attrlist_db->where($Where)->count('list_id');
  1312. $pageObj = new Page($count, config('paginate.list_rows'));
  1313. $pageStr = $pageObj->show();
  1314. $this->assign('pager', $pageObj);
  1315. $this->assign('page', $pageStr);
  1316. // 数据
  1317. $list = $this->shop_product_attrlist_db
  1318. ->where($Where)
  1319. ->order('sort_order asc, list_id asc')
  1320. ->limit($pageObj->firstRow . ',' . $pageObj->listRows)
  1321. ->select();
  1322. $this->assign('list', $list);
  1323. // 内容管理的产品发布/编辑里入口进来
  1324. $oldinlet = input('param.oldinlet/d');
  1325. $this->assign('oldinlet', $oldinlet);
  1326. return $this->fetch();
  1327. }
  1328. // 保存全部参数
  1329. public function attrlist_save()
  1330. {
  1331. function_exists('set_time_limit') && set_time_limit(0);
  1332. if (IS_AJAX_POST) {
  1333. $post = input('post.');
  1334. // 参数名称不可重复
  1335. $ListName = array_unique($post['list_name']);
  1336. if (count($ListName) != count($post['list_name'])) $this->error('参数名称不可重复!');
  1337. // 数据拼装
  1338. $SaveData = [];
  1339. foreach ($ListName as $key => $value) {
  1340. if (!empty($value)) {
  1341. $list_id = $post['list_id'][$key];
  1342. $list_name = trim($value);
  1343. $SaveData[$key] = [
  1344. 'list_id' => !empty($list_id) ? $list_id : 0,
  1345. 'list_name' => $list_name,
  1346. 'desc' => !empty($post['desc'][$key]) ? $post['desc'][$key] : '',
  1347. 'sort_order' => !empty($post['sort_order'][$key]) ? $post['sort_order'][$key] : 100,
  1348. 'update_time' => getTime()
  1349. ];
  1350. if (empty($list_id)) {
  1351. $SaveData[$key]['add_time'] = getTime();
  1352. unset($SaveData[$key]['list_id']);
  1353. }
  1354. }
  1355. }
  1356. $ReturnId = model('ShopProductAttrlist')->saveAll($SaveData);
  1357. if ($ReturnId) {
  1358. adminLog('新增商品参数:' . implode(',', $post['list_name']));
  1359. $this->success('操作成功', url('Product/attrlist_index'));
  1360. } else {
  1361. $this->error('操作失败');
  1362. }
  1363. }
  1364. }
  1365. /**
  1366. * 新增参数
  1367. * @return [type] [description]
  1368. */
  1369. public function attrlist_add()
  1370. {
  1371. if (IS_AJAX_POST) {
  1372. $post = input('post.');
  1373. $post['list_name'] = trim($post['list_name']);
  1374. if (empty($post['list_name'])) {
  1375. $this->error('参数名称不能为空!');
  1376. }
  1377. $SaveData = [
  1378. 'list_name' => $post['list_name'],
  1379. 'desc' => trim($post['desc']),
  1380. 'sort_order' => 100,
  1381. 'lang' => $this->admin_lang,
  1382. 'add_time' => getTime(),
  1383. 'update_time' => getTime(),
  1384. ];
  1385. $ReturnId = Db::name('shop_product_attrlist')->insertGetId($SaveData);
  1386. if ($ReturnId) {
  1387. adminLog('新增商品参数:' . $post['list_name']);
  1388. if (!empty($post['attr_name'])) {
  1389. //数据拼接
  1390. $saveAttrData = [];
  1391. foreach ($post['attr_name'] as $k => $v) {
  1392. $attr_values = str_replace('_', '', $v); // 替换特殊字符
  1393. $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
  1394. $attr_values = trim($attr_values);
  1395. if (empty($attr_values)) {
  1396. unset($post['attr_name'][$k]);
  1397. continue;
  1398. }
  1399. $post['attr_name'][$k] = $attr_values;
  1400. $saveAttrData[] = array(
  1401. 'attr_name' => !empty($post['attr_name'][$k]) ? $post['attr_name'][$k] : '',
  1402. 'list_id' => $ReturnId,
  1403. 'attr_input_type' => !empty($post['attr_input_type'][$k]) ? intval($post['attr_input_type'][$k]) : 0,
  1404. 'attr_values' => !empty($post['attr_values'][$k]) ? trim($post['attr_values'][$k]) : '',
  1405. 'sort_order' => isset($post['attr_sort_order'][$k]) ? intval($post['attr_sort_order'][$k]) : 100,
  1406. 'status' => 1,
  1407. 'lang' => $this->admin_lang,
  1408. 'add_time' => getTime(),
  1409. 'update_time' => getTime(),
  1410. );
  1411. }
  1412. if (!empty($saveAttrData)) {
  1413. $rdata = model('ShopProductAttribute')->saveAll($saveAttrData);
  1414. if ($rdata !== false) {
  1415. // 参数值合计增加
  1416. Db::name('shop_product_attrlist')->where('list_id', $ReturnId)->setInc('attr_count', count($post['attr_name']));
  1417. }
  1418. }
  1419. }
  1420. $this->success('操作成功', url('ShopProduct/attrlist_index'));
  1421. }
  1422. $this->error('操作失败');
  1423. }
  1424. return $this->fetch();
  1425. }
  1426. /**
  1427. * 编辑参数
  1428. * @return [type] [description]
  1429. */
  1430. public function attrlist_edit()
  1431. {
  1432. if (IS_AJAX_POST) {
  1433. $post = input('post.');
  1434. $post['list_id'] = intval($post['list_id']);
  1435. $post['list_name'] = trim($post['list_name']);
  1436. if (empty($post['list_name'])) {
  1437. $this->error('参数名称不能为空!');
  1438. }
  1439. $SaveData = [
  1440. 'list_name' => $post['list_name'],
  1441. 'desc' => trim($post['desc']),
  1442. 'update_time' => getTime(),
  1443. ];
  1444. $res = Db::name('shop_product_attrlist')->where('list_id', $post['list_id'])->update($SaveData);
  1445. if ($res) {
  1446. adminLog('编辑商品参数:' . $post['list_name']);
  1447. if (!empty($post['attr_name'])) {
  1448. //数据拼接
  1449. $saveAttrData = [];
  1450. $attr_ids = [];
  1451. $time = getTime();
  1452. foreach ($post['attr_name'] as $k => $v) {
  1453. $attr_values = str_replace('_', '', $v); // 替换特殊字符
  1454. $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
  1455. $post['attr_name'][$k] = trim($attr_values);
  1456. $attrData = array(
  1457. 'attr_name' => !empty($post['attr_name'][$k]) ? $post['attr_name'][$k] : '',
  1458. 'list_id' => !empty($post['list_id']) ? intval($post['list_id']) : 0,
  1459. 'attr_input_type' => !empty($post['attr_input_type'][$k]) ? intval($post['attr_input_type'][$k]) : 0,
  1460. 'attr_values' => !empty($post['attr_values'][$k]) ? trim($post['attr_values'][$k]) : '',
  1461. 'sort_order' => isset($post['attr_sort_order'][$k]) ? intval($post['attr_sort_order'][$k]) : 100,
  1462. 'update_time' => $time,
  1463. );
  1464. if (!empty($post['attr_id'][$k])) {
  1465. $attrData['attr_id'] = $post['attr_id'][$k];
  1466. $attrData['add_time'] = $time;
  1467. $attr_ids[] = $post['attr_id'][$k];
  1468. }
  1469. $saveAttrData[] = $attrData;
  1470. }
  1471. if (!empty($saveAttrData)) {
  1472. $RId = model('ShopProductAttribute')->saveAll($saveAttrData);
  1473. if ($RId !== false) {
  1474. //删除多余的参数
  1475. Db::name('shop_product_attribute')
  1476. ->where([
  1477. 'list_id' => $post['list_id'],
  1478. 'attr_id' => ['NOTIN', $attr_ids],
  1479. 'update_time'=> ['NEQ', $time],
  1480. ])
  1481. ->delete();
  1482. // 参数值合计增加
  1483. Db::name('shop_product_attrlist')->where('list_id', $post['list_id'])->update(['attr_count' => count($saveAttrData), 'update_time' => getTime()]);
  1484. } else {
  1485. $this->error('操作失败');
  1486. }
  1487. }
  1488. }else{
  1489. //删除多余的参数
  1490. Db::name('shop_product_attribute')
  1491. ->where('list_id', $post['list_id'])
  1492. ->delete();
  1493. // 参数值合计增加
  1494. Db::name('shop_product_attrlist')->where('list_id', $post['list_id'])->update(['attr_count' => 0, 'update_time' => getTime()]);
  1495. }
  1496. $this->success('操作成功', url('ShopProduct/attrlist_index'));
  1497. }
  1498. $this->error('操作失败');
  1499. }
  1500. $list_id = input('param.list_id');
  1501. $list = Db::name('shop_product_attrlist')->where('list_id', $list_id)->find();
  1502. if (empty($list)) $this->error('数据不存在,请联系管理员!');
  1503. $list['attr'] = Db::name('shop_product_attribute')->where('list_id', $list_id)->order('sort_order asc, attr_id asc')->select();
  1504. $this->assign('list', $list);
  1505. return $this->fetch();
  1506. }
  1507. // 参数删除
  1508. public function attrlist_del()
  1509. {
  1510. $id_arr = input('del_id/a');
  1511. $id_arr = eyIntval($id_arr);
  1512. if (!empty($id_arr)) {
  1513. $Result = $this->shop_product_attrlist_db->where('list_id', 'IN', $id_arr)->delete();
  1514. if ($Result) {
  1515. Db::name('shop_product_attribute')->where('list_id', 'IN', $id_arr)->delete();
  1516. adminLog('删除商品参数-id:' . implode(',', $id_arr));
  1517. $this->success('删除成功');
  1518. } else {
  1519. $this->error('删除失败');
  1520. }
  1521. } else {
  1522. $this->error('参数有误');
  1523. }
  1524. }
  1525. /**
  1526. * 商品参数值列表
  1527. */
  1528. public function attribute_index()
  1529. {
  1530. $condition = array();
  1531. // 获取到所有GET参数
  1532. $get = input('get.');
  1533. $list_id = input('list_id/d', 0);
  1534. // 应用搜索条件
  1535. foreach (['keywords', 'list_id'] as $key) {
  1536. if (isset($get[$key]) && $get[$key] !== '') {
  1537. if ($key == 'keywords') {
  1538. $condition['a.attr_name'] = ['LIKE', "%{$get[$key]}%"];
  1539. } else if ($key == 'list_id') {
  1540. $condition['a.list_id'] = $list_id;
  1541. } else {
  1542. $condition['a.' . $key] = ['eq', $get[$key]];
  1543. }
  1544. }
  1545. }
  1546. $condition['a.lang'] = $this->admin_lang;
  1547. $condition['a.is_del'] = 0;
  1548. // 分页
  1549. $count = Db::name('shop_product_attribute')->alias('a')->where($condition)->count();
  1550. $pageObj = new Page($count, config('paginate.list_rows'));
  1551. $pageStr = $pageObj->show();
  1552. $this->assign('pager', $pageObj);
  1553. $this->assign('page', $pageStr);
  1554. // 数据
  1555. $list = Db::name('shop_product_attribute')
  1556. ->alias('a')
  1557. ->where($condition)
  1558. ->order('a.sort_order asc, a.attr_id asc')
  1559. ->limit($pageObj->firstRow . ',' . $pageObj->listRows)
  1560. ->select();
  1561. $attrInputTypeArr = [
  1562. 0 => '手工录入',
  1563. 1 => '选取默认值'
  1564. ];
  1565. $this->assign('attrInputTypeArr', $attrInputTypeArr);
  1566. $this->assign('list', $list);
  1567. return $this->fetch();
  1568. }
  1569. /**
  1570. * 新增商品参数
  1571. */
  1572. public function attribute_add()
  1573. {
  1574. //防止php超时
  1575. function_exists('set_time_limit') && set_time_limit(0);
  1576. if (IS_AJAX_POST) {
  1577. $attr_values = str_replace('_', '', input('attr_values')); // 替换特殊字符
  1578. $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
  1579. $attr_values = trim($attr_values);
  1580. $post_data = input('post.');
  1581. $post_data['list_id'] = intval($post_data['list_id']);
  1582. $post_data['attr_values'] = $attr_values;
  1583. $SaveData = array(
  1584. 'attr_name' => $post_data['attr_name'],
  1585. 'list_id' => $post_data['list_id'],
  1586. 'attr_input_type' => isset($post_data['attr_input_type']) ? $post_data['attr_input_type'] : '',
  1587. 'attr_values' => isset($post_data['attr_values']) ? $post_data['attr_values'] : '',
  1588. 'sort_order' => $post_data['sort_order'],
  1589. 'status' => 1,
  1590. 'lang' => $this->admin_lang,
  1591. 'add_time' => getTime(),
  1592. 'update_time' => getTime(),
  1593. );
  1594. $ReturnId = Db::name('shop_product_attribute')->add($SaveData);
  1595. if ($ReturnId) {
  1596. // 参数值合计增加
  1597. Db::name('shop_product_attrlist')->where('list_id', $post_data['list_id'])->setInc('attr_count');
  1598. adminLog('新增商品参数:' . $SaveData['attr_name']);
  1599. $this->success('操作成功');
  1600. } else {
  1601. $this->error('操作失败');
  1602. }
  1603. }
  1604. $list_id = input('param.list_id/d', 0);
  1605. $list = $this->shop_product_attrlist_db->where('list_id', $list_id)->find();
  1606. $this->assign('list', $list);
  1607. return $this->fetch();
  1608. }
  1609. /**
  1610. * 编辑商品参数
  1611. */
  1612. public function attribute_edit()
  1613. {
  1614. //防止php超时
  1615. function_exists('set_time_limit') && set_time_limit(0);
  1616. if (IS_AJAX_POST) {
  1617. $attr_values = str_replace('_', '', input('attr_values')); // 替换特殊字符
  1618. $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
  1619. $attr_values = trim($attr_values);
  1620. $post_data = input('post.');
  1621. $post_data['list_id'] = intval($post_data['list_id']);
  1622. $post_data['attr_values'] = $attr_values;
  1623. $SaveData = array(
  1624. 'attr_name' => $post_data['attr_name'],
  1625. 'list_id' => $post_data['list_id'],
  1626. 'attr_input_type' => isset($post_data['attr_input_type']) ? $post_data['attr_input_type'] : '',
  1627. 'attr_values' => isset($post_data['attr_values']) ? $post_data['attr_values'] : '',
  1628. 'sort_order' => $post_data['sort_order'],
  1629. 'update_time' => getTime(),
  1630. );
  1631. $ReturnId = Db::name('shop_product_attribute')->where(['attr_id'=>$post_data['attr_id'], 'lang'=>$this->admin_lang])->update($SaveData);
  1632. if ($ReturnId) {
  1633. adminLog('编辑商品参数:' . $SaveData['attr_name']);
  1634. $this->success('操作成功');
  1635. } else {
  1636. $this->error('操作失败');
  1637. }
  1638. }
  1639. $id = input('param.id/d');
  1640. $info = Db::name('shop_product_attribute')->where(['attr_id'=>$id, 'lang'=>$this->admin_lang])->find();
  1641. if (empty($info)) $this->error('数据不存在,请联系管理员!');
  1642. $this->assign('field', $info);
  1643. $list = $this->shop_product_attrlist_db->where('list_id', $info['list_id'])->find();
  1644. $this->assign('list', $list);
  1645. return $this->fetch();
  1646. }
  1647. /**
  1648. * 删除商品参数
  1649. */
  1650. public function attribute_del()
  1651. {
  1652. $id_arr = input('del_id/a');
  1653. $id_arr = eyIntval($id_arr);
  1654. if (!empty($id_arr)) {
  1655. $r = Db::name('shop_product_attribute')->where(['attr_id' => ['IN', $id_arr], 'lang'=>$this->admin_lang])->delete();
  1656. if ($r) {
  1657. $IDCount = count($id_arr);
  1658. Db::name('shop_product_attrlist')->where('list_id', input('list_id/d'))->setDec('attr_count', $IDCount);
  1659. adminLog('删除商品参数-id:' . implode(',', $id_arr));
  1660. $this->success('删除成功');
  1661. } else {
  1662. $this->error('删除失败');
  1663. }
  1664. } else {
  1665. $this->error('参数有误');
  1666. }
  1667. }
  1668. /**
  1669. * 动态获取商品参数输入框 根据不同的数据返回不同的输入框类型
  1670. */
  1671. public function ajax_get_shop_attr_input($typeid = '', $aid = '', $list_id = '')
  1672. {
  1673. $typeid = intval($typeid);
  1674. $aid = intval($aid);
  1675. $list_id = intval($list_id);
  1676. $productLogic = new ProductLogic();
  1677. $str = $productLogic->getShopAttrInput($aid, $typeid, $list_id);
  1678. if (empty($str)) {
  1679. $str = '<div style="font-size: 12px;text-align: center;">提示:该参数还没有参数值,若有需要请点击【<a href="' . url('Product/attribute_index', array('list_id' => $list_id)) . '">商品参数</a>】进行更多操作。</div>';
  1680. }
  1681. if (IS_AJAX) {
  1682. exit($str);
  1683. } else {
  1684. return $str;
  1685. }
  1686. }
  1687. /**
  1688. * 动态获取商品参数输入框 根据不同的数据返回不同的输入框类型
  1689. */
  1690. public function ajax_get_attr_input($typeid = '', $aid = '', $list_id = '')
  1691. {
  1692. $typeid = intval($typeid);
  1693. $aid = intval($aid);
  1694. $list_id = intval($list_id);
  1695. $productLogic = new ProductLogic();
  1696. $str = $productLogic->getAttrInput($aid, $typeid, $list_id);
  1697. if (empty($str)) {
  1698. $str = '<div style="font-size: 12px;text-align: center;">提示:该参数还没有参数值,若有需要请点击【<a href="' . url('Product/attribute_index', array('list_id' => $list_id)) . '">商品参数</a>】进行更多操作。</div>';
  1699. }
  1700. if (IS_AJAX) {
  1701. exit($str);
  1702. } else {
  1703. return $str;
  1704. }
  1705. }
  1706. /**
  1707. * 发布商品
  1708. */
  1709. public function release()
  1710. {
  1711. $typeid = input('param.typeid/d', 0);
  1712. if (0 < $typeid) {
  1713. $param = input('param.');
  1714. $row = Db::name('arctype')->field('current_channel')->find($typeid);
  1715. /*针对不支持发布文档的模型*/
  1716. if ($row['current_channel'] != 2) {
  1717. $this->error('该栏目不支持发布商品!', url('ShopProduct/release'));
  1718. }
  1719. /*-----end*/
  1720. $data = [
  1721. 'typeid' => $typeid,
  1722. 'callback_url' => $this->callback_url,
  1723. ];
  1724. $jumpUrl = url("ShopProduct/add", $data, true, true);
  1725. header('Location: ' . $jumpUrl);
  1726. exit;
  1727. }
  1728. /*允许发布文档列表的栏目*/
  1729. $select_html = allow_release_arctype(0, [2]);
  1730. $this->assign('select_html', $select_html);
  1731. /*--end*/
  1732. return $this->fetch();
  1733. }
  1734. //帮助
  1735. public function help()
  1736. {
  1737. $system_originlist = tpSetting('system.system_originlist');
  1738. $system_originlist = json_decode($system_originlist, true);
  1739. $system_originlist = !empty($system_originlist) ? $system_originlist : [];
  1740. $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
  1741. $this->assign($assign_data);
  1742. return $this->fetch();
  1743. }
  1744. }