校对
This commit is contained in:
503
application/api/controller/Proofread.php
Normal file
503
application/api/controller/Proofread.php
Normal file
@@ -0,0 +1,503 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\api\controller\Base;
|
||||
use think\Db;
|
||||
use app\common\OpenAi;
|
||||
use app\common\Article;
|
||||
/**
|
||||
* @title 文章校对记录
|
||||
* @description 对接OPENAI接口
|
||||
*/
|
||||
class Proofread extends Base
|
||||
{
|
||||
|
||||
/**
|
||||
* @title AI文章校对
|
||||
* @param article_id 文章ID
|
||||
*/
|
||||
public function proofRead($aParam = []){
|
||||
//获取参数
|
||||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||||
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//行号
|
||||
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
|
||||
//查询文章
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$oArticle = new Article;
|
||||
$aArticle = json_decode($oArticle->get($aWhere),true);
|
||||
$aArticle = empty($aArticle['data']) ? [] : $aArticle['data'];
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' ));
|
||||
}
|
||||
if($aArticle['state'] != 6){
|
||||
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
|
||||
}
|
||||
|
||||
//查询是否进行过校对
|
||||
$aProofReadWhere = ['article_id' => $iArticleId,'state' => 2];
|
||||
if(!empty($iAmId)){
|
||||
$aProofReadWhere['am_id'] = $iAmId;
|
||||
}
|
||||
$iCount = Db::name('article_proofread')->where($aProofReadWhere)->count();
|
||||
if(!empty($iCount)){
|
||||
return json_encode(array('status' => 5,'msg' => 'The article or paragraph has been proofread'));
|
||||
}
|
||||
|
||||
//查询文章内容
|
||||
$aWhere['type'] = 0;
|
||||
$aWhere['content'] = ['<>',''];
|
||||
$aWhere['state'] = 0;
|
||||
if(!empty($iAmId)){
|
||||
$aWhere['am_id'] = $iAmId;
|
||||
}
|
||||
$aArticleMain = Db::table('t_article_main')->field('am_id,content,type,is_h1,is_h2,is_h3,ami_id,amt_id')->where($aWhere)->select();
|
||||
if(empty($aArticleMain)){
|
||||
return json_encode(array('status' => 5,'msg' => 'The content of the article is empty'));
|
||||
}
|
||||
|
||||
//实例化公共方法
|
||||
$oHelperFunction = new \app\common\HelperFunction;
|
||||
$oProofReadService = new \app\common\ProofReadService;
|
||||
//数据处理
|
||||
$aH = $aTable = [];
|
||||
foreach ($aArticleMain as $key => $value) {
|
||||
if(empty($oHelperFunction->filterAllTags($value['content']))){
|
||||
continue;
|
||||
}
|
||||
$aResult = $oProofReadService->proofread($value['content']);
|
||||
if(empty($aResult)){
|
||||
continue;
|
||||
}
|
||||
$aResult['am_id'] = $value['am_id'];
|
||||
$aError[] = $aResult;
|
||||
}
|
||||
if(empty($aError)){
|
||||
return json_encode(array('status' => 1,'msg' => 'No errors found'));
|
||||
}
|
||||
//数据处理
|
||||
foreach ($aError as $key => $value) {
|
||||
if(empty($value['errors'])){
|
||||
continue;
|
||||
}
|
||||
foreach ($value['errors'] as $k => $val) {
|
||||
$val['am_id'] = $value['am_id'];
|
||||
$val['article_id'] = $iArticleId;
|
||||
$val['proof_before'] = empty($value['proof_before']) ? '' : $value['proof_before'];
|
||||
$val['proof_after'] = empty($value['proof_after']) ? '' : $value['proof_after'];
|
||||
$aData[] = $val;
|
||||
}
|
||||
}
|
||||
if(empty($aData)){
|
||||
return json_encode(array('status' => 1,'msg' => 'Data processing failed'));
|
||||
}
|
||||
//插入
|
||||
$result = Db::name('article_proofread')->insertAll($aData);
|
||||
if(!$result){
|
||||
return json_encode(array('status' => 6,'msg' => 'No errors found'));
|
||||
}
|
||||
|
||||
//查询参考文献
|
||||
$aWhere = ['state' => ['in',[0,2]],'article_id' => $iArticleId];
|
||||
return json_encode(['status' => 1,'msg' => 'success']);
|
||||
}
|
||||
/**
|
||||
* @title 获取每行校对记录
|
||||
* @param article_id 文章ID
|
||||
* @param am_id 行号
|
||||
* @param state 状态1已执行2未执行3删除
|
||||
*/
|
||||
public function get($aParam = []){
|
||||
|
||||
//获取参数
|
||||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||||
//参数验证-文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select a article']);
|
||||
}
|
||||
//行号
|
||||
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
|
||||
|
||||
//查询文章
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('journal_id,state')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(['status' => 3,'msg' => 'The query article does not exist']);
|
||||
}
|
||||
if($aArticle['state'] < 5 || $aArticle['state'] == 8){
|
||||
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
|
||||
}
|
||||
|
||||
//查询文章内容
|
||||
$aWhere['type'] = 0;
|
||||
$aWhere['content'] = ['<>',''];
|
||||
$aWhere['state'] = 0;
|
||||
if(!empty($iAmId)){
|
||||
$aWhere['am_id'] = $iAmId;
|
||||
}
|
||||
$aArticleMain = Db::name('article_main')->field('am_id,content')->where($aWhere)->select();
|
||||
if(empty($aArticleMain)){
|
||||
return json_encode(array('status' => 5,'msg' => 'The content of the article is empty'));
|
||||
}
|
||||
|
||||
//查询校对内容
|
||||
$aAmId = array_column($aArticleMain, 'am_id');
|
||||
$aWhere = ['am_id' => ['in',$aAmId]];
|
||||
$iState = empty($aParam['state']) ? 0 : $aParam['state'];
|
||||
if(!empty($iState)){
|
||||
$aWhere['state'] = ['in',$iState];
|
||||
}
|
||||
$aProofRead = Db::name('article_proofread')->field('id,am_id,verbatim_texts,revised_content,explanation,state')->where($aWhere)->select();
|
||||
if(empty($aProofRead)){
|
||||
return json_encode(array('status' => 1,'msg' => 'Proofreading record is empty'));
|
||||
}
|
||||
//数据处理
|
||||
$aData = [];
|
||||
$aArticleMain = array_column($aArticleMain, 'content','am_id');
|
||||
foreach ($aProofRead as $key => $value) {
|
||||
$aData[$value['am_id']][] = $value;
|
||||
}
|
||||
|
||||
// 存储每个文章的最新处理内容
|
||||
// 样式定义:标红+下划线
|
||||
// 定义标红+下划线样式
|
||||
// $style = 'color: red; text-decoration: underline;';
|
||||
|
||||
// // 存储最终处理后的文章内容
|
||||
// $aFinalContent = [];
|
||||
|
||||
// // 外层循环:遍历每个文章的错误分组($key为am_id)
|
||||
// foreach ($aData as $amId => $errors) {
|
||||
// // 获取原始文章内容(若不存在则跳过)
|
||||
// $sContent = empty($aArticleMain[$amId]) ? '' : $aArticleMain[$amId];
|
||||
// if (empty($sContent)) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // 初始化当前内容为原始内容,后续替换将基于此更新
|
||||
// $currentContent = $sContent;
|
||||
|
||||
// // 内层循环:处理当前文章的每条错误记录
|
||||
// foreach ($errors as $val) {
|
||||
// // 只处理状态为2的错误
|
||||
// if ($val['state'] != 2) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // 获取错误内容(待标红的文本)
|
||||
// $verbatim_texts = trim($val['verbatim_texts'] ?? '');
|
||||
// if (empty($verbatim_texts)) {
|
||||
// continue; // 空错误内容跳过
|
||||
// }
|
||||
|
||||
// // 构建带样式的替换内容(用span标签包裹,添加CSS样式)
|
||||
// $revised_content = '<span style="' . $style . '">' . htmlspecialchars($verbatim_texts, ENT_QUOTES, 'UTF-8') . '</span>';
|
||||
|
||||
// // 定位错误内容在当前内容中的位置(支持多字节字符,如中文)
|
||||
// $startPos = mb_strpos($currentContent, $verbatim_texts, 0, 'UTF-8');
|
||||
// if ($startPos === false) {
|
||||
// continue; // 未找到错误内容,跳过
|
||||
// }
|
||||
|
||||
// // 计算错误内容的字节长度(用于替换)
|
||||
// $byteLength = strlen($verbatim_texts);
|
||||
// // 转换字符起始位置为字节位置(适配substr_replace的字节处理)
|
||||
// $byteStart = 0;
|
||||
// for ($i = 0; $i < $startPos; $i++) {
|
||||
// $byteStart += strlen(mb_substr($currentContent, $i, 1, 'UTF-8'));
|
||||
// }
|
||||
|
||||
// // 执行替换:用带样式的内容替换原始错误内容
|
||||
// $currentContent = substr_replace($currentContent, $revised_content, $byteStart, $byteLength);
|
||||
// }
|
||||
|
||||
// // 保存当前文章处理后的最终内容
|
||||
// $aFinalContent[$amId] = $currentContent;
|
||||
// }
|
||||
return json_encode(['status' => 1,'msg' => 'success','data' => ['record' => $aData]]);//,'record_style' => $aFinalContent
|
||||
}
|
||||
|
||||
/**
|
||||
* @title 更新状态
|
||||
* @param article_id 文章ID
|
||||
* @param am_id 行号
|
||||
* @param record_id 记录ID
|
||||
* @param state 1已执行2未执行3撤销
|
||||
*/
|
||||
public function change(){
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
//参数验证-文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select a article']);
|
||||
}
|
||||
//参数验证-行号ID
|
||||
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
|
||||
if(empty($iAmId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select the proofreading content']);
|
||||
}
|
||||
//主键ID
|
||||
$iId = empty($aParam['record_id']) ? 0 : $aParam['record_id'];
|
||||
if(empty($iId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select the review record']);
|
||||
}
|
||||
//状态
|
||||
$iState = empty($aParam['state']) ? 0 : intval($aParam['state']);
|
||||
if(!in_array($iState, [1,2,3])){
|
||||
return json_encode(['status' => 2,'msg' => 'Illegal review status']);
|
||||
}
|
||||
|
||||
//修改内容
|
||||
$sContent = empty($aParam['content']) ? '' : $aParam['content'];
|
||||
if(in_array($iState, [1,2]) && empty($sContent)){
|
||||
return json_encode(['status' => 2,'msg' => 'The operation content cannot be empty']);
|
||||
}
|
||||
|
||||
//判断校对记录
|
||||
$aWhere = ['am_id' => $iAmId,'article_id' => $iArticleId,'id' => $iId];
|
||||
$aProofRead = Db::name('article_proofread')->where($aWhere)->find();
|
||||
|
||||
if(empty($aProofRead)){
|
||||
return json_encode(['status' => 3,'msg' => 'Proofreading record is empty']);
|
||||
}
|
||||
if($aProofRead['state'] == 3){
|
||||
return json_encode(['status' => 4,'msg' => 'Record deleted']);
|
||||
}
|
||||
|
||||
//状态一致
|
||||
if($iState == $aProofRead['state']){
|
||||
return json_encode(['status' => 5,'msg' => 'Consistent status without modification']);
|
||||
}
|
||||
|
||||
//判断记录是否执行
|
||||
if($iState == 3 && $aProofRead['state'] == 1){
|
||||
return json_encode(['status' => 6,'msg' => 'This record has been executed and cannot be deleted']);
|
||||
}
|
||||
$sData = $sUpdateContent = '';
|
||||
if($iState == 1){ //执行替换操作
|
||||
$aProofRead['content'] = $sContent;
|
||||
$aResult = $this->replaceError($aProofRead);
|
||||
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
|
||||
if($iStatus != 1){
|
||||
return json_encode($aResult);
|
||||
}
|
||||
//获取内容
|
||||
$sUpdateContent = empty($aResult['data']) ? '' : $aResult['data'];
|
||||
if(empty($sUpdateContent)){
|
||||
return json_encode(['status' => 5,'msg' => 'Content processing failed']);
|
||||
}
|
||||
// $aDealData = json_decode($this->get(['am_id' => $iAmId,'article_id' => $iArticleId]),true);
|
||||
// $aDealData = empty($aDealData['data']) ? [] : $aDealData['data'];
|
||||
// $sData = empty($aDealData['record_style']) ? '' : $aDealData['record_style'];
|
||||
$sData = $sUpdateContent;
|
||||
}
|
||||
if($iState == 2){ //执行替换操作
|
||||
$aProofRead['content'] = $sContent;
|
||||
$aResult = $this->removeReplaceError($aProofRead);
|
||||
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
|
||||
if($iStatus != 1){
|
||||
return json_encode($aResult);
|
||||
}
|
||||
//获取内容
|
||||
$sUpdateContent = empty($aResult['data']) ? '' : $aResult['data'];
|
||||
if(empty($sUpdateContent)){
|
||||
return json_encode(['status' => 5,'msg' => 'Content processing failed']);
|
||||
}
|
||||
// $aDealData = json_decode($this->get(['am_id' => $iAmId,'article_id' => $iArticleId]),true);
|
||||
// $aDealData = empty($aDealData['data']) ? [] : $aDealData['data'];
|
||||
// $sData = empty($aDealData['record_style']) ? '' : $aDealData['record_style'];
|
||||
$sData = $sUpdateContent;
|
||||
}
|
||||
Db::startTrans();
|
||||
//更新原始内容
|
||||
if(!empty($sUpdateContent)){
|
||||
$aWhere = ['am_id' => $iAmId,'state' => 0,'type' => 0];
|
||||
$aUpdate = ['content' => $sUpdateContent];
|
||||
$result_main = Db::name('article_main')->where($aWhere)->limit(1)->update($aUpdate);
|
||||
}
|
||||
//判断更新参数
|
||||
$aUpdate = ['state' => $iState,'update_time' => time()];
|
||||
//数据库更新
|
||||
$aWhere = ['id' => $iId];
|
||||
$result_proofread= Db::name('article_proofread')->where($aWhere)->limit(1)->update($aUpdate);
|
||||
if(!$result_proofread || !$result_main){
|
||||
return json_encode(['status' => 7,'msg' => "Update failed"]);
|
||||
}
|
||||
Db::commit();
|
||||
//返回结果
|
||||
return json_encode(['status' => 1,'msg' => "Update successful",'data' => $sData]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换错误
|
||||
* @param string $errorId 错误ID
|
||||
* @return bool 替换是否成功
|
||||
*/
|
||||
private function replaceError($aParam = [])
|
||||
{
|
||||
if(empty($aParam)){
|
||||
return ['status' => 2,'msg' => 'The content is empty'];
|
||||
}
|
||||
//原始内容
|
||||
$sContent = empty($aParam['content']) ? '' : $aParam['content'];
|
||||
//错误内容
|
||||
$verbatim_texts = empty($aParam['verbatim_texts']) ? '' : $aParam['verbatim_texts'];
|
||||
//正确内容
|
||||
$revised_content = empty($aParam['revised_content']) ? 0 : $aParam['revised_content'];
|
||||
|
||||
$iLength = strlen($verbatim_texts);
|
||||
//内容替换
|
||||
$sContent = $this->replaceByLengthAndKeyword($sContent,$iLength,$verbatim_texts,$revised_content);
|
||||
|
||||
return ['status' => 1,'msg' => 'success','data' => $sContent];
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回替换错误
|
||||
* @param string $errorId 错误ID
|
||||
* @return bool 替换是否成功
|
||||
*/
|
||||
private function removeReplaceError($aParam = [])
|
||||
{
|
||||
if(empty($aParam)){
|
||||
return ['status' => 2,'msg' => 'The content is empty'];
|
||||
}
|
||||
//原始内容
|
||||
$sContent = empty($aParam['content']) ? '' : $aParam['content'];
|
||||
//错误内容
|
||||
$verbatim_texts = empty($aParam['verbatim_texts']) ? '' : $aParam['verbatim_texts'];
|
||||
//正确内容
|
||||
$revised_content = empty($aParam['revised_content']) ? '' : $aParam['revised_content'];
|
||||
|
||||
$iLength = strlen($revised_content);
|
||||
//内容替换
|
||||
$sContent = $this->replaceByLengthAndKeyword($sContent,$iLength,$revised_content,$verbatim_texts);
|
||||
|
||||
return ['status' => 1,'msg' => 'success','data' => $sContent];
|
||||
}
|
||||
/**
|
||||
* 按长度和内容特征快速定位并替换字符串
|
||||
* @param string $str 原始字符串
|
||||
* @param int $targetLength 目标子串长度(字节数,多字节字符需注意)
|
||||
* @param string $keyword 筛选关键词(目标子串需包含此关键词)
|
||||
* @param string $replace 替换内容
|
||||
* @param string $encoding 字符编码(默认UTF-8,处理多字节字符)
|
||||
* @return string 替换后的字符串
|
||||
*/
|
||||
private function replaceByLengthAndKeyword($str, $targetLength, $keyword, $replace, $encoding = 'UTF-8') {
|
||||
// 边界校验:避免无效参数导致错误
|
||||
if (empty($str) || $targetLength <= 0 || empty($keyword)) {
|
||||
return '';
|
||||
}
|
||||
$strLength = strlen($str);
|
||||
if ($targetLength > $strLength) {
|
||||
return ''; // 目标长度超过原始字符串,无需处理
|
||||
}
|
||||
|
||||
$result = $str;
|
||||
$targets = []; // 存储目标子串的起始位置(字节索引)
|
||||
|
||||
// 遍历字符串,提取符合长度且包含关键词的子串位置(一次遍历完成筛选,减少内存占用)
|
||||
for ($i = 0; $i <= $strLength - $targetLength; $i++) {
|
||||
// 截取目标长度的子串
|
||||
$substr = substr($result, $i, $targetLength);
|
||||
// 检查子串是否包含关键词(多字节安全)
|
||||
if (mb_strpos($substr, $keyword, 0, $encoding) !== false) {
|
||||
$targets[] = $i; // 只存起始位置,减少内存占用
|
||||
}
|
||||
}
|
||||
|
||||
// 若没有匹配目标,直接返回原始字符串
|
||||
if (empty($targets)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// 从后往前替换(避免前面替换导致后面位置偏移)
|
||||
// 倒序遍历数组,无需额外排序,效率更高
|
||||
for ($k = count($targets) - 1; $k >= 0; $k--) {
|
||||
$start = $targets[$k];
|
||||
// 二次校验:替换前确认子串仍符合条件(防止重复替换或中间修改导致的偏差)
|
||||
$currentSubstr = substr($result, $start, $targetLength);
|
||||
if (mb_strpos($currentSubstr, $keyword, 0, $encoding) !== false) {
|
||||
$result = substr_replace($result, $replace, $start, $targetLength);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @title 更新内容
|
||||
* @param article_id 文章ID
|
||||
* @param am_id 行号
|
||||
* @param record_id 记录ID
|
||||
* @param revised_content 修改内容
|
||||
* @param is_update_all 是否更新所有1是2否
|
||||
*/
|
||||
public function modify(){
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
//参数验证-文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select a article']);
|
||||
}
|
||||
//参数验证-行号ID
|
||||
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
|
||||
if(empty($iAmId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select the proofreading content']);
|
||||
}
|
||||
//主键ID
|
||||
$iId = empty($aParam['record_id']) ? 0 : $aParam['record_id'];
|
||||
if(empty($iId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select the review record']);
|
||||
}
|
||||
//修改后的内容
|
||||
$sRevisedContent = empty($aParam['revised_content']) ? '' : $aParam['revised_content'];
|
||||
if(empty($sRevisedContent)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please enter the modification content']);
|
||||
}
|
||||
//解释说明
|
||||
$sExplanation = empty($aParam['explanation']) ? '' : $aParam['explanation'];
|
||||
//是否更新所有1是2否
|
||||
$iIsUpdateAll = empty($aParam['is_update_all']) ? 2 : $aParam['is_update_all'];
|
||||
|
||||
//查询内容是否存在
|
||||
$aWhere = ['am_id' => $iAmId,'article_id' => $iArticleId,'id' => $iId];
|
||||
$aProofRead = Db::name('article_proofread')->field('verbatim_texts,revised_content,explanation,state')->where($aWhere)->find();
|
||||
if(empty($aProofRead)){
|
||||
return json_encode(['status' => 3,'msg' => 'Proofreading record is empty']);
|
||||
}
|
||||
if($aProofRead['state'] == 3){
|
||||
return json_encode(['status' => 4,'msg' => 'Record deleted']);
|
||||
}
|
||||
if($aProofRead['state'] == 1){
|
||||
return json_encode(['status' => 5,'msg' => 'Record executed']);
|
||||
}
|
||||
//判断更新参数
|
||||
$aUpdate = ['revised_content' => $sRevisedContent,'update_time' => time()];
|
||||
if(!empty($sExplanation)){
|
||||
$aUpdate['explanation'] = $sExplanation;
|
||||
}
|
||||
//数据库更新
|
||||
$aWhere = ['id' => $iId];
|
||||
if($iIsUpdateAll == 1){
|
||||
if(empty($aProofRead['verbatim_texts']) || empty($aProofRead['revised_content'])){
|
||||
return json_encode(['status' => 6,'msg' => 'AI proofreading content is empty']);
|
||||
}
|
||||
$aWhere = ['verbatim_texts' => $aProofRead['verbatim_texts'],'revised_content' => $aProofRead['revised_content'],'article_id' => $iArticleId,'state' => 2];
|
||||
}
|
||||
$result = Db::name('article_proofread')->where($aWhere)->update($aUpdate);
|
||||
if(!$result){
|
||||
return json_encode(['status' => 7,'msg' => "Update failed"]);
|
||||
}
|
||||
//返回结果
|
||||
return json_encode(['status' => 1,'msg' => "Update successful"]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user