obj = new dFormula(); $this->tbl = 'tcm_formula'; $this->formula_herb_tbl = 'tcm_formula_herb'; $this->herb_tbl = 'tcm_herb'; $this->collect_log_tbl = 'tcm_collect_log'; $this->formula_use_log_tbl = 'tcm_formula_use_log'; } public function getFormulaByCondition($condition, $page_num, $page_size) { $offset = ($page_num - 1) * $page_size; $where = "1=1"; if (!empty($condition)) { foreach ($condition as $key => $val) { if ($key == 'name') { $where .= " and s.{$key} like '%{$val}%'"; } else { $where .= " and s.{$key}={$val}"; } } } $sql = "select s.*,COALESCE(SUM(u.use_num), 0) AS use_num from {$this->tbl} as s left join {$this->formula_use_log_tbl} as u on s.id=u.formula_id where {$where} group by s.id order by use_num desc,s.sort desc,s.id desc limit {$offset},{$page_size}"; // echo "
";
//        print_r($sql);
//        exit;
        return $this->obj->execute($sql, true, true);
    }

    public function getAllFormulaList($condition, $page_num, $page_size) {
        $data = $this->getFormulaByCondition($condition, $page_num, $page_size);

        $formula_ids = array_column($data, 'id');

        $formula_arr = $this->getFormulaHerbData($formula_ids);

        foreach ($data as &$da) {
            if (isset($formula_arr[$da['id']])) {
                $da['formula'] = $formula_arr[$da['id']];
            }

            $original = array();
            if (!empty($da['original'])) {
                $original = json_decode($da['original'], true);
                $original = array_column($original, null, 'name');
            }
            unset($da['original']);

            foreach ($da['formula'] as &$v) {
                //药方克重为0 去查询原方
                if (isset($original[$v['name']]) && $v['num'] == 0) {
                    $v['num_str'] = $original[$v['name']]['num'];
                    //$v['desc'] = $original[$v['name']]['desc'];
                }
            }
        }

        return $data;
    }

    public function getAllFormulaTotal($condition) {
        $where = "1=1";
        if (!empty($condition)) {
            foreach ($condition as $key => $val) {
                if ($key == 'name') {
                    $where .= " and {$key} like '%{$val}%'";
                } else {
                    $where .= " and {$key}={$val}";
                }
            }
        }

        $sql = "select count(*) as count from $this->tbl where {$where}";
        $res = $this->obj->execute($sql, true, true);
        $num = $res[0]['count'];

        return $num;
    }

    public function createFormula($uid, $name, $source, $method, $herbs) {
        if (empty($name)) {
            $this->setError('药方名称不能为空');
            return false;
        }
        $herbs = json_decode($herbs, true);
        if (empty($herbs)) {
            $this->setError('药方药材不能为空');
            return false;
        }

        $data = array(
            'uid' => $uid,
            'name' => $name,
            'source' => $source,
        );

        //录入药方
        if ($uid == 0) {
            $org_herb = array();
            foreach ($herbs as $key => $herb) {
                $org_herb[$key] = array(
                    'name' => trim($herb['name']),
                    'num' => $this->convertToNum(trim($herb['name']), trim($herb['num'])),
                    //'desc' => trim($herb['desc']),
                );
            }

            //更新原方和用法
            $data['original'] = json_encode($org_herb, JSON_UNESCAPED_UNICODE);
            $data['method'] = $method;
        }

        //格式化药方对应的药材数据
        $formula_herb = $this->dealForulaHerb($uid, $herbs);
        if (!$formula_herb) {
            $this->writeLog('formula', 'insert_error_log', '添加药方,药材初始化失败|' . $uid . '|' . json_encode($herbs, JSON_UNESCAPED_UNICODE));
            return false;
        }

        $id = $this->insertFormula($data);
        if (!$id) {
            $this->writeLog('formula', 'insert_error_log', '添加药方失败|' . $uid . '|' . json_encode($data, JSON_UNESCAPED_UNICODE));
            return false;
        }

        //创建药方对应的药材
        foreach ($formula_herb as &$item) {
            $item['formula_id'] = $id;
        }
        $res = $this->insertFormulaHerb($formula_herb);
        if (!$res) {
            $this->writeLog('formula', 'insert_error_log', '添加药方,药材关联失败|' . $uid . '|' . json_encode($formula_herb, JSON_UNESCAPED_UNICODE));
            return false;
        }

        return $id;
    }

    public function saveFormula($uid, $id, $name, $source, $method, $herbs) {
        $herbs = json_decode($herbs, true);
        if (empty($herbs)) {
            $this->setError('药方药材不能为空');
            return false;
        }

        $formula = $this->getFormulaById($id);
        if (empty($formula)) {
            $this->setError('查询不到此药方');
            return false;
        }
        if ($formula['uid'] > 0 && $formula['uid'] != $uid) {
            $this->setError('这不是你的药方');
            return false;
        }

        $data = array();
        if (!empty($name)) $data['name'] = $name;
        if (!empty($source)) $data['source'] = $source;

        //录入药方
        if (!$uid) {
            $org_herb = array();
            foreach ($herbs as $key => $herb) {
                $org_herb[$key] = array(
                    'name' => trim($herb['name']),
                    'num' => $this->convertToNum(trim($herb['name']), trim($herb['num'])),
                    'desc' => trim($herb['desc']),
                );
            }

            //更新原方和用法
            $data['original'] = json_encode($org_herb, JSON_UNESCAPED_UNICODE);
            $data['method'] = $method;
        }

        //格式化药方对应的药材数据
        $formula_herb = $this->dealForulaHerb($uid, $herbs);
        if (!$formula_herb) {
            $this->writeLog('formula', 'update_error_log', '更新药方,药材初始化失败|' . $uid . '|' . json_encode($herbs, JSON_UNESCAPED_UNICODE));
            return false;
        }

        $res = $this->updateFormula($id, $data);
        if (!$res) {
            $this->writeLog('formula', 'update_error_log', '更新药方失败|' . $uid . '|' . json_encode($data, JSON_UNESCAPED_UNICODE));
            return false;
        }

        //批量更新药方药材关联关系
        foreach ($formula_herb as &$item) {
            $item['formula_id'] = $id;
        }
        $res = $this->mutiUpdateFormulaHerb($id, $formula_herb);
        if (!$res) {
            $this->writeLog('formula', 'update_error_log', '更新药方,药材关联失败|' . $uid . '|' . $id . '|' . json_encode($formula_herb, JSON_UNESCAPED_UNICODE));
            return false;
        }

        return true;
    }

    public function dealForulaHerb($uid, $herbs) {
        $formula_herb = array();

        $herb_ids = array();
        foreach ($herbs as $key => $item) {
            $name = trim($item['name']);
            $num = trim($item['num']);

            //自拟药方 克重不能为0
            if ($uid > 0 && $num == 0) {
                $this->setError("{$name}克重不能为零");
                return false;
            }

            $temp = array();

            //格式化药材id
            $herb = $this->getHerb($name);
            if ($herb) {
                $temp['herb_id'] = $herb['id'];
            } else {
                $temp['herb_id'] = $this->insertHerb(array('uid' => $uid, 'name' => $name));
                if (!$temp['herb_id']) {
                    $this->writeLog('formula', 'update_error_log', '添加药材失败|' . $uid . '|' . $name);
                    return false;
                }
            }

            if (isset($herb_ids[$temp['herb_id']])) {
                $this->setError("药材不能重复");
                return false;
            }
            $herb_ids[$temp['herb_id']] = $temp['herb_id'];

            //录药方上传的原方需要 单位换算
            $temp['num'] = $num;
            if ($uid == 0) {
                //目前先不换算 默认为0 使用原方用量
                $temp['num'] = 0;
                //$temp['num'] = $this->convertToNum($name, $num, false);
            }

            $temp['sort'] = $key;

            $formula_herb[] = $temp;
        }

        return $formula_herb;
    }

    public function convertToNum($herb_name, $str, $onlyconertNum = true, $from = '汉') {
        $num_list = $GLOBALS['num_list'];
        $num_list_arr = array_merge(array_keys($GLOBALS['num_list']['num']), array_keys($GLOBALS['num_list']['unit']));

        $weight_list = $GLOBALS['weight_list'][$from];
        $weight_list_arr = array_keys($GLOBALS['weight_list'][$from]);

        //计量数字
        $num_str = str_replace($weight_list_arr, '', $str);

        //计量单位
        $unit = str_replace($num_list_arr, '', $str);
        //计量单位
        $unit = str_replace($num_str, '', $unit);

        //非数字转换
        $num = $num_str;
        if (!is_numeric($num) && $num) {
            $num = 0;
            $temp = 0;

            $length = mb_strlen($num_str);
            for ($i = 0; $i < $length; $i++) {
                $char = mb_substr($num_str, $i, 1);
                if (isset($num_list['num'][$char])) {
                    $temp += $num_list['num'][$char];
                } elseif (isset($num_list['unit'][$char])) {
                    $temp = ($temp == 0 ? 1 : $temp) * $num_list['unit'][$char];
                    $num += $temp; // 将临时结果累加到最终结果中
                    $temp = 0; // 重置临时结果
                }
            }

            $num += $temp;
        }

        //只将汉字数字转换成number
        if ($onlyconertNum) {
            return $num . $unit;
        }

        //单位换算 直接换算成克数
        $weight = isset($weight_list[$unit]) ? $weight_list[$unit] : 0;
        if (isset($weight[$herb_name])) $weight = $weight[$herb_name];
        if (!is_numeric($weight)) $weight = 0;

        return $num * $weight;
    }

    public function insertFormula($info) {
        $id = $this->obj->insert($this->tbl, $info);
        if (empty($id)) {
            $this->setError('添加药材失败');
            return false;
        }

        return $id;
    }

    public function updateFormula($id, $info) {
        $res = $this->obj->update($this->tbl, $info, array('sql' => '`id`=?', 'vals' => array($id)));
        if (!$res) {
            $this->setError('更新失败');
            return false;
        }

        return true;
    }

    public function getHerbById($id) {
        return $this->obj->select($this->herb_tbl, array('sql' => '`id`=?', 'vals' => array($id)));
    }

    public function getHerb($name) {
        return $this->obj->select($this->herb_tbl, array('sql' => '`name`=?', 'vals' => array($name)));
    }

    public function insertHerb($info) {
        $herb_id = $this->obj->insert($this->herb_tbl, $info);
        if (!$herb_id) {
            $this->setError('添加药材失败');
            return false;
        }

        return $herb_id;
    }

    public function insertFormulaHerb($info) {
        $res = $this->obj->mutiInsert($this->formula_herb_tbl, $info);
        if (!$res) {
            $this->setError('添加药方药材失败');
            return false;
        }

        return true;
    }

    public function mutiUpdateFormulaHerb($id, $new_data) {
        $old_data = $this->getFormulaHerb($id);

        $old_num = count($old_data);
        $new_num = count($new_data);

        if ($old_num >= $new_num) {
            //需要删除药方对应的药材
            foreach ($old_data as $key => $value) {
                if (!isset($new_data[$key])) {
                    $res = $this->obj->delete($this->formula_herb_tbl, array('sql' => '`id`=?', 'vals' => array($value['id'])));
                    if (!$res) {
                        $this->setError('删除药方药材失败');
                        return false;
                    }
                }
                $res = $this->obj->update($this->formula_herb_tbl, $new_data[$key], array('sql' => '`id`=?', 'vals' => array($value['id'])));
                if (!$res) {
                    $this->setError('更新药方药材失败');
                    return false;
                }
            }
        } else {
            //需要增加药方对应的药材
            foreach ($new_data as $key => $value) {
                if (!isset($old_data[$key])) {
                    $res = $this->obj->insert($this->formula_herb_tbl, $value);
                    if (!$res) {
                        $this->setError('添加药方药材失败');
                        return false;
                    }
                }
                $res = $this->obj->update($this->formula_herb_tbl, $value, array('sql' => '`id`=?', 'vals' => array($old_data[$key]['id'])));
                if (!$res) {
                    $this->setError('更新药方药材失败');
                    return false;
                }
            }
        }

        return true;
    }

    public function getFormulaHerb($formula_id) {
        return $this->obj->selectAll($this->formula_herb_tbl, array('sql' => '`formula_id`=?', 'vals' => array($formula_id)), 'sort asc ');
    }

    public function getFormulasHerb($formula_ids) {
        $data = $this->obj->selectIn($this->formula_herb_tbl, array('formula_id' => $formula_ids));
        if (empty($data)) return array();
        return array_column($data, null, 'id');
    }

    public function getUserFormulaByUid($uid, $page_num, $page_size) {
        $offset = ($page_num - 1) * $page_size;
        $sql = "select s.id,s.uid,s.name,s.source,COALESCE(u.use_num, 0) AS use_num,s.sort,s.create_time from {$this->tbl} as s left join {$this->formula_use_log_tbl} as u on s.id=u.formula_id and u.uid={$uid} where s.uid={$uid} order by use_num desc,s.sort desc,s.id desc limit {$offset},{$page_size}";
        return $this->obj->execute($sql, true, true);
    }

    public function getUserFormulaList($uid, $page_num, $page_size) {
        $data = $this->getUserFormulaByUid($uid, $page_num, $page_size);

        $formula_ids = array_column($data, 'id');

        $formula_arr = $this->getFormulaHerbData($formula_ids);

        foreach ($data as &$da) {
            unset($da['original']);

            $da['create_time'] = date('Y-m-d', strtotime($da['create_time']));
            $da['formula'] = $formula_arr[$da['id']];
        }

        return $data;
    }

    public function getUserFormulaTotal($uid) {
        return $this->obj->count($this->tbl, array('sql' => '`uid`=?', 'vals' => array($uid)));
    }

    public function getUserFormulaInfo($id, $uid) {
        //药方信息
        $formula = $this->getFormulaById($id);
        if (empty($formula)) {
            $this->setError('查询不到此药方');
            return false;
        }
        //自拟药方药方归属
        if ($formula['uid'] != $uid) {
            $this->setError('这不是你的药方');
            return false;
        }

        $formulaHerb = array();

        $formula_arr = $this->getFormulaHerbData(array($formula['id']));
        foreach ($formula_arr as $ar) {
            foreach ($ar as &$v) {
                //药方克重为0 去查询原方
                if (isset($original[$v['name']])) {
                    $v['num_str'] = $original[$v['name']]['num'];
                    $v['desc'] = $original[$v['name']]['desc'];
                }
            }

            $formulaHerb = $ar;
        }

        $formula['formula'] = $formulaHerb;

        return $formula;
    }

    public function getFormulaByName($uid, $page_num, $page_size, $name) {
        $offset = ($page_num - 1) * $page_size;

        $where = $uid > 0 ? "s.uid in (0,{$uid})" : "s.uid=0";
        if ($name) {
            $where .= " and s.`name` like '%{$name}%'";
        }

        $sql = "select s.id,s.uid,s.name,s.source,s.original,s.method,COALESCE(u.use_num, 0) AS use_num,s.sort from {$this->tbl} as s left join {$this->formula_use_log_tbl} as u on s.id=u.formula_id and u.uid={$uid} where {$where} order by use_num desc,s.sort desc,s.id desc limit {$offset},{$page_size}";
        return $this->obj->execute($sql, true, true);
    }

    public function getSearchFormulaList($uid, $page_num, $page_size, $name = '') {
        $data = $this->getFormulaByName($uid, $page_num, $page_size, $name);

        $formula_ids = array_column($data, 'id');

        $formula_arr = $this->getFormulaHerbData($formula_ids);

        foreach ($data as &$da) {
            if (isset($formula_arr[$da['id']])) {
                $da['formula'] = $formula_arr[$da['id']];
            }

            $original = array();
            if (!empty($da['original'])) {
                $original = json_decode($da['original'], true);
                $original = array_column($original, null, 'name');
            }
            unset($da['original']);

            foreach ($da['formula'] as &$v) {
                //药方克重为0 去查询原方
                if (isset($original[$v['name']]) && $v['num'] == 0) {
                    $v['num_str'] = $original[$v['name']]['num'];
                    //$v['desc'] = $original[$v['name']]['desc'];
                }
            }
        }

        return $data;
    }

    public function getFormulaHerbData($formula_ids) {
        $formula_herbs = $this->getFormulasHerb($formula_ids);

        $herb_ids = array_column($formula_herbs, 'herb_id');
        $herbs = $this->getHerbs($herb_ids);
        $herb_arr = array_column($herbs, null, 'id');

        $formula_arr = array();
        foreach ($formula_herbs as $formula_herb) {
            $formula_arr[$formula_herb['formula_id']][] = array(
                'id' => $formula_herb['herb_id'],
                'name' => $herb_arr[$formula_herb['herb_id']]['name'],
                'num' => $formula_herb['num'],
                //'desc' => $formula_herb['desc'],
                'num_str' => $formula_herb['num'] . 'g',
            );
        }
        return $formula_arr;
    }

    public function getSearchFormulaTotal($uid, $name = '') {
        $where = $uid > 0 ? "uid in (0,{$uid})" : "uid=0";
        if ($name) {
            $where .= " and `name` like '%{$name}%'";
        }

        $sql = "select count(*) as count from $this->tbl where {$where}";
        $res = $this->obj->execute($sql, true, true);
        $num = $res[0]['count'];

        return $num;
    }

    public function getFormulaInfo($id, $uid) {
        //药方信息
        $formula = $this->getFormulaById($id);
        if (empty($formula)) {
            $this->setError('查询不到此药方');
            return false;
        }

        //自拟药方 判断药方归属
        if ($formula['uid'] > 0 && $formula['uid'] != $uid) {
            $this->setError('这不是你的药方');
            return false;
        }

        if (!empty($formula['original'])) {
            $original = json_decode($formula['original'], true);
            $original = array_column($original, null, 'name');
        }
        unset($formula['original']);

        $formulaHerb = array();

        $formula_arr = $this->getFormulaHerbData(array($formula['id']));
        foreach ($formula_arr as $ar) {
            foreach ($ar as &$v) {
                //药方克重为0 去查询原方
                if (isset($original[$v['name']])) {
                    $v['num_str'] = $original[$v['name']]['num'];
                    //$v['desc'] = $original[$v['name']]['desc'];
                }
            }

            $formulaHerb = $ar;
        }

        $formula['formula'] = $formulaHerb;

        return $formula;
    }

    public function getFormulaById($id) {
        return $this->obj->select($this->tbl, array('sql' => '`id`=?', 'vals' => array($id)));
    }

    public function getHerbs($ids) {
        return $this->obj->selectIn($this->herb_tbl, array('id' => $ids));
    }

    public function getFormulaByIds($ids) {
        return $this->obj->selectIn($this->tbl, array('id' => $ids));
    }

    public function updateFormulaUseLog($uid, $formula_id) {
        $res = $this->obj->increase($this->formula_use_log_tbl, array('sql' => '`uid`=? and `formula_id`=?', 'vals' => array($uid, $formula_id)), 'use_num');
        if (!$res) {
            $this->setError('添加药方药材失败');
            return false;
        }

        return true;
    }

    public function getCollectLog($page_num, $page_size) {
        $offset = ($page_num - 1) * $page_size;
        return $this->obj->selectAll($this->collect_log_tbl, array(), 'collect_time desc ', array($offset, $page_size));
    }

    public function getCollectLogTotal() {
        return $this->obj->count($this->collect_log_tbl);
    }

}