作者 Cool
1 个管道 的构建 通过 耗费 1 秒

Merge branch 'master' of http://114.215.101.231:8099/guosheng/community into liuzhen

# Conflicts:
#	public/api.html
  1 +<?php
  2 +
  3 +namespace app\admin\controller;
  4 +
  5 +use app\common\controller\Backend;
  6 +use app\admin\model\Housespec as SpecModel;
  7 +use app\admin\model\Housespecvalue as SpecValueModel;
  8 +
  9 +/**
  10 + * 社区活动管理
  11 + *
  12 + * @icon fa fa-circle-o
  13 + */
  14 +class HouseActivity extends Backend
  15 +{
  16 +
  17 + /**
  18 + * HouseActivity模型对象
  19 + * @var \app\admin\model\HouseActivity
  20 + */
  21 + protected $model = null;
  22 +
  23 + public function _initialize()
  24 + {
  25 + parent::_initialize();
  26 + $this->SpecModel = new SpecModel;
  27 + $this->SpecValueModel = new SpecValueModel;
  28 + $this->model = new \app\admin\model\HouseActivity;
  29 + $this->view->assign("specTypeList", $this->model->getSpecTypeList());
  30 + }
  31 +
  32 + /**
  33 + * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
  34 + * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
  35 + * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
  36 + */
  37 +
  38 +
  39 + /**
  40 + * 查看
  41 + */
  42 + public function index()
  43 + {
  44 + //当前是否为关联查询
  45 + $this->relationSearch = false;
  46 + //设置过滤方法
  47 + $this->request->filter(['strip_tags', 'trim']);
  48 + if ($this->request->isAjax())
  49 + {
  50 + //如果发送的来源是Selectpage,则转发到Selectpage
  51 + if ($this->request->request('keyField'))
  52 + {
  53 + return $this->selectpage();
  54 + }
  55 + list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  56 + $total = $this->model
  57 +
  58 + ->where($where)
  59 + ->order($sort, $order)
  60 + ->count();
  61 +
  62 + $list = $this->model
  63 +
  64 + ->where($where)
  65 + ->order($sort, $order)
  66 + ->limit($offset, $limit)
  67 + ->select();
  68 +
  69 + foreach ($list as $row) {
  70 + $row->visible(['id','title','spec_type','start_time','end_time','updatetime']);
  71 +
  72 + }
  73 + $list = collection($list)->toArray();
  74 + $result = array("total" => $total, "rows" => $list);
  75 +
  76 + return json($result);
  77 + }
  78 + return $this->view->fetch();
  79 + }
  80 +
  81 + public function addSpec($spec_name, $spec_value){
  82 + // 判断规格组是否存在
  83 + if (!$specId = $this->SpecModel->getSpecIdByName($spec_name)) {
  84 + // 新增规格组and规则值
  85 + if ($this->SpecModel->add($spec_name)
  86 + && $this->SpecValueModel->add($this->SpecModel['id'], $spec_value))
  87 + return $this->success('', '', [
  88 + 'spec_id' => (int)$this->SpecModel['id'],
  89 + 'spec_value_id' => (int)$this->SpecValueModel['id'],
  90 + ]);
  91 + return $this->error();
  92 + }
  93 + //return ;
  94 + // 判断规格值是否存在
  95 + if ($specValueId = $this->SpecValueModel->getSpecValueIdByName($specId, $spec_value)) {
  96 + return $this->success('', '', [
  97 + 'spec_id' => (int)$specId,
  98 + 'spec_value_id' => (int)$specValueId,
  99 + ]);
  100 + }
  101 + // 添加规则值
  102 + if ($this->SpecValueModel->add($specId, $spec_value))
  103 + return $this->success('', '', [
  104 + 'spec_id' => (int)$specId,
  105 + 'spec_value_id' => (int)$this->SpecValueModel['id'],
  106 + ]);
  107 + return $this->error();
  108 + }
  109 +
  110 +
  111 + /**
  112 + * 添加规格值
  113 + */
  114 + public function addSpecValue($spec_id, $spec_value)
  115 + {
  116 + // 判断规格值是否存在
  117 + if ($specValueId = $this->SpecValueModel->getSpecValueIdByName($spec_id, $spec_value)) {
  118 + return $this->success('', '', [
  119 + 'spec_value_id' => (int)$specValueId,
  120 + ]);
  121 + }
  122 + // 添加规则值
  123 + if ($this->SpecValueModel->add($spec_id, $spec_value))
  124 + return $this->success('', '', [
  125 + 'spec_value_id' => (int)$this->SpecValueModel['id'],
  126 + ]);
  127 + return $this->error();
  128 + }
  129 +
  130 + /**
  131 + * 添加
  132 + */
  133 + public function add()
  134 + {
  135 + if ($this->request->isPost()) {
  136 + $params = $this->request->post("row/a");
  137 + if ($params) {
  138 + if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
  139 + $params[$this->dataLimitField] = $this->auth->id;
  140 + }
  141 + try {
  142 + //是否采用模型验证
  143 + if ($this->modelValidate) {
  144 + $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  145 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
  146 + $this->model->validate($validate);
  147 + }
  148 + $result = $this->model->allowField(true)->save($params);
  149 + if ($result !== false) {
  150 + //成功之后 存储商品规格
  151 + $spec_many_params = $this->request->post("spec_many/a");
  152 + $this->model->addGoodsSpec($params,$spec_many_params,$this->request->post("spec/a"));
  153 + $this->success();
  154 + } else {
  155 + $this->error($this->model->getError());
  156 + }
  157 + } catch (\think\exception\PDOException $e) {
  158 + $this->error($e->getMessage());
  159 + } catch (\think\Exception $e) {
  160 + $this->error($e->getMessage());
  161 + }
  162 + }
  163 + $this->error(__('Parameter %s can not be empty', ''));
  164 + }
  165 + return $this->view->fetch();
  166 + }
  167 +
  168 + /**
  169 + * 删除
  170 + */
  171 + public function del($ids = "")
  172 + {
  173 + if ($ids) {
  174 + $pk = $this->model->getPk();
  175 + $adminIds = $this->getDataLimitAdminIds();
  176 + if (is_array($adminIds)) {
  177 + $count = $this->model->where($this->dataLimitField, 'in', $adminIds);
  178 + }
  179 + $list = $this->model->where($pk, 'in', $ids)->select();
  180 + $count = 0;
  181 + foreach ($list as $k => $v) {
  182 + // 删除商品sku
  183 + $v->removesku();
  184 +
  185 + $count += $v->delete();
  186 + }
  187 + if ($count) {
  188 + $this->success();
  189 + } else {
  190 + $this->error(__('No rows were deleted'));
  191 + }
  192 + }
  193 + $this->error(__('Parameter %s can not be empty', 'ids'));
  194 + }
  195 +
  196 + /**
  197 + * 编辑
  198 + */
  199 + public function edit($ids = NULL)
  200 + {
  201 + $row = $this->model->get($ids, ['specRel', 'spec', 'spec_rel.spec']);
  202 + if (!$row)
  203 + $this->error(__('No Results were found'));
  204 + $adminIds = $this->getDataLimitAdminIds();
  205 + if (is_array($adminIds)) {
  206 + if (!in_array($row[$this->dataLimitField], $adminIds)) {
  207 + $this->error(__('You have no permission'));
  208 + }
  209 + }
  210 + if ($this->request->isPost()) {
  211 + $params = $this->request->post("row/a");
  212 + if ($params) {
  213 + try {
  214 + //是否采用模型验证
  215 + if ($this->modelValidate) {
  216 + $name = basename(str_replace('\\', '/', get_class($this->model)));
  217 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate;
  218 + $row->validate($validate);
  219 + }
  220 + $result = $row->allowField(true)->save($params);
  221 + if ($result !== false) {
  222 + //成功之后 存储商品规格
  223 + $spec_many_params = $this->request->post("spec_many/a");
  224 + $row->addGoodsSpec($params,$spec_many_params,$this->request->post("spec/a"), true);
  225 + $this->success();
  226 + } else {
  227 + $this->error($row->getError());
  228 + }
  229 + } catch (\think\exception\PDOException $e) {
  230 + $this->error($e->getMessage());
  231 + } catch (\think\Exception $e) {
  232 + $this->error($e->getMessage());
  233 + }
  234 + }
  235 + $this->error(__('Parameter %s can not be empty', ''));
  236 + }
  237 + // 多规格信息
  238 + $specData = 'null';
  239 + if ($row['spec_type'] === '2'){
  240 + $specData = json_encode($this->model->getManySpecData($row['spec_rel'], $row['spec']));
  241 + }
  242 + $row['specData'] = $specData;
  243 + $this->view->assign("row", $row);
  244 + return $this->view->fetch();
  245 + }
  246 +}
  1 +<?php
  2 +
  3 +return [
  4 + 'Id' => 'ID',
  5 + 'Title' => '活动标题',
  6 + 'Content' => '描述详情',
  7 + 'Spec_type' => '活动规格',
  8 + 'Spec_type 0' => '无规格(免费)',
  9 + 'Spec_type 1' => '单规格',
  10 + 'Spec_type 2' => '多规格',
  11 + 'House_ids' => '社区ID集合',
  12 + 'Start_time' => '活动开始时间',
  13 + 'End_time' => '活动结束时间',
  14 + 'Createtime' => '创建时间',
  15 + 'Updatetime' => '更新时间'
  16 +];
  1 +<?php
  2 +
  3 +namespace app\admin\model;
  4 +
  5 +use think\Model;
  6 +
  7 +
  8 +class HouseActivity extends Model
  9 +{
  10 +
  11 +
  12 +
  13 +
  14 +
  15 + // 表名
  16 + protected $name = 'house_activity';
  17 +
  18 + // 自动写入时间戳字段
  19 + protected $autoWriteTimestamp = 'int';
  20 +
  21 + // 定义时间戳字段名
  22 + protected $createTime = 'createtime';
  23 + protected $updateTime = 'updatetime';
  24 + protected $deleteTime = false;
  25 +
  26 + // 追加属性
  27 + protected $append = [
  28 + 'spec_type_text',
  29 + 'start_time_text',
  30 + 'end_time_text'
  31 + ];
  32 +
  33 +
  34 +
  35 + public function getSpecTypeList()
  36 + {
  37 + return ['0' => __('Spec_type 0'), '1' => __('Spec_type 1'), '2' => __('Spec_type 2')];
  38 + }
  39 +
  40 +
  41 + public function getSpecTypeTextAttr($value, $data)
  42 + {
  43 + $value = $value ? $value : (isset($data['spec_type']) ? $data['spec_type'] : '');
  44 + $list = $this->getSpecTypeList();
  45 + return isset($list[$value]) ? $list[$value] : '';
  46 + }
  47 +
  48 +
  49 + public function getStartTimeTextAttr($value, $data)
  50 + {
  51 + $value = $value ? $value : (isset($data['start_time']) ? $data['start_time'] : '');
  52 + return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
  53 + }
  54 +
  55 +
  56 + public function getEndTimeTextAttr($value, $data)
  57 + {
  58 + $value = $value ? $value : (isset($data['end_time']) ? $data['end_time'] : '');
  59 + return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
  60 + }
  61 +
  62 + protected function setStartTimeAttr($value)
  63 + {
  64 + return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
  65 + }
  66 +
  67 + protected function setEndTimeAttr($value)
  68 + {
  69 + return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
  70 + }
  71 +
  72 + /**
  73 + * 关联活动规格表
  74 + */
  75 + public function spec()
  76 + {
  77 + return $this->hasMany('Houseactivityspec','house_activity_id','id');
  78 + }
  79 +
  80 + /**
  81 + * 关联活动规格关系表
  82 + */
  83 + public function specRel()
  84 + {
  85 + return $this->belongsToMany('Housespecvalue', 'house_activity_spec_rel','spec_value_id','house_activity_id');
  86 + }
  87 +
  88 + /**
  89 + * 添加活动规格
  90 + * @param $data
  91 + * @param $isUpdate
  92 + * @throws \Exception
  93 + */
  94 + public function addGoodsSpec(&$data,$params,$specparams,$isUpdate = false)
  95 + {
  96 + // 更新模式: 先删除所有规格
  97 + $model = new Houseactivityspec;
  98 + $isUpdate && $model->removeAll($this['id']);
  99 + // 添加规格数据
  100 + if ($data['spec_type'] === '1') {
  101 + // 单规格
  102 + $this->spec()->save($specparams);
  103 + } else if ($data['spec_type'] === '2') {
  104 + // 添加商品与规格关系记录
  105 + $model->addGoodsSpecRel($this['id'],$params['spec_attr']);
  106 + // 添加商品sku
  107 + $model->addSkuList($this['id'],$params['spec_list']);
  108 + }
  109 + }
  110 +
  111 + public function removesku(){
  112 + // 删除活动sku
  113 + (new Houseactivityspec)->removeAll($this['id']);
  114 + }
  115 + /**
  116 + * 获取规格信息
  117 + */
  118 + public function getManySpecData($spec_rel, $skuData)
  119 + {
  120 + // spec_attr
  121 + $specAttrData = [];
  122 + foreach ($spec_rel as $item) {
  123 + if (!isset($specAttrData[$item['spec_id']])) {
  124 + $specAttrData[$item['spec_id']] = [
  125 + 'group_id' => $item['spec']['id'],
  126 + 'group_name' => $item['spec']['spec_name'],
  127 + 'spec_items' => [],
  128 + ];
  129 + }
  130 + $specAttrData[$item['spec_id']]['spec_items'][] = [
  131 + 'item_id' => $item['pivot']['spec_value_id'],
  132 + 'spec_value' => $item['spec_value'],
  133 + ];
  134 + }
  135 +
  136 + // spec_list
  137 + $specListData = [];
  138 + foreach ($skuData as $item) {
  139 + $specListData[] = [
  140 + 'id' => $item['id'],
  141 + 'spec_sku_id' => $item['spec_sku_id'],
  142 + 'rows' => [],
  143 + 'form' => [
  144 + 'price' => $item['price'],
  145 + ],
  146 + ];
  147 + }
  148 + return ['spec_attr' => array_values($specAttrData), 'spec_list' => $specListData];
  149 + }
  150 +
  151 +}
  1 +<?php
  2 +
  3 +namespace app\admin\model;
  4 +use think\Model;
  5 +
  6 +class Houseactivityspec extends Model
  7 +{
  8 +
  9 + // 表名
  10 + protected $name = 'house_activity_spec';
  11 +
  12 + // 自动写入时间戳字段
  13 + protected $autoWriteTimestamp = 'int';
  14 +
  15 + // 定义时间戳字段名
  16 + protected $createTime = 'create_time';
  17 + protected $updateTime = 'update_time';
  18 +
  19 + /**
  20 + * 批量添加活动sku记录
  21 + * @param $house_activity_id
  22 + * @param $spec_list
  23 + * @return array|false
  24 + * @throws \Exception
  25 + */
  26 + public function addSkuList($house_activity_id, $spec_list)
  27 + {
  28 + $data = [];
  29 + foreach ($spec_list as $item) {
  30 + $data[] = array_merge($item['form'], [
  31 + 'spec_sku_id' => $item['spec_sku_id'],
  32 + 'house_activity_id' => $house_activity_id,
  33 + ]);
  34 + }
  35 + return $this->saveAll($data);
  36 + }
  37 +
  38 + /**
  39 + * 添加商品活动关系记录
  40 + * @param $house_activity_id
  41 + * @param $spec_attr
  42 + * @return array|false
  43 + * @throws \Exception
  44 + */
  45 + public function addGoodsSpecRel($house_activity_id, $spec_attr)
  46 + {
  47 + $data = [];
  48 + array_map(function ($val) use (&$data, $house_activity_id) {
  49 + array_map(function ($item) use (&$val, &$data, $house_activity_id) {
  50 + $data[] = [
  51 + 'house_activity_id' => $house_activity_id,
  52 + 'spec_id' => $val['group_id'],
  53 + 'spec_value_id' => $item['item_id'],
  54 + ];
  55 + }, $val['spec_items']);
  56 + }, $spec_attr);
  57 + $model = new Houseactivityspecrel;
  58 + return $model->saveAll($data);
  59 + }
  60 +
  61 + /**
  62 + * 移除指定活动的所有sku
  63 + * @param $house_activity_id
  64 + * @return int
  65 + */
  66 + public function removeAll($house_activity_id)
  67 + {
  68 + $model = new Houseactivityspecrel;
  69 + $model->where('house_activity_id','=', $house_activity_id)->delete();
  70 + return $this->where('house_activity_id','=', $house_activity_id)->delete();
  71 + }
  72 +}
  1 +<?php
  2 +
  3 +namespace app\admin\model;
  4 +use think\Model;
  5 +
  6 +class Houseactivityspecrel extends Model
  7 +{
  8 + // 表名
  9 + protected $name = 'house_activity_spec_rel';
  10 +
  11 + // 自动写入时间戳字段
  12 + protected $autoWriteTimestamp = 'int';
  13 +
  14 + // 定义时间戳字段名
  15 + protected $createTime = 'create_time';
  16 + protected $updateTime = '';
  17 +
  18 + /**
  19 + * 关联规格组
  20 + * @return \think\model\relation\BelongsTo
  21 + */
  22 + public function spec()
  23 + {
  24 + return $this->belongsTo('Housespec');
  25 + }
  26 +}
  1 +<?php
  2 +
  3 +namespace app\admin\model;
  4 +use think\Model;
  5 +/**
  6 + * 规格/属性(组)模型
  7 + * Class Spec
  8 + * @package app\store\model
  9 + */
  10 +class Housespec extends Model
  11 +{
  12 +
  13 + // 表名
  14 + protected $name = 'house_spec';
  15 +
  16 + // 自动写入时间戳字段
  17 + protected $autoWriteTimestamp = 'int';
  18 +
  19 + // 定义时间戳字段名
  20 + protected $createTime = 'createtime';
  21 + protected $updateTime = '';
  22 +
  23 + /**
  24 + * 根据规格组名称查询规格id
  25 + * @param $spec_name
  26 + * @return mixed
  27 + */
  28 + public function getSpecIdByName($spec_name)
  29 + {
  30 + return self::where(compact('spec_name'))->value('id');
  31 + }
  32 +
  33 + /**
  34 + * 新增规格组
  35 + * @param $spec_name
  36 + * @return false|int
  37 + */
  38 + public function add($spec_name)
  39 + {
  40 + return $this->save(compact('spec_name'));
  41 + }
  42 +
  43 +}
  1 +<?php
  2 +
  3 +namespace app\admin\model;
  4 +use think\Model;
  5 +/**
  6 + * 规格/属性(组)模型
  7 + * Class Spec
  8 + * @package app\store\model
  9 + */
  10 +class Housespecvalue extends Model
  11 +{
  12 +
  13 + // 表名
  14 + protected $name = 'house_spec_value';
  15 +
  16 + // 自动写入时间戳字段
  17 + protected $autoWriteTimestamp = 'int';
  18 +
  19 + // 定义时间戳字段名
  20 + protected $createTime = 'createtime';
  21 + protected $updateTime = '';
  22 +
  23 + /**
  24 + * 根据规格组名称查询规格id
  25 + * @param $spec_id
  26 + * @param $spec_value
  27 + * @return mixed
  28 + */
  29 + public function getSpecValueIdByName($spec_id, $spec_value)
  30 + {
  31 + return self::where(compact('spec_id', 'spec_value'))->value('id');
  32 + }
  33 +
  34 + /**
  35 + * 新增规格值
  36 + * @param $spec_id
  37 + * @param $spec_value
  38 + * @return false|int
  39 + */
  40 + public function add($spec_id, $spec_value)
  41 + {
  42 + return $this->save(compact('spec_value', 'spec_id'));
  43 + }
  44 +
  45 + /**
  46 + * 关联规格组表
  47 + * @return $this|\think\model\relation\BelongsTo
  48 + */
  49 + public function spec()
  50 + {
  51 + return $this->belongsTo('Housespec','spec_id','id');
  52 + }
  53 +
  54 +}
  1 +<?php
  2 +
  3 +namespace app\admin\validate;
  4 +
  5 +use think\Validate;
  6 +
  7 +class HouseActivity extends Validate
  8 +{
  9 + /**
  10 + * 验证规则
  11 + */
  12 + protected $rule = [
  13 + ];
  14 + /**
  15 + * 提示消息
  16 + */
  17 + protected $message = [
  18 + ];
  19 + /**
  20 + * 验证场景
  21 + */
  22 + protected $scene = [
  23 + 'add' => [],
  24 + 'edit' => [],
  25 + ];
  26 +
  27 +}
  1 +<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
  2 +
  3 + <div class="form-group">
  4 + <label class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
  5 + <div class="col-xs-12 col-sm-8">
  6 + <input id="c-title" data-rule="required" class="form-control" name="row[title]" type="text" value="">
  7 + </div>
  8 + </div>
  9 + <div class="form-group">
  10 + <label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
  11 + <div class="col-xs-12 col-sm-8">
  12 + <textarea id="c-content" data-rule="required" class="form-control editor" rows="5" name="row[content]" cols="50"></textarea>
  13 + </div>
  14 + </div>
  15 + <div class="form-group">
  16 + <label class="control-label col-xs-12 col-sm-2">{:__('Spec_type')}:</label>
  17 + <div class="col-xs-12 col-sm-8">
  18 +
  19 + <select id="c-spec_type" data-rule="required" class="form-control selectpicker" name="row[spec_type]">
  20 + {foreach name="specTypeList" item="vo"}
  21 + <option value="{$key}" {in name="key" value="0"}selected{/in}>{$vo}</option>
  22 + {/foreach}
  23 + </select>
  24 +
  25 + </div>
  26 + </div>
  27 + <!-- 活动规格属性 start -->
  28 +<div class="goods-spec-many form-group">
  29 + <!-- <label class="control-label col-xs-12 col-sm-2"></label>-->
  30 + <div class="goods-spec-box col-xs-12 col-sm-11" style="background-color: white;">
  31 + <!-- 规格属性 -->
  32 + <div class="spec-attr"></div>
  33 +
  34 + <!-- 添加规格:按钮 -->
  35 + <div class="spec-group-button">
  36 + <button type="button" class="btn-addSpecGroup btn btn-xs btn-success">添加规格</button>
  37 + </div>
  38 +
  39 + <!-- 添加规格:表单 -->
  40 + <div class="spec-group-add">
  41 + <div class="spec-group-add-item form-group">
  42 + <label class="control-label form-require">规格名 </label>
  43 + <input type="text" class="input-specName tpl-form-input"
  44 + placeholder="请输入规格名称">
  45 + </div>
  46 + <div class="spec-group-add-item form-group">
  47 + <label class="control-label form-require">规格值 </label>
  48 + <input type="text" class="input-specValue tpl-form-input"
  49 + placeholder="请输入规格值">
  50 + </div>
  51 + <div class="spec-group-add-item margin-top">
  52 + <button type="button" class="btn-addSpecName btn btn-xs btn-success"> 确定
  53 + </button>
  54 + <button type="button" class="btn-cancleAddSpecName btn btn-xs btn-default"> 取消
  55 + </button>
  56 + </div>
  57 + </div>
  58 + <!-- 商品多规格sku信息 -->
  59 + <div class="goods-sku scrollable-horizontal">
  60 + <!-- 分割线 -->
  61 + <div class="goods-spec-line"></div>
  62 + <!-- sku 批量设置 -->
  63 + <div class="spec-batch form-inline">
  64 + <div class="form-group">
  65 + <label class="control-label">批量设置</label>
  66 + </div>
  67 + <div class="form-group">
  68 + <input type="number" data-type="price" placeholder="报名费用">
  69 + </div>
  70 + <div class="form-group">
  71 + <button type="button" class="btn-specBatchBtn btn btn-sm btn-secondary
  72 + radius">确定
  73 + </button>
  74 + </div>
  75 + </div>
  76 + <!-- sku table -->
  77 + <table class="spec-sku-tabel table table-bordered table-centered margin-bottom-xs text-nowrap"></table>
  78 + </div>
  79 + </div>
  80 +</div>
  81 +
  82 +<div class="goods-spec-single">
  83 + <div class="form-group">
  84 + <label class="control-label col-xs-12 col-sm-2">报名费用:</label>
  85 + <div class="col-xs-12 col-sm-8">
  86 + <input id="c-price" data-rule="required" class="form-control form-control" name="spec[price]" type="number" value="0">
  87 + </div>
  88 + </div>
  89 +</div>
  90 +<!-- 活动规格属性 end -->
  91 +
  92 + <div class="form-group">
  93 + <label class="control-label col-xs-12 col-sm-2">{:__('House_ids')}:</label>
  94 + <div class="col-xs-12 col-sm-8">
  95 + <input id="c-house_ids" data-rule="required" data-source="house/index" data-multiple="true" class="form-control selectpage" name="row[house_ids]" type="text" value="">
  96 + </div>
  97 + </div>
  98 + <div class="form-group">
  99 + <label class="control-label col-xs-12 col-sm-2">{:__('Start_time')}:</label>
  100 + <div class="col-xs-12 col-sm-8">
  101 + <input id="c-start_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[start_time]" type="text" value="{:date('Y-m-d H:i:s')}">
  102 + </div>
  103 + </div>
  104 + <div class="form-group">
  105 + <label class="control-label col-xs-12 col-sm-2">{:__('End_time')}:</label>
  106 + <div class="col-xs-12 col-sm-8">
  107 + <input id="c-end_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[end_time]" type="text" value="{:date('Y-m-d H:i:s')}">
  108 + </div>
  109 + </div>
  110 + <div class="form-group layer-footer">
  111 + <label class="control-label col-xs-12 col-sm-2"></label>
  112 + <div class="col-xs-12 col-sm-8">
  113 + <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
  114 + <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
  115 + </div>
  116 + </div>
  117 +</form>
  118 +{include file="house_activity/spec_many_template" /}
  119 +
  120 +<link rel="stylesheet" href="__CDN__/assets/addons/litestore/css/litestoregoods.css">
  1 +<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
  2 +
  3 + <div class="form-group">
  4 + <label class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
  5 + <div class="col-xs-12 col-sm-8">
  6 + <input id="c-title" data-rule="required" class="form-control" name="row[title]" type="text" value="{$row.title|htmlentities}">
  7 + </div>
  8 + </div>
  9 + <div class="form-group">
  10 + <label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
  11 + <div class="col-xs-12 col-sm-8">
  12 + <textarea id="c-content" data-rule="required" class="form-control editor" rows="5" name="row[content]" cols="50">{$row.content|htmlentities}</textarea>
  13 + </div>
  14 + </div>
  15 + <div class="form-group">
  16 + <label class="control-label col-xs-12 col-sm-2">{:__('Spec_type')}:</label>
  17 + <div class="col-xs-12 col-sm-8">
  18 +
  19 + <select id="c-spec_type" data-rule="required" class="form-control selectpicker" name="row[spec_type]">
  20 + {foreach name="specTypeList" item="vo"}
  21 + <option value="{$key}" {in name="key" value="$row.spec_type"}selected{/in}>{$vo}</option>
  22 + {/foreach}
  23 + </select>
  24 +
  25 + </div>
  26 + </div>
  27 +
  28 + <!-- 商品规格属性 start -->
  29 + <div class="goods-spec-many form-group">
  30 + <!-- <label class="control-label col-xs-12 col-sm-2"></label>-->
  31 + <div class="goods-spec-box col-xs-12 col-sm-11" style="background-color: white;">
  32 + <!-- 规格属性 -->
  33 + <div class="spec-attr"></div>
  34 +
  35 + <!-- 添加规格:按钮 -->
  36 + <div class="spec-group-button">
  37 + <button type="button" class="btn-addSpecGroup btn btn-xs btn-success">添加规格</button>
  38 + </div>
  39 +
  40 + <!-- 添加规格:表单 -->
  41 + <div class="spec-group-add">
  42 + <div class="spec-group-add-item form-group">
  43 + <label class="control-label form-require">规格名 </label>
  44 + <input type="text" class="input-specName tpl-form-input"
  45 + placeholder="请输入规格名称">
  46 + </div>
  47 + <div class="spec-group-add-item form-group">
  48 + <label class="control-label form-require">规格值 </label>
  49 + <input type="text" class="input-specValue tpl-form-input"
  50 + placeholder="请输入规格值">
  51 + </div>
  52 + <div class="spec-group-add-item margin-top">
  53 + <button type="button" class="btn-addSpecName btn btn-xs btn-success"> 确定
  54 + </button>
  55 + <button type="button" class="btn-cancleAddSpecName btn btn-xs btn-default"> 取消
  56 + </button>
  57 + </div>
  58 + </div>
  59 + <!-- 商品多规格sku信息 -->
  60 + <div class="goods-sku scrollable-horizontal">
  61 + <!-- 分割线 -->
  62 + <div class="goods-spec-line"></div>
  63 + <!-- sku 批量设置 -->
  64 + <div class="spec-batch form-inline">
  65 + <div class="form-group">
  66 + <label class="control-label">批量设置</label>
  67 + </div>
  68 + <div class="form-group">
  69 + <input type="number" data-type="price" placeholder="报名费用">
  70 + </div>
  71 + <div class="form-group">
  72 + <button type="button" class="btn-specBatchBtn btn btn-sm btn-secondary
  73 + radius">确定
  74 + </button>
  75 + </div>
  76 + </div>
  77 + <!-- sku table -->
  78 + <table class="spec-sku-tabel table table-bordered table-centered margin-bottom-xs text-nowrap"></table>
  79 + </div>
  80 + </div>
  81 + </div>
  82 +
  83 + <div class="goods-spec-single">
  84 + <div class="form-group">
  85 + <label class="control-label col-xs-12 col-sm-2">报名费用:</label>
  86 + <div class="col-xs-12 col-sm-8">
  87 + <input id="c-price" data-rule="required" class="form-control form-control" name="spec[price]" type="number" value="{$row.spec.0.price|default=0}">
  88 + </div>
  89 + </div>
  90 + </div>
  91 + <!-- 商品规格属性 end -->
  92 +
  93 + <div class="form-group">
  94 + <label class="control-label col-xs-12 col-sm-2">{:__('House_ids')}:</label>
  95 + <div class="col-xs-12 col-sm-8">
  96 + <input id="c-house_ids" data-rule="required" data-source="house/index" data-multiple="true" class="form-control selectpage" name="row[house_ids]" type="text" value="{$row.house_ids|htmlentities}">
  97 + </div>
  98 + </div>
  99 + <div class="form-group">
  100 + <label class="control-label col-xs-12 col-sm-2">{:__('Start_time')}:</label>
  101 + <div class="col-xs-12 col-sm-8">
  102 + <input id="c-start_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[start_time]" type="text" value="{:$row.start_time?datetime($row.start_time):''}">
  103 + </div>
  104 + </div>
  105 + <div class="form-group">
  106 + <label class="control-label col-xs-12 col-sm-2">{:__('End_time')}:</label>
  107 + <div class="col-xs-12 col-sm-8">
  108 + <input id="c-end_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[end_time]" type="text" value="{:$row.end_time?datetime($row.end_time):''}">
  109 + </div>
  110 + </div>
  111 + <div class="form-group layer-footer">
  112 + <label class="control-label col-xs-12 col-sm-2"></label>
  113 + <div class="col-xs-12 col-sm-8">
  114 + <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
  115 + <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
  116 + </div>
  117 + </div>
  118 +</form>
  119 +{include file="house_activity/spec_many_template" /}
  120 +
  121 +<link rel="stylesheet" href="__CDN__/assets/addons/litestore/css/litestoregoods.css">
  122 +
  123 +<script type="text/javascript">
  124 + var from_specData = <?= $row['specData'] ?>;
  125 +</script>
  1 +<div class="panel panel-default panel-intro">
  2 + {:build_heading()}
  3 +
  4 + <div class="panel-body">
  5 + <div id="myTabContent" class="tab-content">
  6 + <div class="tab-pane fade active in" id="one">
  7 + <div class="widget-body no-padding">
  8 + <div id="toolbar" class="toolbar">
  9 + <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
  10 + <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('house_activity/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
  11 + <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('house_activity/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
  12 + <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('house_activity/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
  13 + <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('house_activity/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
  14 +
  15 + <div class="dropdown btn-group {:$auth->check('house_activity/multi')?'':'hide'}">
  16 + <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
  17 + <ul class="dropdown-menu text-left" role="menu">
  18 + <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
  19 + <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
  20 + </ul>
  21 + </div>
  22 +
  23 +
  24 + </div>
  25 + <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
  26 + data-operate-edit="{:$auth->check('house_activity/edit')}"
  27 + data-operate-del="{:$auth->check('house_activity/del')}"
  28 + width="100%">
  29 + </table>
  30 + </div>
  31 + </div>
  32 +
  33 + </div>
  34 + </div>
  35 +</div>
  1 +<!-- 商品规格属性模板 -->
  2 +<script id="tpl_spec_attr" type="text/template">
  3 + <% for(var j=0;j< spec_attr.length;j++){ %>
  4 + <div class="spec-group-item" data-index="<%=j%>" data-group-id="<%=spec_attr[j].group_id%>">
  5 + <div class="spec-group-name">
  6 + <span><%=spec_attr[j].group_name%></span>
  7 + <i class="spec-group-delete fa fa-trash icon-shanchu1" title="点击删除"></i>
  8 + </div>
  9 + <div class="spec-list am-cf">
  10 + <% for(var k=0;k<spec_attr[j].spec_items.length;k++){ %>
  11 + <div class="spec-item am-fl" data-item-index="<%=k%>">
  12 + <span><%=spec_attr[j].spec_items[k].spec_value%></span>
  13 + <i class="spec-item-delete fa fa-trash icon-shanchu1" title="点击删除"></i>
  14 + </div>
  15 + <% } %>
  16 + <div class="spec-item-add am-cf am-fl">
  17 + <input type="text" class="ipt-specItem am-fl am-field-valid">
  18 + <button type="button" class="btn-addSpecItem btn btn-xs btn-success am-fl">添加</button>
  19 + </div>
  20 + </div>
  21 + </div>
  22 + <% } %>
  23 +</script>
  24 +
  25 +<!-- 商品规格table模板 -->
  26 +<script id="tpl_spec_table" type="text/template">
  27 + <tbody>
  28 + <tr>
  29 + <% for(var i=0;i< spec_attr.length;i++){ %>
  30 + <th><%=spec_attr[i].group_name%></th>
  31 + <% } %>
  32 + <th>报名费用</th>
  33 + </tr>
  34 + <% for(var i=0;i<spec_list.length;i++){ %>
  35 + <tr data-index="<%=i%>" data-sku-id="<%=spec_list[i].spec_sku_id %>">
  36 + <% for(var k=0;k<spec_list[i].rows.length;k++){ %>
  37 + <td class="td-spec-value am-text-middle" rowspan="<%=spec_list[i].rows[k].rowspan%>">
  38 + <%=spec_list[i].rows[k].spec_value%>
  39 + </td>
  40 + <% } %>
  41 + <td>
  42 + <input type="number" name="price" data-rule="required" value="<%=spec_list[i].form.price%>" class="am-field-valid ipt-w80"
  43 + required>
  44 + </td>
  45 + </tr>
  46 + <% } %>
  47 + </tbody>
  48 +</script>
@@ -167,13 +167,12 @@ class House extends Api @@ -167,13 +167,12 @@ class House extends Api
167 167
168 $data = Db::name('house_board') 168 $data = Db::name('house_board')
169 ->field('id,house_id,title,content,look_num,createtime') 169 ->field('id,house_id,title,content,look_num,createtime')
170 - ->where('deletime','')  
171 ->where('id',$id) 170 ->where('id',$id)
172 ->find(); 171 ->find();
173 $data['createtime'] = date('Y-m-d',$data['createtime']); 172 $data['createtime'] = date('Y-m-d',$data['createtime']);
174 173
175 174
176 - $data['avatar'] = Db::name('house_board') 175 + $data['avatar'] = Db::name('house_board_detail')
177 ->alias('a') 176 ->alias('a')
178 ->join('user b','a.user_id = b.id') 177 ->join('user b','a.user_id = b.id')
179 ->where('a.house_board_id',$id) 178 ->where('a.house_board_id',$id)
@@ -251,19 +250,17 @@ class House extends Api @@ -251,19 +250,17 @@ class House extends Api
251 $qiniu = get_addon_config('qiniu')['cdnurl']; 250 $qiniu = get_addon_config('qiniu')['cdnurl'];
252 $user_id = $this->auth->id; 251 $user_id = $this->auth->id;
253 $area = $this->request->param('area'); 252 $area = $this->request->param('area');
254 - if(empty($area)){  
255 - $this->error('缺少必要参数');  
256 - }  
257 $keyword = $this->request->param('keyword'); 253 $keyword = $this->request->param('keyword');
  254 + $where = [];
  255 + if(!empty($area)){
  256 + $where['area'] = ['like',"%$area%"];
  257 + }
258 if(!empty($keyword)){ 258 if(!empty($keyword)){
259 $where['name'] = ['like',"%$keyword%"]; 259 $where['name'] = ['like',"%$keyword%"];
260 - }else{  
261 - $where = true;  
262 } 260 }
263 261
264 //查询该市区下的所有小区 262 //查询该市区下的所有小区
265 $data = Db::name('house') 263 $data = Db::name('house')
266 - ->where('area','like',"%$area%")  
267 ->where($where) 264 ->where($where)
268 ->field('id,name,area') 265 ->field('id,name,area')
269 ->order('createtime desc') 266 ->order('createtime desc')
@@ -148,7 +148,7 @@ class HouseBoard extends Api @@ -148,7 +148,7 @@ class HouseBoard extends Api
148 * @ApiMethod (POST) 148 * @ApiMethod (POST)
149 * 149 *
150 * @ApiHeaders (name=token, type=string, required=true, description="请求的Token") 150 * @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
151 - * @ApiParams (name="house_board_id", type=inter, required=true, description="社区id") 151 + * @ApiParams (name="house_id", type=inter, required=true, description="社区id")
152 * @ApiParams (name="page", type="inter", required=false, description="当前页(默认1)") 152 * @ApiParams (name="page", type="inter", required=false, description="当前页(默认1)")
153 * @ApiParams (name="pageNum", type="inter", required=false, description="每页显示数据个数(默认10)") 153 * @ApiParams (name="pageNum", type="inter", required=false, description="每页显示数据个数(默认10)")
154 * 154 *
@@ -174,7 +174,7 @@ class HouseBoard extends Api @@ -174,7 +174,7 @@ class HouseBoard extends Api
174 $page = $this->request->param('page', 1, 'intval'); 174 $page = $this->request->param('page', 1, 'intval');
175 $pageNum = $this->request->param('pageNum', 10, 'intval'); 175 $pageNum = $this->request->param('pageNum', 10, 'intval');
176 $user_id = $this->auth->id; 176 $user_id = $this->auth->id;
177 - $house_id = $this->request->param('house_board_id'); 177 + $house_id = $this->request->param('house_id');
178 if(empty($house_id)){ 178 if(empty($house_id)){
179 $this->error('社区id不能为空'); 179 $this->error('社区id不能为空');
180 } 180 }
@@ -375,4 +375,171 @@ class HouseBoard extends Api @@ -375,4 +375,171 @@ class HouseBoard extends Api
375 $this->success('success',$info); 375 $this->success('success',$info);
376 376
377 } 377 }
  378 +
  379 + /**
  380 + * @ApiTitle (社区公告-社区活动)
  381 + * @ApiSummary (社区公告-社区活动)
  382 + * @ApiMethod (POST)
  383 + *
  384 + * @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
  385 + * @ApiParams (name="house_id", type="inter", required=true, description="社区id")
  386 + *
  387 + * @ApiReturn({
  388 + "code": 1,
  389 + "msg": "success",
  390 + "time": "1598587213",
  391 + "data": [
  392 + {
  393 + "id": // 活动id
  394 + "title": // 活动标题
  395 + "spec_type": // 活动规格:0=无规格(免费),1=单规格,2=多规格
  396 + "content": // 活动描述
  397 + "activity_time": 活动日期
  398 + "price": // 报名费用
  399 + "status": { // 活动状态
  400 + "text": // 状态名称
  401 + "value": // 状态值 0=报名中,1=已报名,2=已到期
  402 + }
  403 + }
  404 + ]
  405 + })
  406 + */
  407 + public function activity()
  408 + {
  409 + $user_id = $this->auth->id;
  410 + $house_id = $this->request->param('house_id'); //社区id
  411 + empty($house_id) && $this->error('缺少必要参数');
  412 + $list = $this->getActivityList("find_in_set({$house_id},house_ids)");
  413 + $this->success('success',$list);
  414 + }
  415 +
  416 + /**
  417 + * @ApiTitle (社区公告-社区活动-详情)
  418 + * @ApiSummary (社区公告-社区活动-详情)
  419 + * @ApiMethod (POST)
  420 + *
  421 + * @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
  422 + * @ApiParams (name="house_activity_id", type="inter", required=true, description="社区活动id")
  423 + *
  424 + * @ApiReturn({
  425 + "code": 1,
  426 + "msg": "success",
  427 + "time": "1598587213",
  428 + "data": {
  429 + "id": // 活动id
  430 + "title": // 活动标题
  431 + "spec_type": // 活动规格:0=无规格(免费),1=单规格,2=多规格
  432 + "content": // 活动描述
  433 + "activity_time": 活动日期
  434 + "price": // 报名费用
  435 + "status": { // 活动状态
  436 + "text": // 状态名称
  437 + "value": // 状态值 0=报名中,1=已报名,2=已到期
  438 + }
  439 + }
  440 + })
  441 + */
  442 + public function activityInfo()
  443 + {
  444 + $user_id = $this->auth->id;
  445 + $house_activity_id = $this->request->param('house_activity_id'); //社区id
  446 + empty($house_activity_id) && $this->error('缺少必要参数');
  447 + $list = $this->getActivityList(['ha.id'=>$house_activity_id]);
  448 + $info = !empty($list) ? $list[0] : [];
  449 + $this->success('success',$info);
  450 + }
  451 +
  452 + /**
  453 + * 获取活动信息
  454 + */
  455 + private function getActivityList($where){
  456 + $list = Db::name('house_activity')
  457 + ->alias('ha')
  458 + ->join('house_join hj','hj.house_activity_id = ha.id','left')
  459 + ->where($where)
  460 + ->field('
  461 + ha.id,
  462 + ha.title,
  463 + ha.content,
  464 + ha.start_time,
  465 + ha.end_time,
  466 + ha.spec_type,
  467 + hj.pay_status
  468 + ')
  469 + ->order("ha.createtime desc")
  470 + ->select();
  471 + foreach ($list as $k => &$v) {
  472 + // 活动报名费用
  473 + $price = Db::name('house_activity_spec')->where('house_activity_id',$v['id'])->value('price');
  474 + $v['price'] = $price > 0 ? $price : 0;
  475 + // 活动日期
  476 + $v['activity_time'] = date('Y-m-d',$v['start_time']).'-'.date('Y-m-d',$v['end_time']);
  477 + // 活动状态
  478 + if($v['pay_status'] == '1'){
  479 + $status = ['text'=>'已报名','value'=>1];
  480 + }else{
  481 + $status = $v['end_time'] < time() ? ['text'=>'已到期','value'=>2] : ['text'=>'报名中','value'=>0];
  482 + }
  483 + $v['status'] = $status;
  484 + unset($v['start_time'],$v['end_time'],$v['pay_status']);
  485 + }
  486 + return $list;
  487 + }
  488 +
  489 + /**
  490 + * @ApiTitle (社区公告-社区活动-获取规格)
  491 + * @ApiSummary (社区公告-社区活动-获取规格)
  492 + * @ApiMethod (POST)
  493 + * @ApiParams (name="house_activity_id", type="integer", required=true, description="活动ID")
  494 + * @ApiReturnParams (name="code", type="integer", required=true, sample="0")
  495 + * @ApiReturnParams (name="msg", type="string", required=true, sample="返回成功")
  496 + * @ApiReturnParams (name="data", type="object", description="扩展数据返回")
  497 + * @ApiReturn ({
  498 + "code": 1,
  499 + "msg": "成功",
  500 + "time": "1598600665",
  501 + "data": {
  502 + "spec_attr": [
  503 + {
  504 + "group_id": 25,
  505 + "group_name": "颜色",
  506 + "spec_items": [
  507 + {
  508 + "item_id": 52,
  509 + "spec_value": "白色"
  510 + },
  511 + {
  512 + "item_id": 54,
  513 + "spec_value": "黑色"
  514 + }
  515 + ]
  516 + }
  517 + ],
  518 + "spec_list": {
  519 + "52_50": {
  520 + "spec_sku_id": "52_50",
  521 + "price": "12.00"
  522 + }
  523 + }
  524 + }
  525 + })
  526 + */
  527 + public function specData()
  528 + {
  529 + $house_activity_id = $this->request->param('house_activity_id');
  530 + $activity = \app\admin\model\HouseActivity::get($house_activity_id);
  531 + empty($activity) && $this->error('活动信息不存在');
  532 + // 规格信息
  533 + $spec_data = $activity['spec_type'] == '2' ? $activity->getManySpecData($activity['spec_rel'], $activity['spec']) : null;
  534 + // 规格价格信息
  535 + if($spec_data){
  536 + $spec_list = [];
  537 + foreach($spec_data['spec_list'] as $v){
  538 + $spec_list[$v['spec_sku_id']]['spec_sku_id'] = $v['spec_sku_id'];
  539 + $spec_list[$v['spec_sku_id']]['price'] = $v['form']['price'];
  540 + }
  541 + $spec_data['spec_list'] = $spec_list;
  542 + }
  543 + $this->success(__('成功'),$spec_data);
  544 + }
378 } 545 }
此 diff 太大无法显示。
  1 +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'backend/house_activity.spec'], function ($, undefined, Backend, Table, Form, spec) {
  2 +
  3 + var Controller = {
  4 + index: function () {
  5 + // 初始化表格参数配置
  6 + Table.api.init({
  7 + extend: {
  8 + index_url: 'house_activity/index' + location.search,
  9 + add_url: 'house_activity/add',
  10 + edit_url: 'house_activity/edit',
  11 + del_url: 'house_activity/del',
  12 + multi_url: 'house_activity/multi',
  13 + table: 'house_activity',
  14 + }
  15 + });
  16 +
  17 + var table = $("#table");
  18 +
  19 + // 初始化表格
  20 + table.bootstrapTable({
  21 + url: $.fn.bootstrapTable.defaults.extend.index_url,
  22 + pk: 'id',
  23 + sortName: 'id',
  24 + columns: [
  25 + [
  26 + {checkbox: true},
  27 + {field: 'id', title: __('Id')},
  28 + {field: 'title', title: __('Title')},
  29 + {field: 'spec_type', title: __('Spec_type'), searchList: {"0":__('Spec_type 0'),"1":__('Spec_type 1'),"2":__('Spec_type 2')}, formatter: Table.api.formatter.normal},
  30 + {field: 'start_time', title: __('Start_time'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
  31 + {field: 'end_time', title: __('End_time'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
  32 + {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
  33 + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
  34 + ]
  35 + ]
  36 + });
  37 +
  38 + // 为表格绑定事件
  39 + Table.api.bindevent(table);
  40 + },
  41 + add: function () {
  42 + setTimeout(function () {
  43 + $('select[name="row[spec_type]"]').trigger("change");
  44 + }, 100);
  45 + Form.api.bindevent($("form[role=form]"), function(data, ret){
  46 + Fast.api.close(data);
  47 + Toastr.success("活动提交成功");
  48 + }, function(data, ret){
  49 + Toastr.success("活动提交失败");
  50 + }, function(success, error){
  51 + //注意如果我们需要阻止表单,可以在此使用return false;即可
  52 + //如果我们处理完成需要再次提交表单则可以使用submit提交,如下
  53 + console.log(this);
  54 + var form = this;
  55 + if (form.size() === 0) {
  56 + Toastr.error("表单未初始化完成,无法提交");
  57 + return false;
  58 + }
  59 + var type = form.attr("method") ? form.attr("method").toUpperCase() : 'GET';
  60 + type = type && (type === 'GET' || type === 'POST') ? type : 'GET';
  61 + url = form.attr("action");
  62 + url = url ? url : location.href;
  63 + //修复当存在多选项元素时提交的BUG
  64 + var params = {};
  65 + var multipleList = $("[name$='[]']", form);
  66 + if (multipleList.size() > 0) {
  67 + var postFields = form.serializeArray().map(function (obj) {
  68 + return $(obj).prop("name");
  69 + });
  70 + $.each(multipleList, function (i, j) {
  71 + if (postFields.indexOf($(this).prop("name")) < 0) {
  72 + params[$(this).prop("name")] = '';
  73 + }
  74 + });
  75 + }
  76 + var dataParam = {spec_many: specMany.getData()};
  77 + console.log(dataParam);
  78 + Fast.api.ajax({
  79 + type: type,
  80 + url: url,
  81 + data: form.serialize() + (Object.keys(params).length > 0 ? '&' + $.param(params) : '') + (Object.keys(dataParam).length > 0 ? '&' + $.param(dataParam) : ''),
  82 + dataType: 'json',
  83 + complete: function (xhr) {
  84 + var token = xhr.getResponseHeader('__token__');
  85 + if (token) {
  86 + $("input[name='__token__']", form).val(token);
  87 + }
  88 + //关闭弹窗
  89 + var index = parent.Layer.getFrameIndex(window.name);
  90 + var callback = parent.$("#layui-layer" + index).data("callback");
  91 + parent.Layer.close(index);
  92 + //刷新列表
  93 + parent.$("#table").bootstrapTable('refresh');
  94 + }
  95 + }, function (data, ret) {
  96 + $('.form-group', form).removeClass('has-feedback has-success has-error');
  97 + if (data && typeof data === 'object') {
  98 + if (typeof data.token !== 'undefined') {
  99 + $("input[name='__token__']", form).val(data.token);
  100 + }
  101 + if (typeof data.callback !== 'undefined' && typeof data.callback === 'function') {
  102 + data.callback.call(form, data);
  103 + }
  104 + }
  105 + }, function (data, ret) {
  106 + if (data && typeof data === 'object' && typeof data.token !== 'undefined') {
  107 + $("input[name='__token__']", form).val(data.token);
  108 + }
  109 + });
  110 + return false;
  111 + });
  112 +
  113 + // 注册商品多规格组件
  114 + var specMany = new GoodsSpec({
  115 + container: '.goods-spec-many',
  116 + OutForm:Form
  117 + });
  118 +
  119 + // 切换单/多规格
  120 + $('select[name="row[spec_type]"').change(function (e) {
  121 + var $goodsSpecMany = $('.goods-spec-many')
  122 + , $goodsSpecSingle = $('.goods-spec-single');
  123 + if (e.currentTarget.value === '1') {
  124 + $goodsSpecMany.hide() && $goodsSpecSingle.show();
  125 + } else if (e.currentTarget.value === '2') {
  126 + $goodsSpecMany.show() && $goodsSpecSingle.hide();
  127 + } else {
  128 + $goodsSpecMany.hide() && $goodsSpecSingle.hide();
  129 + }
  130 + });
  131 + },
  132 + edit: function () {
  133 + setTimeout(function () {
  134 + $('select[name="row[spec_type]"]').trigger("change");
  135 + }, 100);
  136 + Form.api.bindevent($("form[role=form]"), function(data, ret){
  137 + //Fast.api.close(data);
  138 + Toastr.success("商品提交成功");
  139 + }, function(data, ret){
  140 + Toastr.success("商品提交失败");
  141 + }, function(success, error){
  142 + //注意如果我们需要阻止表单,可以在此使用return false;即可
  143 + //如果我们处理完成需要再次提交表单则可以使用submit提交,如下
  144 + console.log(this);
  145 + var form = this;
  146 + if (form.size() === 0) {
  147 + Toastr.error("表单未初始化完成,无法提交");
  148 + return false;
  149 + }
  150 + var type = form.attr("method") ? form.attr("method").toUpperCase() : 'GET';
  151 + type = type && (type === 'GET' || type === 'POST') ? type : 'GET';
  152 + url = form.attr("action");
  153 + url = url ? url : location.href;
  154 + //修复当存在多选项元素时提交的BUG
  155 + var params = {};
  156 + var multipleList = $("[name$='[]']", form);
  157 + if (multipleList.size() > 0) {
  158 + var postFields = form.serializeArray().map(function (obj) {
  159 + return $(obj).prop("name");
  160 + });
  161 + $.each(multipleList, function (i, j) {
  162 + if (postFields.indexOf($(this).prop("name")) < 0) {
  163 + params[$(this).prop("name")] = '';
  164 + }
  165 + });
  166 + }
  167 + var dataParam = {spec_many: specMany.getData()};
  168 + console.log(dataParam);
  169 + Fast.api.ajax({
  170 + type: type,
  171 + url: url,
  172 + data: form.serialize() + (Object.keys(params).length > 0 ? '&' + $.param(params) : '') + (Object.keys(dataParam).length > 0 ? '&' + $.param(dataParam) : ''),
  173 + dataType: 'json',
  174 + complete: function (xhr) {
  175 + var token = xhr.getResponseHeader('__token__');
  176 + if (token) {
  177 + $("input[name='__token__']", form).val(token);
  178 + }
  179 + //关闭弹窗
  180 + var index = parent.Layer.getFrameIndex(window.name);
  181 + var callback = parent.$("#layui-layer" + index).data("callback");
  182 + parent.Layer.close(index);
  183 + //刷新列表
  184 + parent.$("#table").bootstrapTable('refresh');
  185 + }
  186 + }, function (data, ret) {
  187 + $('.form-group', form).removeClass('has-feedback has-success has-error');
  188 + if (data && typeof data === 'object') {
  189 + if (typeof data.token !== 'undefined') {
  190 + $("input[name='__token__']", form).val(data.token);
  191 + }
  192 + if (typeof data.callback !== 'undefined' && typeof data.callback === 'function') {
  193 + data.callback.call(form, data);
  194 + }
  195 + }
  196 + }, function (data, ret) {
  197 + if (data && typeof data === 'object' && typeof data.token !== 'undefined') {
  198 + $("input[name='__token__']", form).val(data.token);
  199 + }
  200 + });
  201 + return false;
  202 + });
  203 + // 注册商品多规格组件
  204 + var specMany = new GoodsSpec({
  205 + container: '.goods-spec-many',
  206 + OutForm:Form
  207 + }, from_specData);
  208 +
  209 + // 切换单/多规格
  210 + $('select[name="row[spec_type]"').change(function (e) {
  211 + var $goodsSpecMany = $('.goods-spec-many')
  212 + , $goodsSpecSingle = $('.goods-spec-single');
  213 + if (e.currentTarget.value === '1') {
  214 + $goodsSpecMany.hide() && $goodsSpecSingle.show();
  215 + } else if (e.currentTarget.value === '2') {
  216 + $goodsSpecMany.show() && $goodsSpecSingle.hide();
  217 + } else {
  218 + $goodsSpecMany.hide() && $goodsSpecSingle.hide();
  219 + }
  220 + });
  221 + },
  222 + api: {
  223 + bindevent: function () {
  224 + Form.api.bindevent($("form[role=form]"));
  225 + }
  226 + }
  227 + };
  228 + return Controller;
  229 +});
  1 +(function () {
  2 + // 商品规格数据
  3 + var data = {
  4 + spec_attr: [],
  5 + spec_list: []
  6 + }
  7 +
  8 + // 配置信息
  9 + , setting = {
  10 + container: '.goods-spec-many',
  11 + OutForm:''
  12 + };
  13 +
  14 + function GoodsSpec(options, baseData) {
  15 + // 配置信息
  16 + setting = $.extend(true, {}, setting, options);
  17 + // 已存在的规格数据
  18 + typeof baseData !== 'undefined' && baseData !== null && (data = baseData);
  19 + // 初始化
  20 + this.initialize();
  21 + }
  22 +
  23 + GoodsSpec.prototype = {
  24 + /**
  25 + * 初始化
  26 + */
  27 + initialize: function () {
  28 + // 注册html容器
  29 + this.$container = $(setting.container);
  30 + this.$specAttr = this.$container.find('.spec-attr');
  31 + // 显示添加规则组表单事件
  32 + this.showAddSpecGroupEvent();
  33 + // 确认新增规则组事件
  34 + this.submitAddSpecGroupEvent();
  35 + // 取消新增规则组事件
  36 + this.cancelAddSpecGroupEvent();
  37 + // 注册添加规格元素事件
  38 + this.addSpecItemEvent();
  39 + // 注册删除规则组事件
  40 + this.deleteSpecGroupEvent();
  41 + // 注册删除规则元素事件
  42 + this.deleteSpecItemEvent();
  43 + // 注册删除单一sku事件
  44 + this.deleteSKUEvent();
  45 + // 注册批量设置sku事件
  46 + this.batchUpdateSku();
  47 + // 注册表格input数据修改事件
  48 + this.updateSpecInputEvent();
  49 + // 渲染已存在的sku信息
  50 + this.renderHtml();
  51 + },
  52 +
  53 + /**
  54 + * 显示添加规则组表单
  55 + */
  56 + showAddSpecGroupEvent: function () {
  57 + // 显示添加规则组表单
  58 + this.$container.on('click', '.btn-addSpecGroup', function () {
  59 + var $specGroupButton = $(this).parent()
  60 + , $specGroupAdd = $specGroupButton.next();
  61 + $specGroupButton.hide();
  62 + $specGroupAdd.show();
  63 + });
  64 + },
  65 +
  66 + /**
  67 + * 确认新增规则组
  68 + */
  69 + submitAddSpecGroupEvent: function () {
  70 + var _this = this;
  71 + // 确认添加
  72 + _this.$container.on('click', '.btn-addSpecName', function () {
  73 + var $specGroupAdd = $(this).parent().parent()
  74 + , $specGroupButton = $specGroupAdd.prev()
  75 + , $specNameInput = _this.$container.find('.input-specName')
  76 + , $specValueInput = _this.$container.find('.input-specValue')
  77 + , specValueInputValue = $specValueInput.val()
  78 + , specNameInputValue = $specNameInput.val();
  79 + if (specNameInputValue === '' || specValueInputValue === '') {
  80 + layer.msg('请填写规则名或规则值');
  81 + return false;
  82 + }
  83 + // 添加到数据库
  84 + var load = layer.load();
  85 + $.post('house_activity/addSpec', {
  86 + spec_name: specNameInputValue,
  87 + spec_value: specValueInputValue
  88 + }, function (result) {
  89 + console.log(result);
  90 + layer.close(load);
  91 + if (result.code !== 1) {
  92 + layer.msg(result.msg);
  93 + return false;
  94 + }
  95 + // 清空输入内容
  96 + $specNameInput.val('') && $specValueInput.val('');
  97 + // 记录规格数据
  98 + data.spec_attr.push({
  99 + group_id: result.data.spec_id,
  100 + group_name: specNameInputValue,
  101 + spec_items: [{
  102 + item_id: result.data.spec_value_id,
  103 + spec_value: specValueInputValue
  104 + }]
  105 + });
  106 + // 渲染规格属性html
  107 + _this.renderHtml();
  108 + // 隐藏添加规格组表单
  109 + $specGroupAdd.hide() && $specGroupButton.show();
  110 + });
  111 +
  112 + });
  113 + },
  114 +
  115 + /**
  116 + * 取消新增规格组
  117 + */
  118 + cancelAddSpecGroupEvent: function () {
  119 + this.$container.on('click', '.btn-cancleAddSpecName', function () {
  120 + var $specGroupAdd = $(this).parent().parent()
  121 + , $specGroupButton = $specGroupAdd.prev();
  122 + // 隐藏添加规格组表单
  123 + $specGroupAdd.hide() && $specGroupButton.show()
  124 + });
  125 + },
  126 +
  127 + /**
  128 + * 添加规则元素事件
  129 + */
  130 + addSpecItemEvent: function () {
  131 + var _this = this;
  132 + _this.$container.on('click', '.btn-addSpecItem', function () {
  133 + var $this = $(this)
  134 + , $iptSpecItem = $this.prev('.ipt-specItem')
  135 + , specItemInputValue = $iptSpecItem.val()
  136 + , $specItemAddContainer = $this.parent()
  137 + , $specGroup = $specItemAddContainer.parent().parent();
  138 + if (specItemInputValue === '') {
  139 + layer.msg('规格值不能为空');
  140 + return false;
  141 + }
  142 + // 添加到数据库
  143 + var load = layer.load();
  144 + $.post('house_activity/addSpecValue', {
  145 + spec_id: $specGroup.data('group-id'),
  146 + spec_value: specItemInputValue
  147 + }, function (result) {
  148 + layer.close(load);
  149 + if (result.code !== 1) {
  150 + layer.msg(result.msg);
  151 + return false;
  152 + }
  153 + // 记录规格数据
  154 + data.spec_attr[$specGroup.data('index')].spec_items.push({
  155 + item_id: result.data.spec_value_id,
  156 + spec_value: specItemInputValue
  157 + });
  158 + // 渲染规格属性html
  159 + _this.renderHtml();
  160 + });
  161 + });
  162 + },
  163 + /**
  164 + * 删除规则组事件
  165 + */
  166 + deleteSpecGroupEvent: function () {
  167 + var _this = this;
  168 + _this.$container.on('click', '.spec-group-delete', function () {
  169 + // 规则组索引
  170 + var index = $(this).parent().parent().attr('data-index');
  171 + layer.confirm('确定要删除该规则组吗?确认后不可恢复请谨慎操作', function (layerIndex) {
  172 + // 删除指定规则组
  173 + data.spec_attr.splice(index, 1);
  174 + // 重新渲染规格属性html
  175 + _this.renderHtml();
  176 + layer.close(layerIndex);
  177 + });
  178 + });
  179 + },
  180 +
  181 + /**
  182 + * 删除规则组事件
  183 + */
  184 + deleteSpecItemEvent: function () {
  185 + var _this = this;
  186 + _this.$container.on('click', '.spec-item-delete', function () {
  187 + var $item = $(this).parent()
  188 + , $specGroup = $item.parent().parent()
  189 + , groupIndex = $specGroup.attr('data-index')
  190 + , itemIndex = $item.attr('data-item-index');
  191 + layer.confirm('确定要删除该规则吗?确认后不可恢复请谨慎操作', function (layerIndex) {
  192 + // 删除指定规则组
  193 + data.spec_attr[groupIndex].spec_items.splice(itemIndex, 1);
  194 + // 重新渲染规格属性html
  195 + _this.renderHtml();
  196 + layer.close(layerIndex);
  197 + });
  198 + });
  199 + },
  200 +
  201 + /**
  202 + * 注册批量设置sku事件
  203 + */
  204 + batchUpdateSku: function () {
  205 + var _this = this,
  206 + $specBatch = _this.$container.find('.spec-batch');
  207 + $specBatch.on('click', '.btn-specBatchBtn', function () {
  208 + var formData = {};
  209 + $specBatch.find('input').each(function () {
  210 + var $this = $(this)
  211 + , formType = $this.data('type')
  212 + , value = $this.val();
  213 + if (typeof formType !== 'undefined' && formType !== '' && value !== '') {
  214 + formData[formType] = value;
  215 + }
  216 + });
  217 + if (!$.isEmptyObject(formData)) {
  218 + data.spec_list.forEach(function (item, index) {
  219 + data.spec_list[index].form = $.extend({}, data.spec_list[index].form, formData);
  220 + });
  221 + // 渲染商品规格table
  222 + _this.renderTabelHtml();
  223 + }
  224 + });
  225 + },
  226 +
  227 + /**
  228 + * 渲染多规格模块html
  229 + */
  230 + renderHtml: function () {
  231 + // 渲染商品规格元素
  232 + this.$specAttr.html(Template('tpl_spec_attr', data));
  233 + // 渲染商品规格table
  234 + this.renderTabelHtml();
  235 + },
  236 + deleteSKUEvent: function () {
  237 + var _this = this;
  238 + _this.$container.on('click', '.delsku-bt', function () {
  239 + // sku索引
  240 + var index = $(this).parent().parent().attr('data-index');
  241 + var sh_num = data.spec_list[index].form.stock_num;
  242 + var msgs = sh_num < 0? '确定要显示该sku吗?': '确定要隐藏该sku吗?';
  243 + layer.confirm(msgs, function (layerIndex) {
  244 + data.spec_list[index].form.stock_num = sh_num<0? 0 : -1;
  245 + console.log(data);
  246 + _this.$specAttr.html(Template('tpl_spec_attr', data));
  247 + var $specTabel = _this.$container.find('.spec-sku-tabel')
  248 + , $goodsSku = $specTabel.parent();
  249 + // 商品规格为空:隐藏sku容器
  250 + if (data.spec_attr.length === 0) {
  251 + $specTabel.empty();
  252 + $goodsSku.hide();
  253 + return false;
  254 + }
  255 + // 渲染table
  256 + $specTabel.html(Template('tpl_spec_table', data));
  257 + // 显示sku容器
  258 + $goodsSku.show();
  259 +
  260 + (setting.OutForm).events.plupload($(".spec-sku-tabel"));
  261 + (setting.OutForm).events.faselect($(".spec-sku-tabel"));
  262 + layer.close(layerIndex);
  263 + return;
  264 + //_this.renderHtml();
  265 + //layer.close(layerIndex);
  266 + });
  267 + });
  268 + },
  269 + /**
  270 + * 渲染表格html
  271 + */
  272 + renderTabelHtml: function () {
  273 + var $specTabel = this.$container.find('.spec-sku-tabel')
  274 + , $goodsSku = $specTabel.parent();
  275 + // 商品规格为空:隐藏sku容器
  276 + if (data.spec_attr.length === 0) {
  277 + $specTabel.empty();
  278 + $goodsSku.hide();
  279 + return false;
  280 + }
  281 + // 构建规格组合列表
  282 + this.buildSpeclist();
  283 + // 渲染table
  284 + $specTabel.html(Template('tpl_spec_table', data));
  285 + // 显示sku容器
  286 + $goodsSku.show();
  287 +
  288 + //绑定按钮;
  289 + (setting.OutForm).events.plupload($(".spec-sku-tabel"));
  290 + (setting.OutForm).events.faselect($(".spec-sku-tabel"));
  291 + },
  292 +
  293 + /**
  294 + * 构建规格组合列表
  295 + */
  296 + buildSpeclist: function () {
  297 + // 规格组合总数 (table行数)
  298 + var totalRow = 1;
  299 + for (var i = 0; i < data.spec_attr.length; i++) {
  300 + totalRow *= data.spec_attr[i].spec_items.length;
  301 + }
  302 + // 遍历tr 行
  303 + var spec_list = [];
  304 + for (i = 0; i < totalRow; i++) {
  305 + var rowData = [], rowCount = 1, specSkuIdAttr = [];
  306 + // 遍历td 列
  307 + for (var j = 0; j < data.spec_attr.length; j++) {
  308 + var skuValues = data.spec_attr[j].spec_items;
  309 + rowCount *= skuValues.length;
  310 + var anInterBankNum = (totalRow / rowCount)
  311 + , point = ((i / anInterBankNum) % skuValues.length);
  312 + if (0 === (i % anInterBankNum)) {
  313 + rowData.push({
  314 + rowspan: anInterBankNum,
  315 + item_id: skuValues[point].item_id,
  316 + spec_value: skuValues[point].spec_value
  317 + });
  318 + }
  319 + specSkuIdAttr.push(skuValues[parseInt(point.toString())].item_id);
  320 + }
  321 + spec_list.push({
  322 + spec_sku_id: specSkuIdAttr.join('_'),
  323 + rows: rowData,
  324 + form: {}
  325 + });
  326 + }
  327 + // 合并旧sku数据
  328 + if (data.spec_list.length > 0 && spec_list.length > 0) {
  329 + for (i = 0; i < spec_list.length; i++) {
  330 + var overlap = data.spec_list.filter(function (val) {
  331 + return val.spec_sku_id === spec_list[i].spec_sku_id;
  332 + });
  333 + if (overlap.length > 0) spec_list[i].form = overlap[0].form;
  334 + }
  335 + }
  336 + data.spec_list = spec_list;
  337 + },
  338 +
  339 + /**
  340 + * 输入规格信息自动同步更新spec_list
  341 + */
  342 + updateSpecInputEvent: function () {
  343 + var _this = this;
  344 + _this.$container.find('.spec-sku-tabel').on('propertychange change', 'input', function () {
  345 + var $this = $(this)
  346 + , dataType = $this.attr('name')
  347 + , specIndex = $this.parent().parent().data('index');
  348 + data.spec_list[specIndex].form[dataType] = $this.val();
  349 + });
  350 + },
  351 +
  352 + /**
  353 + * 获取当前data
  354 + */
  355 + getData: function () {
  356 + return data;
  357 + },
  358 +
  359 + /**
  360 + * sku列表是否为空
  361 + * @returns {boolean}
  362 + */
  363 + isEmptySkuList: function () {
  364 + return !data.spec_list.length;
  365 + }
  366 +
  367 + };
  368 +
  369 + window.GoodsSpec = GoodsSpec;
  370 +
  371 +})();
  372 +