Рубрики
Uncategorized

Как сделать Небольшую программную функцию Красного пакета пароля

Автор оригинала: David Wong.

В процессе поддержки бэкенда для небольших программ есть много интересных функций. Некоторые из них основаны на вашей практической способности к распространению идей и решению проблем. Вот отрывок, чтобы записать это. Будет лучше, если вы сможете помочь другим.

Давайте начнем с нескольких чертежей, чтобы увидеть общие функции:

Возможно, и так.

На рисунках мы видим, что задействованы несколько более сложные функции: распознавание речи, алгоритм выделения красных пакетов, алгоритм периферийных красных пакетов и так далее. Все остальное-простые грубые операции. Я использовал КОДИРОВАНИЕ + ТЕСТИРОВАНИЕ почти неделю. Вот несколько идей и методов для реализации каждой точки функции.

Распознавание речи:

Сценарий применения этой функции таков: Пользователь устанавливает красный пакет китайского пароля, пользователь B получает красный пакет, который должен озвучить пароль, и, если он идеально совпадает, получает определенную долю красного пакета.

Запись, естественно, является собственным интерфейсом, предоставляемым виджетом вызова, но загвоздка здесь в том, что формат записи Weixin таков. шелк. Метод онлайн – поиска заключается в конвертации. формат silk в формат WAV или MP3, а затем вызовите интерфейс платформ облачных сервисов для реализации функции распознавания речи.

Библиотека, предоставленная https://github.com/kn007/silk… используется для преобразования в формат WAV, а затем результаты распознавания голоса распознаются с помощью открытого интерфейса распознавания речи Baidu https://ai.baidu.com/tech/spe….

Этапы реализации бизнеса заключаются в следующем:

1. Достижение функции записи в интерфейсе 2. интерфейс загрузки для загрузки. голосовые файлы silk и сохраните их в библиотеке 3. Запустите задачу распознавания речи и успешно верните ее на внешний интерфейс (асинхронно) 4. Результаты опроса внешнего интерфейса.

Поскольку загрузка для распознавания и возврат результатов являются трудоемкими операциями, процесс идентификации лучше всего выполнять асинхронно. (Шаг 3)

Загрузить код детали голосового интерфейса:

//... Business Code Sketch ___________
Voice = $this - > getCreatedVoiceByBody (); // Upload and put into the library
This - > identifyVoice ($voice); // Triggered Speech Recognition Task
 
// ...
 
public function identifyVoice($voice)
{
    WorkerUtil::sendTaskByRouteAndParams('task/detectvoice', ['voiceid' => $voice->id, 'type' =>'redpack']);
}

Как видно выше, идентификатор записи и тип, содержащий адрес голосового файла, отправляются в службу внутренних задач.

Служба внутренних задач обрабатывается следующим образом:

class DetectVoice extends Action
{
    public function run($voiceid, $type = 'redpack')
    {
        if ($type == 'redpack') {
            $voice = Voices::findOne($voiceid);
            $url = $voice->voice;
            $saveName = '/runtime/redpack-'.$voiceid.'.silk';
            $convertName = '/runtime/redpack-'.$voiceid.'.wav';
        }
        $this->saveToLocalByRemoteVoiceUrlAndLocalFileName($url, $saveName);
        $cfg = [
            'appKey' => 'xxx',
            'appSecret' => 'xxx',
            'appId' => 'xxx',
        ];
        $util = new BaiduVoiceUtil($cfg);
        $code = exec("bash /www/silk-v3-decoder/converter.sh {$saveName} wav");
        if ($code == 0) {
            $result = $util->asr($convertName);
            if ($result['err_no'] == 0) {
                $voicesResult = json_encode($result['result'], JSON_UNESCAPED_UNICODE);
                $voice->result = $voicesResult;
                $voice->save();
                @unlink($saveName);
                @unlink($convertName);
            }
        }
    }
    ...
}

Логика обработки службы задач также понятна: получение voiceid, который необходимо распознать, поиск записей, загрузка голосовых файлов в локальный каталог TMP, вызов формата преобразования оболочки, вызов голосового интерфейса Baidu для распознавания преобразованного формата, а затем внесение результатов в базу данных.

Голосовая таблица структурирована следующим образом:

Таким образом, функция распознавания речи завершена.

Распределение красных пакетов

Сценарий применения: при создании красных конвертов

Как правило, есть два способа открыть красные конверты. Один из них заключается в выделении доли каждой акции при ее создании. Один из них заключается в динамическом выделении при его открытии, и первый из них принят здесь.

Подробные обсуждения можно найти по адресу https://www.zhihu.com/questio.

Честно говоря, прочитав этот ответ, я кое-что узнал, например, о реализации структуры пакета Weixin Red, распределении записи и так далее.

Поскольку наше приложение не имеет величины Weixin, нам, естественно, не нужно слишком много учитывать (нагрузку, параллелизм и т. Д.). Требования к продукту заключаются только в том, чтобы реализовать подобный Weixin метод распределения красных пакетов с точки зрения суммы денег. Поэтому, учитывая расширение и производительность, а также время, я напрямую использовал ответ Чэнь Пэна при распределении написания, но стал версией PHP. Он также соответствует redis в качестве хранилища общего доступа к пакетам red и возможной схеме одновременного решения проблем.

Сначала код (красный пакет/создать):

$redpack = $this->getCreatedRedPackByBody();
//... Business Logic Code Sketch ___________
// Setting Random Red Pack Share
$this->setRedPackOpenOdds($redpack);
 
protected function setRedPackOpenOdds($rp)
{
    $remainNum = $rp->num;
    $remainMoney = $rp->fee;
    $key = 'redpack:'.$rp->id;
    $redis = yii::$app->redis;
    while (!empty($remainNum)) {
        $money = $this->getRandomMoney($remainNum, $remainMoney);
        $redis->executeCommand('RPUSH', [$key, $money]);
    }
    $redis->executeCommand('expire', [$key, 259200]);
}
 
protected function getRandomMoney(&$remainNum, &$remainMoney)
{
    if ($remainNum == 1) {
        $remainNum--;
        return $remainMoney;
    }
    $randomNum = StringUtil::getRandom(6, 1);
    $seed = $randomNum / 1000000;
    $min = 1;
    $max = $remainMoney / $remainNum * 2;
    $money = $seed * $max;
    $money = $money <= $min ? $min : ceil($money);
    $remainNum--;
    $remainMoney -= $money;
    return $money;
}

Эта часть логики кода относительно проста, в основном:

После вычисления случайной суммы текущая сумма и количество копий записываются в список redis: id), а затем общая сумма и количество копий вычитаются до тех пор, пока они не будут вычтены.

Есть несколько примечательных моментов:

1. Метод генерации случайных чисел в исходном ответе использует java. math. БигДецимал. Но у PHP нет соответствующей функции, и его собственное случайное число не очень хорошо. Здесь мы используем наш собственный метод генерации случайных чисел (получаем шесть битов случайных чисел, затем делим их на биты и получаем случайные числа, аналогичные 0,608948) 2. На долю каждого красного конверта устанавливается однодневное время истечения срока действия, которое предназначено для реализации функции истечения срока действия красного конверта.

Результат в redis (в баллах):

распределение 10 юаней 15

Сто юаней выделяется на семь:

Пятьдесят юаней выделяется на 25:

Можно видеть, что случайное распределение в основном реализовано, и учитывается требование лучшей руки.

Использовать также просто, откройте красный пакет, чтобы получить общий доступ, используйте левую часть этого списка по одному из стека в строке.

Карта в красном конверте

Сценарий приложения: Просмотр Красных пакетов, Опубликованных вокруг

Ключом к этой реализации является алгоритм координат вокруг нее. Прежде всего, обязательным условием является получение координат широты и долготы при создании красных конвертов, что реализовано на переднем конце, мы можем только записывать.

Затем, когда вызывается интерфейс, передаются текущие широта и долгота пользователя. В соответствии с этой широтой и долготой рассчитайте диапазон периметра, а затем просмотрите записи в таблице в диапазоне периметра.

Код выглядит следующим образом:

/**
*
*@ Param double $lng longitude
*@ Param double $lat latitude
*@ Param integer $radius range
* @return array
*/
public function run($lng, $lat, $radius = 500)
{
    $coordinates = $this->getAroundByCoordinates($lng, $lat, $radius);
    $field = 'id,lat,lng';
    $data = (new Query())
            ->select($field)
            ->from('{{app_redpack}}')
            ->where(sprintf("`lat` BETWEEN %f AND %f AND `lng` BETWEEN %f AND %f AND `ishandle` = 1 AND `isexpire` = 0", $coordinates[0], $coordinates[2], $coordinates[1], $coordinates[3]))
            ->all();
    return ResponseUtil::getOutputArrayByCodeAndData(Api::SUCCESS, $data);
}
 
/**
* The circumference of the earth is 24901 miles.
* 24,901/360 degrees = 69.17 miles/degrees
*@ Param double $longitude
*@ Param double $latitude latitude
*@ Param integer $raidus range. Unit rice.
* @return array
*/
public function getAroundByCoordinates($longitude, $latitude, $raidus)
{
    (double) $degree = (24901 * 1609) / 360.0;
    (double) $dpmLat = 1 / $degree;
    (double) $radiusLat = $dpmLat * $raidus;
    (double) $minLat = $latitude - $radiusLat;
    (double) $maxLat = $latitude + $radiusLat;
    (double) $mpdLng = $degree * cos($latitude * (pi() / 180));
    (double) $dpmLng = 1 / $mpdLng;
    (double) $radiusLng = $dpmLng * $raidus;
    (double) $minLng = $longitude - $radiusLng;
    (double) $maxLng = $longitude + $radiusLng;
    return [$minLat, $minLng, $maxLat, $maxLng];
}

Ключом является getAroundByCoordinats, который вычисляет координаты верхнего левого, нижнего левого, верхнего правого и нижнего правого углов в соответствии с долготой и широтой ввода и размером диапазона. Если он отмечен на карте, то представляет собой прямоугольный диапазон.

Заинтересованные люди могут использовать http://lbs.qq.com/tool/getpoint/tool чтобы выбрать координату случайным образом и вычислить четыре угла в соответствии с приведенным выше методом, чтобы увидеть, точно ли это диапазон, указанный $raidus.

Важно отметить, что я не писал этот метод, но я действительно не помню, откуда он взялся. Я просто помню, как изменил реализацию Java на php . Приношу извинения автору оригинала.