定价管理
This commit is contained in:
parent
65470ba161
commit
ea14003efc
85
app/Domains/Virtual/Http/Controllers/FetchController.php
Normal file
85
app/Domains/Virtual/Http/Controllers/FetchController.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace App\Domains\Virtual\Http\Controllers;
|
||||
|
||||
use App\Core\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Domains\Virtual\Repositories\CompanyRepository;
|
||||
use App\Domains\Virtual\Repositories\PackageRepository;
|
||||
|
||||
class FetchController extends Controller
|
||||
{
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* 构造函数,自动注入.
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用名称查找企业
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function companies(CompanyRepository $companyRepository)
|
||||
{
|
||||
return res($this->search($companyRepository), '', 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用名称查找套餐
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function packages(PackageRepository $packageRepository)
|
||||
{
|
||||
return res($this->search($packageRepository), '', 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一搜索归并
|
||||
*
|
||||
* @param [type] $repository
|
||||
* @param string $field
|
||||
* @param integer $limit
|
||||
* @param string $primaryKey
|
||||
* @return void
|
||||
*/
|
||||
protected function search($repository, $field = 'name', $primaryKey = 'id')
|
||||
{
|
||||
$search = $this->request->get('search');
|
||||
$limit = $this->request->get('limit', 0);
|
||||
|
||||
$results = $repository->select([$primaryKey, $field])->get();
|
||||
|
||||
if ($search) {
|
||||
$results = $results->filter(function ($item) use ($search, $field) {
|
||||
$result = true;
|
||||
|
||||
if (strpos($item[$field], $search) === false) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
if (strpos(pinyin_abbr($item[$field]), $search) === false) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
if (strpos(implode('', pinyin($item[$field])), $search) === false) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
});
|
||||
}
|
||||
|
||||
$sorted = $results->sortBy($field)->values()->all();
|
||||
|
||||
if ($limit) {
|
||||
return array_slice($sorted, 0, $limit);
|
||||
}
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
}
|
89
app/Domains/Virtual/Http/Controllers/ProductController.php
Normal file
89
app/Domains/Virtual/Http/Controllers/ProductController.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace App\Domains\Virtual\Http\Controllers;
|
||||
|
||||
use App\Dicts;
|
||||
use App\Core\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Exceptions\NotExistException;
|
||||
use App\Domains\Virtual\Services\ProductService;
|
||||
use App\Domains\Virtual\Repositories\ProductRepository;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
protected $request;
|
||||
protected $productService;
|
||||
|
||||
/**
|
||||
* 构造函数,自动注入.
|
||||
*/
|
||||
public function __construct(Request $request, ProductService $productService)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->productService = $productService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getCompanyProducts(Dicts $dicts)
|
||||
{
|
||||
$companyId = $this->request->get('company_id');
|
||||
$carrierOperator = $this->request->get('carrier_operator');
|
||||
|
||||
$products = $this->productService->getCompanyProducts($companyId, $carrierOperator);
|
||||
|
||||
$carrierOperators = $dicts->get('carrier_operator');
|
||||
|
||||
$products->map(function ($item) use ($carrierOperators) {
|
||||
$item->carrier_operator = $carrierOperators[$item['package']['carrier_operator']] ?? '未知';
|
||||
});
|
||||
|
||||
return res($products, '定价列表', 201);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$attributes = $this->request->all();
|
||||
|
||||
$account = $this->productService->store($attributes);
|
||||
|
||||
return res($account, '创建成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
$attributes = $this->request->all();
|
||||
$attributes['id'] = $id;
|
||||
|
||||
$account = $this->productService->store($attributes);
|
||||
|
||||
return res($account, '修改成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
$ids = $this->request->ids();
|
||||
|
||||
$this->productService->destroy($ids);
|
||||
|
||||
return res(true, '删除成功');
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ class PackageRepository extends Repository
|
||||
*/
|
||||
protected $fieldSearchable = [
|
||||
'id' => '=',
|
||||
'name' => 'like',
|
||||
'created_at' => 'like',
|
||||
];
|
||||
|
||||
|
@ -6,6 +6,10 @@ $router->group(['prefix' => 'virtual', 'as' => 'virtual', 'middleware' => ['admi
|
||||
// The controllers live in Domains/Virtual/Http/Controllers
|
||||
$router->get('/', ['as' => 'index', 'uses' => 'VirtualController@index']);
|
||||
|
||||
// 名称查找
|
||||
$router->get('/fetch/companies', ['as' => 'fetch.companies', 'uses' => 'FetchController@companies']);
|
||||
$router->get('/fetch/packages', ['as' => 'fetch.packages', 'uses' => 'FetchController@packages']);
|
||||
|
||||
// 企业管理
|
||||
$router->get('/companies/index', ['as' => 'companies.index', 'uses' => 'CompanyController@index']);
|
||||
$router->get('/companies/show/{id}', ['as' => 'companies.show', 'uses' => 'CompanyController@show']);
|
||||
@ -24,6 +28,12 @@ $router->group(['prefix' => 'virtual', 'as' => 'virtual', 'middleware' => ['admi
|
||||
// $router->post('/company/addresses/create', ['as' => 'company.addresses.create', 'uses' => 'CompanyAddressController@create']);
|
||||
// $router->post('/company/addresses/update/{id}', ['as' => 'company.addresses.update', 'uses' => 'CompanyAddressController@update']);
|
||||
// $router->post('/company/addresses/destroy', ['as' => 'company.addresses.destroy', 'uses' => 'CompanyAddressController@destroy']);
|
||||
|
||||
// 企业定价管理
|
||||
$router->get('/products/index', ['as' => 'products.index', 'uses' => 'ProductController@getCompanyProducts']);
|
||||
$router->post('/products/create', ['as' => 'products.create', 'uses' => 'ProductController@create']);
|
||||
$router->post('/products/update/{id}', ['as' => 'products.update', 'uses' => 'ProductController@update']);
|
||||
$router->post('/products/destroy', ['as' => 'products.destroy', 'uses' => 'ProductController@destroy']);
|
||||
|
||||
/**
|
||||
* 需要认证的接口
|
||||
|
@ -71,7 +71,7 @@ class CompanyAddressService extends Service
|
||||
|
||||
$rule = [
|
||||
'company_id' => ['required', 'exists:virtual_companies,id'],
|
||||
'contacts' => ['required', 'display_length:2,32'],
|
||||
'contacts' => ['required', 'between:2,32'],
|
||||
'mobile' => ['required', 'cn_phone'],
|
||||
'area' => ['required', 'max:255'],
|
||||
'address' => ['required', 'max:255'],
|
||||
@ -81,7 +81,7 @@ class CompanyAddressService extends Service
|
||||
'company_id.required' => '请输入企业ID',
|
||||
'company_id.exists' => '企业不存在或已删除',
|
||||
'contacts.required' => '联系人不能为空',
|
||||
'contacts.display_length' => '联系人名称长度不合法',
|
||||
'contacts.between' => '联系人名称长度不合法',
|
||||
'mobile.required' => '手机号不能为空',
|
||||
'mobile.cn_phone' => '手机号不合法',
|
||||
'area.required' => '请选择区域',
|
||||
|
@ -53,8 +53,8 @@ class CompanyService extends Service
|
||||
$attributes = array_only($attributes, array_merge(app(Company::class)->getFillable()));
|
||||
|
||||
$rule = [
|
||||
'name' => ['required', 'display_length:2,32', Rule::unique($this->companyRepository->getTable(), 'name')->ignore($attributes['id'])],
|
||||
'contacts' => ['string', 'display_length:2,32'],
|
||||
'name' => ['required', 'between:2,32', Rule::unique($this->companyRepository->getTable(), 'name')->ignore($attributes['id'])],
|
||||
'contacts' => ['string', 'between:2,32'],
|
||||
'mobile' => ['string', 'cn_phone'],
|
||||
'address' => ['string'],
|
||||
'extends' => ['array'],
|
||||
@ -62,9 +62,9 @@ class CompanyService extends Service
|
||||
|
||||
$message = [
|
||||
'name.required' => '请输入企业名称',
|
||||
'name.display_length' => '企业名称长度不合法',
|
||||
'name.between' => '企业名称长度不合法',
|
||||
'name.unique' => '企业名称已经被其他用户所使用',
|
||||
'contacts.display_length' => '联系人长度不合法',
|
||||
'contacts.between' => '联系人长度不合法',
|
||||
'mobile.cn_phone' => '手机号不合法',
|
||||
];
|
||||
|
||||
|
@ -4,7 +4,9 @@ namespace App\Domains\Virtual\Services;
|
||||
use App\Core\Service;
|
||||
use App\Models\Virtual\Product;
|
||||
use App\Exceptions\NotExistException;
|
||||
use App\Exceptions\NotAllowedException;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Domains\Virtual\Repositories\PackageRepository;
|
||||
use App\Domains\Virtual\Repositories\ProductRepository;
|
||||
|
||||
class ProductService extends Service
|
||||
@ -48,21 +50,48 @@ class ProductService extends Service
|
||||
*/
|
||||
public function store(array $attributes = [])
|
||||
{
|
||||
$attributes['base_price'] = floatval($attributes['base_price']) * 100;
|
||||
$attributes['renewal_price'] = floatval($attributes['renewal_price']) * 100;
|
||||
|
||||
$rule = [
|
||||
'name' => ['required', 'between:2,32'],
|
||||
'company_id' => ['required', 'exists:virtual_companies,id'],
|
||||
'package_id' => ['required'],
|
||||
'base_price' => [],
|
||||
'renewal_price' => [],
|
||||
'remark' => [],
|
||||
];
|
||||
|
||||
$message = [
|
||||
'name.required' => '请输入定价名称',
|
||||
'name.between' => '请输入2-32个字符',
|
||||
'company_id.required' => '请输入企业ID',
|
||||
'company_id.exists' => '企业不存在或已删除',
|
||||
'package_id.required' => '请输入套餐ID',
|
||||
];
|
||||
|
||||
Validator::validate($attributes, $rule, $message);
|
||||
|
||||
if (!$package = app(PackageRepository::class)->find($attributes['package_id'])) {
|
||||
throw new NotExistException('套餐不存在或已删除');
|
||||
}
|
||||
|
||||
$attributes['sn'] = $package['sn'] . '_' . $attributes['company_id'] . '_' . $attributes['base_price'];
|
||||
|
||||
if (!$attributes['id']) {
|
||||
if ($this->productRepository->where('sn', $attributes['sn'])->count()) {
|
||||
throw new NotAllowedException('已存在相同定价,请勿重复添加');
|
||||
}
|
||||
$node = $this->productRepository->create($attributes);
|
||||
}
|
||||
|
||||
if ($attributes['id']) {
|
||||
if (!$node = $this->productRepository->find($attributes['id'])) {
|
||||
throw new NotExistException('地址不存在或已删除');
|
||||
throw new NotExistException('定价不存在或已删除');
|
||||
}
|
||||
|
||||
if ($this->productRepository->where('sn', $attributes['sn'])->where('id', '<>', $attributes['id'])->count()) {
|
||||
throw new NotAllowedException('已存在相同定价,请核对后重试');
|
||||
}
|
||||
|
||||
$this->productRepository->setModel($node)->update($attributes);
|
||||
|
@ -52,6 +52,9 @@ class AppServiceProvider extends ServiceProvider
|
||||
// Image
|
||||
$this->app->register(\Intervention\Image\ImageServiceProviderLumen::class);
|
||||
|
||||
// 拼音
|
||||
$this->app->register(\Overtrue\LaravelPinyin\ServiceProvider::class);
|
||||
|
||||
// SMS
|
||||
$this->app->singleton('sms', function ($app) {
|
||||
return $app->loadComponent('sms', \Dipper\Sms\SmsServiceProvider::class);
|
||||
|
@ -16,7 +16,8 @@
|
||||
"dipper/flashmessage": ">=1.0.0",
|
||||
"dipper/jwt-auth": ">=1.0.0",
|
||||
"dipper/sms": ">=1.0.0",
|
||||
"jeremeamia/SuperClosure": "^2.4"
|
||||
"jeremeamia/SuperClosure": "^2.4",
|
||||
"overtrue/laravel-pinyin": "~3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "~1.4",
|
||||
|
102
composer.lock
generated
102
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ea5d9710363a1e1208b542ba36020b4b",
|
||||
"content-hash": "0792baf15c321ccef7691753e5b70a7c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
@ -3980,6 +3980,106 @@
|
||||
],
|
||||
"time": "2018-10-10T09:24:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "overtrue/laravel-pinyin",
|
||||
"version": "3.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/overtrue/laravel-pinyin.git",
|
||||
"reference": "4ca98a67cc2cd53ce98ee43dddbc5f5093cdbacc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/overtrue/laravel-pinyin/zipball/4ca98a67cc2cd53ce98ee43dddbc5f5093cdbacc",
|
||||
"reference": "4ca98a67cc2cd53ce98ee43dddbc5f5093cdbacc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"overtrue/pinyin": "~3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Overtrue\\LaravelPinyin\\ServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Pinyin": "Overtrue\\LaravelPinyin\\Facades\\Pinyin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Overtrue\\LaravelPinyin\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"email": "anzhengchao@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Chinese to Pinyin translator.",
|
||||
"keywords": [
|
||||
"Chinese",
|
||||
"Pinyin",
|
||||
"laravel",
|
||||
"overtrue"
|
||||
],
|
||||
"time": "2017-07-02T22:06:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "overtrue/pinyin",
|
||||
"version": "3.0.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/overtrue/pinyin.git",
|
||||
"reference": "3b781d267197b74752daa32814d3a2cf5d140779"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/overtrue/pinyin/zipball/3b781d267197b74752daa32814d3a2cf5d140779",
|
||||
"reference": "3b781d267197b74752daa32814d3a2cf5d140779",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Carlos",
|
||||
"homepage": "http://github.com/overtrue"
|
||||
}
|
||||
],
|
||||
"description": "Chinese to pinyin translator.",
|
||||
"homepage": "https://github.com/overtrue/pinyin",
|
||||
"keywords": [
|
||||
"Chinese",
|
||||
"Pinyin",
|
||||
"cn2pinyin"
|
||||
],
|
||||
"time": "2017-07-10T07:20:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v9.99.99",
|
||||
|
@ -197,6 +197,7 @@ class CreateBaseTables extends Migration
|
||||
$table->integer('package_id')->unsigned()->default(0)->comment('套餐ID');
|
||||
$table->integer('base_price')->unsigned()->default(0)->comment('基础价格');
|
||||
$table->integer('renewal_price')->unsigned()->default(0)->comment('续费价格');
|
||||
$table->text('remark')->nullable()->comment('备注');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
"jquery": "^3.3.1",
|
||||
"js-cookie": "^2.2.0",
|
||||
"moment": "^2.22.2",
|
||||
"pinyin-engine": "^1.1.0",
|
||||
"vue": "^2.5.2",
|
||||
"vue-router": "^3.0.1",
|
||||
"vuex": "^3.0.1",
|
||||
|
31
frontend/src/api/virtual/fetch.js
Normal file
31
frontend/src/api/virtual/fetch.js
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 名称操作
|
||||
*/
|
||||
|
||||
/**
|
||||
* [companies 企业列表]
|
||||
* @param {[type]} name [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function companies(name, limit = 5) {
|
||||
return service.get('api/virtual/fetch/companies', {
|
||||
params: {
|
||||
search: name,
|
||||
limit
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* [packages 企业列表]
|
||||
* @param {[type]} name [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function packages(name, limit = 5) {
|
||||
return service.get('api/virtual/fetch/packages', {
|
||||
params: {
|
||||
search: name,
|
||||
limit
|
||||
}
|
||||
});
|
||||
}
|
42
frontend/src/api/virtual/products.js
Normal file
42
frontend/src/api/virtual/products.js
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 定价管理
|
||||
*/
|
||||
|
||||
/**
|
||||
* [index 定价列表]
|
||||
* @param {[type]} data [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function index(data) {
|
||||
return service.get('api/virtual/products/index', {
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* [create 创建定价]
|
||||
* @param {[type]} data [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function create(data) {
|
||||
return serviceForm.post('api/virtual/products/create', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* [update 修改定价]
|
||||
* @param {[type]} data [description]
|
||||
* @param {[type]} id [角色id]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function update(data, id) {
|
||||
return serviceForm.post(`api/virtual/products/update/${id}`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* [destroy 删除定价]
|
||||
* @param {[type]} data [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function destroy(data) {
|
||||
return service.post('api/virtual/products/destroy', data);
|
||||
}
|
@ -7,11 +7,12 @@ import Vue from 'vue';
|
||||
import iView from 'iview';
|
||||
import Cookies from 'js-cookie';
|
||||
import Treeselect from '@riophae/vue-treeselect';
|
||||
import { service, serviceForm, axios } from 'service/service';
|
||||
import { service, serviceForm } from 'service/service';
|
||||
import App from './App';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
import mixins from './mixins';
|
||||
import complete from './mixins/complete';
|
||||
import md5 from 'blueimp-md5';
|
||||
import jquery from 'jquery';
|
||||
|
||||
@ -29,6 +30,7 @@ Vue.config.productionTip = false;
|
||||
|
||||
Vue.use(iView);
|
||||
Vue.mixin(mixins);
|
||||
Vue.mixin(complete);
|
||||
Vue.use(base);
|
||||
Vue.component('Treeselect', Treeselect);
|
||||
|
||||
|
65
frontend/src/mixins/complete.js
Normal file
65
frontend/src/mixins/complete.js
Normal file
@ -0,0 +1,65 @@
|
||||
import * as FETCH from 'api/virtual/fetch';
|
||||
import PinyinEngine from 'pinyin-engine';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
completeCompanyInitialized: false,
|
||||
completeCompaniesPinyinEngine: null,
|
||||
completeCompanies: [],
|
||||
completeHandledCompanies: [],
|
||||
completePackageInitialized: false,
|
||||
completePackagesPinyinEngine: null,
|
||||
completePackages: [],
|
||||
completeHandledPackages: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
initCompleteCompanies() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.completeCompanyInitialized = true;
|
||||
FETCH.companies(null, 0).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.completeCompanies = res.data;
|
||||
this.completeCompaniesPinyinEngine = new PinyinEngine(res.data, ['name']);
|
||||
resolve(res.data);
|
||||
}
|
||||
|
||||
reject(res);
|
||||
});
|
||||
});
|
||||
},
|
||||
handleCompleteCompanies(value) {
|
||||
if (!this.completeCompanyInitialized) {
|
||||
this.initCompleteCompanies();
|
||||
}
|
||||
|
||||
if (this.completeCompaniesPinyinEngine) {
|
||||
this.completeHandledCompanies = this.completeCompaniesPinyinEngine.query(value);
|
||||
}
|
||||
},
|
||||
initCompletePackages() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.completePackageInitialized = true;
|
||||
FETCH.packages(null, 0).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.completePackages = res.data;
|
||||
this.completePackagesPinyinEngine = new PinyinEngine(res.data, ['name']);
|
||||
resolve(res.data);
|
||||
}
|
||||
|
||||
reject(res);
|
||||
});
|
||||
});
|
||||
},
|
||||
handleCompletePackages(value) {
|
||||
if (!this.completePackageInitialized) {
|
||||
this.initCompletePackages();
|
||||
}
|
||||
|
||||
if (this.completePackagesPinyinEngine) {
|
||||
this.completeHandledPackages = this.completePackagesPinyinEngine.query(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -18,7 +18,8 @@ const routes = [
|
||||
{ path: '/accounts', name: 'Accounts', component: load('user/accounts/index'), meta: { title: '账号管理' } },
|
||||
{ path: '/iframe', name: 'Iframe', component: load('iframe/index'), meta: { title: 'iframe' } },
|
||||
{ path: '/companies', name: 'Companies', component: load('virtual/companies/index'), meta: { title: '企业管理' } },
|
||||
{ path: '/company/accounts', name: 'CompanyAccounts', component: load('virtual/company_accounts/index'), meta: { title: '账号管理' } }
|
||||
{ path: '/company/accounts', name: 'CompanyAccounts', component: load('virtual/company_accounts/index'), meta: { title: '账号管理' } },
|
||||
{ path: '/products', name: 'Products', component: load('virtual/products/index'), meta: { title: '定价管理' } }
|
||||
]
|
||||
},
|
||||
{ path: '*', redirect: { path: '/home' } }
|
||||
|
@ -1,90 +1,95 @@
|
||||
<template>
|
||||
<div class="layout-nav">
|
||||
<div class="logo-wrap">
|
||||
<img class="small" :src="CONFIG.logo_small" v-if="collapsed">
|
||||
<img class="big" :src="CONFIG.logo_big" v-else>
|
||||
</div>
|
||||
<div class="nav-wrap" v-if="left_menu.list.length">
|
||||
<Menu
|
||||
ref="sideMenu"
|
||||
v-show="!collapsed"
|
||||
width="auto"
|
||||
theme="dark"
|
||||
accordion
|
||||
:active-name="left_menu.active_name"
|
||||
:open-names="left_menu.open_names"
|
||||
@on-select="menuChange">
|
||||
<template v-for="(item,index) in left_menu.list">
|
||||
<side-menu-item v-if="item.menus && item.menus.length" :menu="item"></side-menu-item>
|
||||
<div class="layout-nav">
|
||||
<div class="logo-wrap">
|
||||
<img :src="CONFIG.logo_small" class="small" v-if="collapsed">
|
||||
<img :src="CONFIG.logo_big" class="big" v-else>
|
||||
</div>
|
||||
<div class="nav-wrap" v-if="left_menu.list.length">
|
||||
<Menu
|
||||
:active-name="left_menu.active_name"
|
||||
:open-names="left_menu.open_names"
|
||||
@on-select="menuChange"
|
||||
accordion
|
||||
ref="sideMenu"
|
||||
theme="dark"
|
||||
v-show="!collapsed"
|
||||
width="auto"
|
||||
>
|
||||
<template v-for="(item,index) in left_menu.list">
|
||||
<side-menu-item :menu="item" v-if="item.menus && item.menus.length"></side-menu-item>
|
||||
|
||||
<menuItem v-else :name="item.id">
|
||||
<Icon :type="item.icon" v-if="item.icon" />
|
||||
<span>{{item.title}}</span>
|
||||
</menuItem>
|
||||
</template>
|
||||
</Menu>
|
||||
<menuItem :name="item.id" v-else>
|
||||
<Icon :type="item.icon" v-if="item.icon"/>
|
||||
<span>{{item.title}}</span>
|
||||
</menuItem>
|
||||
</template>
|
||||
</Menu>
|
||||
|
||||
<div class="menu-collapsed" v-show="collapsed">
|
||||
<template v-for="(item,index) in left_menu.list">
|
||||
<collapsed-menu :menu="item" :level="1"></collapsed-menu>
|
||||
</template>
|
||||
</div>
|
||||
<div class="menu-collapsed" v-show="collapsed">
|
||||
<template v-for="(item,index) in left_menu.list">
|
||||
<collapsed-menu :level="1" :menu="item"></collapsed-menu>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 此处组件不能用异步加载(异步加载导致刷新页面菜单无法高亮)
|
||||
import sideMenuItem from 'views/layout/menu/side_menu_item';
|
||||
import collapsedMenu from 'views/layout/menu/collapsed_menu';
|
||||
// 此处组件不能用异步加载(异步加载导致刷新页面菜单无法高亮)
|
||||
import sideMenuItem from "views/layout/menu/side_menu_item";
|
||||
import collapsedMenu from "views/layout/menu/collapsed_menu";
|
||||
|
||||
export default{
|
||||
components: {
|
||||
sideMenuItem,
|
||||
collapsedMenu
|
||||
},
|
||||
props:{
|
||||
collapsed:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
['left_menu.open_names'](){
|
||||
if(this.$refs.sideMenu && this.left_menu.list.length){
|
||||
this.$nextTick(() => {
|
||||
this.$refs.sideMenu.updateOpened();
|
||||
this.$refs.sideMenu.updateActiveName();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
/**
|
||||
* [menuChange 菜单点击事件]
|
||||
* @param {[type]} mid [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
menuChange(mid){
|
||||
const menu = this.permissions_object[mid];
|
||||
switch(menu.open){
|
||||
case 0: //iframe方式
|
||||
this.$router.push({path:'/iframe',query:{mid:menu.id}});
|
||||
break;
|
||||
case 1: //打开新窗口
|
||||
window.open(menu.path);
|
||||
break;
|
||||
case 2: //弹出窗口
|
||||
const top = (window.outerHeight-menu.height)/2;
|
||||
const left = (window.outerWidth-menu.width)/2;
|
||||
window.open(menu.path,'',`width=${menu.width},height=${menu.height},top=${top},left=${left}`);
|
||||
break;
|
||||
case 3: //vue组件
|
||||
this.$router.push({path:menu.path,query:{mid:menu.id}});
|
||||
break;
|
||||
}
|
||||
}
|
||||
export default {
|
||||
components: {
|
||||
sideMenuItem,
|
||||
collapsedMenu
|
||||
},
|
||||
props: {
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
["left_menu.open_names"]() {
|
||||
if (this.$refs.sideMenu && this.left_menu.list.length) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.sideMenu.updateOpened();
|
||||
this.$refs.sideMenu.updateActiveName();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* [menuChange 菜单点击事件]
|
||||
* @param {[type]} mid [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
menuChange(mid) {
|
||||
const menu = this.permissions_object[mid];
|
||||
switch (menu.open) {
|
||||
case 0: //iframe方式
|
||||
this.$router.push({ path: "/iframe", query: { mid: menu.id } });
|
||||
break;
|
||||
case 1: //打开新窗口
|
||||
window.open(menu.path);
|
||||
break;
|
||||
case 2: //弹出窗口
|
||||
const top = (window.outerHeight - menu.height) / 2;
|
||||
const left = (window.outerWidth - menu.width) / 2;
|
||||
window.open(
|
||||
menu.path,
|
||||
"",
|
||||
`width=${menu.width},height=${menu.height},top=${top},left=${left}`
|
||||
);
|
||||
break;
|
||||
case 3: //vue组件
|
||||
this.$router.push({ path: menu.path, query: { mid: menu.id } });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -27,7 +27,9 @@
|
||||
<div class="search-wrap" v-show="search.show">
|
||||
<ul class="handle-wraper">
|
||||
<li class="handle-item w-250">
|
||||
<Input clearable placeholder="请输入企业名称" v-model.trim="params.name"></Input>
|
||||
<AutoComplete @on-search="handleCompleteCompanies" clearable icon="ios-search" placeholder="请输入企业名称" v-model.trim="params.name">
|
||||
<Option :key="item.id" :value="item.name" v-for="item in completeHandledCompanies">{{ item.name }}</Option>
|
||||
</AutoComplete>
|
||||
</li>
|
||||
|
||||
<li class="handle-item w-250">
|
||||
|
@ -1,5 +1,4 @@
|
||||
import * as API from 'api/virtual/companies';
|
||||
|
||||
export default {
|
||||
name: 'Companies',
|
||||
components: {
|
||||
|
@ -23,7 +23,9 @@
|
||||
<div class="search-wrap" v-show="search.show">
|
||||
<ul class="handle-wraper">
|
||||
<li class="handle-item w-250">
|
||||
<Input clearable placeholder="请输入企业名称" v-model.trim="params.name"></Input>
|
||||
<AutoComplete @on-search="handleCompleteCompanies" clearable icon="ios-search" placeholder="请输入企业名称" v-model.trim="params.name">
|
||||
<Option :key="item.id" :value="item.name" v-for="item in completeHandledCompanies">{{ item.name }}</Option>
|
||||
</AutoComplete>
|
||||
</li>
|
||||
|
||||
<li class="handle-item w-250">
|
||||
@ -59,7 +61,13 @@
|
||||
></Page>
|
||||
</div>
|
||||
|
||||
<ui-edit :data="editObj.data" :show.sync="editObj.show" :isUpdate.sync="editObj.isUpdate" @add-success="index" @update-success="index(list_data.current_page)"></ui-edit>
|
||||
<ui-edit
|
||||
:data="editObj.data"
|
||||
:isUpdate.sync="editObj.isUpdate"
|
||||
:show.sync="editObj.show"
|
||||
@add-success="index"
|
||||
@update-success="index(list_data.current_page)"
|
||||
></ui-edit>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
58
frontend/src/views/virtual/products/edit.vue
Normal file
58
frontend/src/views/virtual/products/edit.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<Modal :closable="false" :mask-closable="false" :title="isUpdate ? '编辑定价' : '添加定价'" @on-visible-change="visibleChange" v-model="my_show">
|
||||
<div class="page-edit-wrap uinn-lr20">
|
||||
<ui-loading :show="page_loading.show"></ui-loading>
|
||||
|
||||
<ul>
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">
|
||||
<span class="title-require">*</span>定价名称:
|
||||
</div>
|
||||
<div class="ui-list-content">
|
||||
<Input :maxlength="32" v-model.trim="params.name"></Input>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">
|
||||
<span class="title-require">*</span>选择套餐:
|
||||
</div>
|
||||
<div class="ui-list-content">
|
||||
<Select filterable v-model.trim="params.package_id">
|
||||
<Option :key="item.id" :value="item.id" v-for="item in completePackages">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">基础价格</div>
|
||||
<div class="ui-list-content">
|
||||
<InputNumber :max="10000" :min="0" :step="0.1" v-model.trim="params.base_price"></InputNumber>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">续费价格</div>
|
||||
<div class="ui-list-content">
|
||||
<InputNumber :max="10000" :min="0" :step="0.1" v-model.trim="params.renewal_price"></InputNumber>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">备注:</div>
|
||||
<div class="ui-list-content">
|
||||
<p>
|
||||
<Input :maxlength="32" v-model.trim="params.remark"></Input>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<footer class="ta-c" slot="footer">
|
||||
<Button @click="clear" class="w-80" ghost type="primary">取消</Button>
|
||||
<Button :loading="loading" @click="ok" class="w-80" type="primary">提交</Button>
|
||||
</footer>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script src="./js/edit.js"></script>
|
101
frontend/src/views/virtual/products/index.vue
Normal file
101
frontend/src/views/virtual/products/index.vue
Normal file
@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div class="page-wrap">
|
||||
<ui-loading :show="page_loading.show"></ui-loading>
|
||||
<div class="product-content">
|
||||
<div class="nav">
|
||||
<div class="search umar-t5">
|
||||
<AutoComplete @on-search="handleSearchCompanies" placeholder="输入名称进行过滤"></AutoComplete>
|
||||
</div>
|
||||
<div class="box">
|
||||
<CellGroup @on-click="index" v-for="item in companies">
|
||||
<Cell :name="item.id" :selected="item.id == params.company_id ? true : false" :title="item.name"/>
|
||||
</CellGroup>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<div class="page-handle-wrap">
|
||||
<ul class="handle-wraper bd-b">
|
||||
<li class="f-l">
|
||||
<div class="text-exp">
|
||||
<b>全部信息</b>
|
||||
</div>
|
||||
</li>
|
||||
<li class="f-r" v-if="params.company_id">
|
||||
<div class="handle-item">
|
||||
<Button @click="openEdit(true, null)" icon="md-add" type="primary" v-has="'create'">添加定价</Button>
|
||||
</div>
|
||||
|
||||
<div class="handle-item">
|
||||
<Button @click="search.show=!search.show" ghost icon="ios-search" type="primary">搜索</Button>
|
||||
</div>
|
||||
|
||||
<div class="handle-item">
|
||||
<Button @click="index(1)" icon="md-refresh">刷新</Button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="search-wrap" v-show="search.show">
|
||||
<ul class="handle-wraper">
|
||||
<li class="handle-item w-250">
|
||||
<Select clearable v-model="params.carrier_operator">
|
||||
<Option :value="'0'">联通</Option>
|
||||
<Option :value="'1'">移动</Option>
|
||||
<Option :value="'2'">电信</Option>
|
||||
</Select>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="handle-wraper">
|
||||
<li class="f-r">
|
||||
<div class="handle-item">
|
||||
<Button @click="index(1)" ghost type="primary">立即搜索</Button>
|
||||
</div>
|
||||
<div class="handle-item">
|
||||
<Button @click="resetSearch" ghost type="warning">重置搜索</Button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-list-wrap">
|
||||
<Table :columns="columns" :data="data ? data : []"></Table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ui-edit :data="editObj.data" :isUpdate="editObj.isUpdate" :show.sync="editObj.show" @add-success="index" @update-success="index"></ui-edit>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./js/index.js"></script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
.product-content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
.nav {
|
||||
width: 20%;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
.box {
|
||||
margin-top: 10px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
.info-wrap {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
112
frontend/src/views/virtual/products/js/edit.js
Normal file
112
frontend/src/views/virtual/products/js/edit.js
Normal file
@ -0,0 +1,112 @@
|
||||
import * as API from 'api/virtual/products';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isUpdate: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
my_show: false,
|
||||
loading: false,
|
||||
params: {
|
||||
name: '',
|
||||
company_id: '',
|
||||
package_id: '',
|
||||
base_price: 0,
|
||||
renewal_price: 0,
|
||||
remark: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show(bool) {
|
||||
this.my_show = bool;
|
||||
if (bool) {
|
||||
if (this.data) {
|
||||
for (let k in this.data) {
|
||||
if (k in this.params) {
|
||||
this.params[k] = this.data[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.completePackageInitialized) {
|
||||
this.initCompletePackages();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
ok() {
|
||||
if (!this.params.company_id) {
|
||||
this.$Message.info('非法请求');
|
||||
}
|
||||
|
||||
if (!this.params.name) {
|
||||
this.$Message.info('请输入定价名称');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.params.package_id) {
|
||||
this.$Message.info('请选择一个套餐');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isUpdate) {
|
||||
// 编辑
|
||||
API.update(this.params, this.data.id).then(res => {
|
||||
this.loading = false;
|
||||
if (res.code == 0) {
|
||||
this.$emit('update-success');
|
||||
this.$Message.success('更新成功');
|
||||
this.clear();
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
});
|
||||
} else {
|
||||
// 添加
|
||||
API.create(this.params).then(res => {
|
||||
this.loading = false;
|
||||
if (res.code == 0) {
|
||||
this.$emit('add-success');
|
||||
this.$Message.success('添加成功');
|
||||
this.clear();
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
visibleChange(bool) {
|
||||
if (!bool) {
|
||||
this.$emit('update:show', false);
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
for (let k in this.params) {
|
||||
if (k === 'base_price' || k === 'renewal_price') {
|
||||
this.params[k] = 0;
|
||||
} else {
|
||||
this.params[k] = '';
|
||||
}
|
||||
}
|
||||
|
||||
this.my_show = false;
|
||||
}
|
||||
}
|
||||
};
|
216
frontend/src/views/virtual/products/js/index.js
Normal file
216
frontend/src/views/virtual/products/js/index.js
Normal file
@ -0,0 +1,216 @@
|
||||
import * as API from 'api/virtual/products';
|
||||
|
||||
export default {
|
||||
name: 'Products',
|
||||
components: {
|
||||
UiEdit: resolve => require(['views/virtual/products/edit'], resolve)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
params: {
|
||||
company_id: null,
|
||||
carrier_operator: null
|
||||
},
|
||||
trashed: '',
|
||||
editObj: {
|
||||
show: false,
|
||||
isUpdate: false,
|
||||
data: null
|
||||
},
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
companies: [],
|
||||
data: [],
|
||||
columns: [
|
||||
{
|
||||
title: 'ID',
|
||||
key: 'id',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '定价名称',
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: '套餐名称',
|
||||
key: '',
|
||||
render: (h, { row, column, index }) => {
|
||||
if (row.package) {
|
||||
return h('span', row.package.name);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '定价名称',
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: '套餐价格',
|
||||
key: '',
|
||||
render: (h, { row, column, index }) => {
|
||||
let price = Number(row.base_price / 100);
|
||||
return h('span', price.toFixed(2));
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '续费价格',
|
||||
key: '',
|
||||
render: (h, { row, column, index }) => {
|
||||
let price = Number(row.renewal_price / 100);
|
||||
return h('span', price.toFixed(2));
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '运营商',
|
||||
key: 'carrier_operator'
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'updated_at',
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 170,
|
||||
render: (h, {
|
||||
row,
|
||||
column,
|
||||
index
|
||||
}) => {
|
||||
let html = [];
|
||||
|
||||
if (this.haveJurisdiction('update')) {
|
||||
html.push(h('Button', {
|
||||
props: {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
click: (event) => {
|
||||
this.openEdit(true, row);
|
||||
}
|
||||
}
|
||||
}, '编辑'));
|
||||
}
|
||||
|
||||
if (this.haveJurisdiction('destroy')) {
|
||||
html.push(h('Button', {
|
||||
props: {
|
||||
type: 'error',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'md-trash'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
click: () => {
|
||||
this.$Modal.confirm({
|
||||
title: '提示',
|
||||
content: '删除后该定价不可使用,请谨慎操作',
|
||||
onOk: () => {
|
||||
API.destroy({
|
||||
ids: row.id
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$Message.success('删除成功');
|
||||
this.request();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, '删除'));
|
||||
}
|
||||
|
||||
if (html.length) {
|
||||
return h('div', html);
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// this.index(1);
|
||||
this.initCompleteCompanies().then(res => {
|
||||
this.companies = res;
|
||||
}).catch(err => {
|
||||
this.$Message.error(err.message);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* [index 列表]
|
||||
* @param {Number} company_id [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
index(company_id = null) {
|
||||
if (company_id) {
|
||||
this.params.company_id = company_id;
|
||||
}
|
||||
|
||||
this.isShowLoading(true);
|
||||
|
||||
API.index(this.params).then(res => {
|
||||
this.isShowLoading(false);
|
||||
if (res.code == 0) {
|
||||
this.data = res.data;
|
||||
}
|
||||
}).catch(() => {
|
||||
this.isShowLoading(false);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* [openEdit 打开编辑弹窗]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
openEdit(show, row = null) {
|
||||
let isUpdate = false;
|
||||
let data = {};
|
||||
|
||||
if (row) {
|
||||
isUpdate = true;
|
||||
data = JSON.parse(JSON.stringify(row));
|
||||
data.base_price = data.base_price ? Number(data.base_price / 100) : 0;
|
||||
data.renewal_price = data.renewal_price ? Number(data.renewal_price / 100) : 0;
|
||||
data.company_id = this.params.company_id;
|
||||
} else {
|
||||
data = { company_id: this.params.company_id };
|
||||
}
|
||||
|
||||
this.editObj = { show, data, isUpdate };
|
||||
},
|
||||
/**
|
||||
* [request 刷新]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
request() {
|
||||
this.index();
|
||||
},
|
||||
resetSearch() {
|
||||
for (let k in this.params) {
|
||||
if (k !== 'company_id') {
|
||||
this.params[k] = null;
|
||||
}
|
||||
}
|
||||
this.index();
|
||||
},
|
||||
handleSearchCompanies(value) {
|
||||
if (value === '') {
|
||||
this.companies = this.completeCompanies;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.completeCompaniesPinyinEngine) {
|
||||
this.companies = this.completeCompaniesPinyinEngine.query(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
1
vendor/composer/autoload_files.php
vendored
1
vendor/composer/autoload_files.php
vendored
@ -67,5 +67,6 @@ return array(
|
||||
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
|
||||
'7b310ffe822e5ee3a4f219c3bf86fd38' => $vendorDir . '/dipper/foundation/src/helpers.php',
|
||||
'bee9632da3ca00a99623b9c35d0c4f8b' => $vendorDir . '/laravel/lumen-framework/src/helpers.php',
|
||||
'cda2d2f579338909929d3104d0afc501' => $vendorDir . '/overtrue/laravel-pinyin/src/helpers.php',
|
||||
'5c496105b995e0fd9efd783e0ae26dcf' => $baseDir . '/app/helpers.php',
|
||||
);
|
||||
|
2
vendor/composer/autoload_psr4.php
vendored
2
vendor/composer/autoload_psr4.php
vendored
@ -39,6 +39,8 @@ return array(
|
||||
'Predis\\' => array($vendorDir . '/predis/predis/src'),
|
||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||
'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'),
|
||||
'Overtrue\\Pinyin\\' => array($vendorDir . '/overtrue/pinyin/src'),
|
||||
'Overtrue\\LaravelPinyin\\' => array($vendorDir . '/overtrue/laravel-pinyin/src'),
|
||||
'Namshi\\JOSE\\' => array($vendorDir . '/namshi/jose/src/Namshi/JOSE'),
|
||||
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
|
||||
'MongoDB\\' => array($vendorDir . '/mongodb/mongodb/src'),
|
||||
|
14
vendor/composer/autoload_static.php
vendored
14
vendor/composer/autoload_static.php
vendored
@ -68,6 +68,7 @@ class ComposerStaticInite79258a3e34ad3e251999111d9f334d9
|
||||
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
|
||||
'7b310ffe822e5ee3a4f219c3bf86fd38' => __DIR__ . '/..' . '/dipper/foundation/src/helpers.php',
|
||||
'bee9632da3ca00a99623b9c35d0c4f8b' => __DIR__ . '/..' . '/laravel/lumen-framework/src/helpers.php',
|
||||
'cda2d2f579338909929d3104d0afc501' => __DIR__ . '/..' . '/overtrue/laravel-pinyin/src/helpers.php',
|
||||
'5c496105b995e0fd9efd783e0ae26dcf' => __DIR__ . '/../..' . '/app/helpers.php',
|
||||
);
|
||||
|
||||
@ -123,6 +124,11 @@ class ComposerStaticInite79258a3e34ad3e251999111d9f334d9
|
||||
'PhpParser\\' => 10,
|
||||
'PhpOffice\\PhpSpreadsheet\\' => 25,
|
||||
),
|
||||
'O' =>
|
||||
array (
|
||||
'Overtrue\\Pinyin\\' => 16,
|
||||
'Overtrue\\LaravelPinyin\\' => 23,
|
||||
),
|
||||
'N' =>
|
||||
array (
|
||||
'Namshi\\JOSE\\' => 12,
|
||||
@ -363,6 +369,14 @@ class ComposerStaticInite79258a3e34ad3e251999111d9f334d9
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet',
|
||||
),
|
||||
'Overtrue\\Pinyin\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/overtrue/pinyin/src',
|
||||
),
|
||||
'Overtrue\\LaravelPinyin\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/overtrue/laravel-pinyin/src',
|
||||
),
|
||||
'Namshi\\JOSE\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/namshi/jose/src/Namshi/JOSE',
|
||||
|
104
vendor/composer/installed.json
vendored
104
vendor/composer/installed.json
vendored
@ -4389,6 +4389,110 @@
|
||||
"php"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "overtrue/laravel-pinyin",
|
||||
"version": "3.0.5",
|
||||
"version_normalized": "3.0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/overtrue/laravel-pinyin.git",
|
||||
"reference": "4ca98a67cc2cd53ce98ee43dddbc5f5093cdbacc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/overtrue/laravel-pinyin/zipball/4ca98a67cc2cd53ce98ee43dddbc5f5093cdbacc",
|
||||
"reference": "4ca98a67cc2cd53ce98ee43dddbc5f5093cdbacc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"overtrue/pinyin": "~3.0"
|
||||
},
|
||||
"time": "2017-07-02T22:06:52+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Overtrue\\LaravelPinyin\\ServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Pinyin": "Overtrue\\LaravelPinyin\\Facades\\Pinyin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Overtrue\\LaravelPinyin\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"email": "anzhengchao@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Chinese to Pinyin translator.",
|
||||
"keywords": [
|
||||
"Chinese",
|
||||
"Pinyin",
|
||||
"laravel",
|
||||
"overtrue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "overtrue/pinyin",
|
||||
"version": "3.0.6",
|
||||
"version_normalized": "3.0.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/overtrue/pinyin.git",
|
||||
"reference": "3b781d267197b74752daa32814d3a2cf5d140779"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/overtrue/pinyin/zipball/3b781d267197b74752daa32814d3a2cf5d140779",
|
||||
"reference": "3b781d267197b74752daa32814d3a2cf5d140779",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8"
|
||||
},
|
||||
"time": "2017-07-10T07:20:01+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Carlos",
|
||||
"homepage": "http://github.com/overtrue"
|
||||
}
|
||||
],
|
||||
"description": "Chinese to pinyin translator.",
|
||||
"homepage": "https://github.com/overtrue/pinyin",
|
||||
"keywords": [
|
||||
"Chinese",
|
||||
"Pinyin",
|
||||
"cn2pinyin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v9.99.99",
|
||||
|
22
vendor/overtrue/laravel-pinyin/LICENSE
vendored
Executable file
22
vendor/overtrue/laravel-pinyin/LICENSE
vendored
Executable file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 安正超
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
92
vendor/overtrue/laravel-pinyin/README.md
vendored
Executable file
92
vendor/overtrue/laravel-pinyin/README.md
vendored
Executable file
@ -0,0 +1,92 @@
|
||||
# Laravel-pinyin
|
||||
|
||||
Chinese to Pinyin translator for Laravel5 / Lumen based on [overtrue/pinyin](https://github.com/overtrue/pinyin).
|
||||
|
||||
[](https://packagist.org/packages/overtrue/laravel-pinyin) [](https://packagist.org/packages/overtrue/laravel-pinyin) [](https://packagist.org/packages/overtrue/laravel-pinyin) [](https://packagist.org/packages/overtrue/laravel-pinyin)
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
composer require "overtrue/laravel-pinyin:~3.0"
|
||||
```
|
||||
|
||||
## For Laravel
|
||||
|
||||
Add the following line to the section `providers` of `config/app.php`:
|
||||
|
||||
```php
|
||||
'providers' => [
|
||||
//...
|
||||
Overtrue\LaravelPinyin\ServiceProvider::class,
|
||||
],
|
||||
```
|
||||
|
||||
as optional, you can use facade:
|
||||
|
||||
```php
|
||||
|
||||
'aliases' => [
|
||||
//...
|
||||
'Pinyin' => Overtrue\LaravelPinyin\Facades\Pinyin::class,
|
||||
],
|
||||
```
|
||||
|
||||
## For Lumen
|
||||
|
||||
Add the following line to `bootstrap/app.php` after `// $app->withEloquent();`
|
||||
|
||||
```php
|
||||
...
|
||||
// $app->withEloquent();
|
||||
|
||||
$app->register(Overtrue\LaravelPinyin\ServiceProvider::class);
|
||||
...
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
you can get the instance of `Overtrue\Pinyin\Pinyin` from app container:
|
||||
|
||||
```php
|
||||
|
||||
$pinyin = app('pinyin');
|
||||
echo $pinyin->sentence('带着希望去旅行,比到达终点更美好');
|
||||
// dài zhe xī wàng qù lǔ xíng, bǐ dào dá zhōng diǎn gèng měi hǎo
|
||||
```
|
||||
|
||||
There are more convenient functions:
|
||||
|
||||
| function | method |
|
||||
| ------------- | --------------------------------------------------- |
|
||||
| `pinyin()` | `app('pinyin')->convert()` |
|
||||
| `pinyin_abbr()` | `app('pinyin')->abbr()` |
|
||||
| `pinyin_permalink` | `app('pinyin')->permalink()` |
|
||||
| `pinyin_sentence` | `app('pinyin')->sentence()` |
|
||||
|
||||
```php
|
||||
var_dump(pinyin('带着希望去旅行,比到达终点更美好'));
|
||||
// ["dai", "zhe", "xi", "wang", "qu", "lv", "xing", "bi", "dao", "da", "zhong", "dian", "geng", "mei", "hao"]
|
||||
|
||||
var_dump(pinyin_abbr('带着希望去旅行'));
|
||||
// dzxwqlx
|
||||
...
|
||||
```
|
||||
|
||||
Using facade:
|
||||
|
||||
```php
|
||||
use Pinyin; // Facade class, NOT Overtrue\Pinyin\Pinyin
|
||||
|
||||
var_dump(Pinyin::convert('带着希望去旅行'));
|
||||
// ["dai", "zhe", "xi", "wang", "qu", "lv", "xing"]
|
||||
|
||||
echo Pinyin::sentence('带着希望去旅行,比到达终点更美好');
|
||||
// dài zhe xī wàng qù lǔ xíng, bǐ dào dá zhōng diǎn gèng měi hǎo
|
||||
|
||||
```
|
||||
|
||||
About `overtrue/pinyin` specific configuration and use, refer to: [overtrue/pinyin](https://github.com/overtrue/pinyin)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
38
vendor/overtrue/laravel-pinyin/composer.json
vendored
Executable file
38
vendor/overtrue/laravel-pinyin/composer.json
vendored
Executable file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "overtrue/laravel-pinyin",
|
||||
"description": "Chinese to Pinyin translator.",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"pinyin",
|
||||
"chinese",
|
||||
"overtrue"
|
||||
],
|
||||
"require": {
|
||||
"overtrue/pinyin": "~3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Overtrue\\LaravelPinyin\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Overtrue\\LaravelPinyin\\ServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Pinyin": "Overtrue\\LaravelPinyin\\Facades\\Pinyin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"email": "anzhengchao@gmail.com"
|
||||
}
|
||||
]
|
||||
}
|
14
vendor/overtrue/laravel-pinyin/src/Facades/Pinyin.php
vendored
Normal file
14
vendor/overtrue/laravel-pinyin/src/Facades/Pinyin.php
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Overtrue\LaravelPinyin\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
use Overtrue\Pinyin\Pinyin as Accessor;
|
||||
|
||||
class Pinyin extends Facade
|
||||
{
|
||||
public static function getFacadeAccessor()
|
||||
{
|
||||
return Accessor::class;
|
||||
}
|
||||
}
|
41
vendor/overtrue/laravel-pinyin/src/ServiceProvider.php
vendored
Executable file
41
vendor/overtrue/laravel-pinyin/src/ServiceProvider.php
vendored
Executable file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Overtrue\LaravelPinyin;
|
||||
|
||||
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
class ServiceProvider extends LaravelServiceProvider
|
||||
{
|
||||
/**
|
||||
* Indicates if loading of the provider is deferred.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $defer = true;
|
||||
|
||||
/**
|
||||
* Register the provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->singleton(Pinyin::class, function($app)
|
||||
{
|
||||
return new Pinyin();
|
||||
});
|
||||
|
||||
$this->app->alias(Pinyin::class, 'pinyin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return [Pinyin::class, 'pinyin'];
|
||||
}
|
||||
}
|
91
vendor/overtrue/laravel-pinyin/src/helpers.php
vendored
Executable file
91
vendor/overtrue/laravel-pinyin/src/helpers.php
vendored
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
if (! function_exists('pinyin')) {
|
||||
/**
|
||||
* Get the Pinyin of given string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function pinyin($string, $option = Pinyin::NONE)
|
||||
{
|
||||
return app(Pinyin::class)->convert($string, $option);
|
||||
}
|
||||
} else {
|
||||
Log::warning('There exist multiple function "pinyin".');
|
||||
}
|
||||
|
||||
if (! function_exists('pinyin_abbr')) {
|
||||
/**
|
||||
* Get the fist letters of given string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function pinyin_abbr($string, $delimiter = '')
|
||||
{
|
||||
return app(Pinyin::class)->abbr($string, $delimiter);
|
||||
}
|
||||
} else {
|
||||
Log::warning('There exist multiple function "pinyin_abbr".');
|
||||
}
|
||||
|
||||
if (! function_exists('pinyin_permlink')) {
|
||||
/**
|
||||
* Get a pinyin permalink from string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @deprecated since version 3.0.1. Use the "pinyin_permalink" method instead.
|
||||
*/
|
||||
function pinyin_permlink($string, $delimiter = '-')
|
||||
{
|
||||
return app(Pinyin::class)->permalink($string, $delimiter);
|
||||
}
|
||||
} else {
|
||||
Log::warning('There exist multiple function "pinyin_permlink".');
|
||||
}
|
||||
|
||||
if (! function_exists('pinyin_permalink')) {
|
||||
/**
|
||||
* Get a pinyin permalink from string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function pinyin_permalink($string, $delimiter = '-')
|
||||
{
|
||||
return app(Pinyin::class)->permalink($string, $delimiter);
|
||||
}
|
||||
} else {
|
||||
Log::warning('There exist multiple function "pinyin_permalink".');
|
||||
}
|
||||
|
||||
if (! function_exists('pinyin_sentence')) {
|
||||
/**
|
||||
* Get the fist pinyin and letters of given string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $tone
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function pinyin_sentence($string, $tone = false)
|
||||
{
|
||||
return app(Pinyin::class)->sentence($string, $tone);
|
||||
}
|
||||
} else {
|
||||
Log::warning('There exist multiple function "pinyin_sentence".');
|
||||
}
|
21
vendor/overtrue/pinyin/LICENSE
vendored
Executable file
21
vendor/overtrue/pinyin/LICENSE
vendored
Executable file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 安正超
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
120
vendor/overtrue/pinyin/README.md
vendored
Executable file
120
vendor/overtrue/pinyin/README.md
vendored
Executable file
@ -0,0 +1,120 @@
|
||||
Pinyin
|
||||
======
|
||||
|
||||
[](https://travis-ci.org/overtrue/pinyin)
|
||||
[](https://packagist.org/packages/overtrue/pinyin) [](https://packagist.org/packages/overtrue/pinyin) [](https://packagist.org/packages/overtrue/pinyin) [](https://packagist.org/packages/overtrue/pinyin)
|
||||
[](https://scrutinizer-ci.com/g/overtrue/pinyin/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/overtrue/pinyin/?branch=master)
|
||||
|
||||
<p align="center">
|
||||
<br>
|
||||
<b>创造不息,交付不止</b>
|
||||
<br>
|
||||
<a href="https://www.yousails.com">
|
||||
<img src="https://yousails.com/banners/brand.png" width=350>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
:cn: 基于 [CC-CEDICT](http://cc-cedict.org/wiki/) 词典的中文转拼音工具,更准确的支持多音字的汉字转拼音解决方案。
|
||||
|
||||
|
||||
## 安装
|
||||
|
||||
使用 Composer 安装:
|
||||
|
||||
```
|
||||
composer require "overtrue/pinyin:~3.0"
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
可选转换方案:
|
||||
|
||||
- 内存型,适用于服务器内存空间较富余,优点:转换快
|
||||
- 小内存型(默认),适用于内存比较紧张的环境,优点:占用内存小,转换不如内存型快
|
||||
- I/O型,适用于虚拟机,内存限制比较严格环境。优点:非常微小内存消耗。缺点:转换慢,不如内存型转换快,php >= 5.5
|
||||
|
||||
### 拼音数组
|
||||
|
||||
```php
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
// 小内存型
|
||||
$pinyin = new Pinyin(); // 默认
|
||||
// 内存型
|
||||
// $pinyin = new Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
|
||||
// I/O型
|
||||
// $pinyin = new Pinyin('Overtrue\Pinyin\GeneratorFileDictLoader');
|
||||
|
||||
$pinyin->convert('带着希望去旅行,比到达终点更美好');
|
||||
// ["dai", "zhe", "xi", "wang", "qu", "lv", "xing", "bi", "dao", "da", "zhong", "dian", "geng", "mei", "hao"]
|
||||
|
||||
$pinyin->convert('带着希望去旅行,比到达终点更美好', PINYIN_UNICODE);
|
||||
// ["dài","zhe","xī","wàng","qù","lǚ","xíng","bǐ","dào","dá","zhōng","diǎn","gèng","měi","hǎo"]
|
||||
|
||||
$pinyin->convert('带着希望去旅行,比到达终点更美好', PINYIN_ASCII);
|
||||
//["dai4","zhe","xi1","wang4","qu4","lv3","xing2","bi3","dao4","da2","zhong1","dian3","geng4","mei3","hao3"]
|
||||
```
|
||||
|
||||
- 小内存型: 将字典分片载入内存
|
||||
- 内存型: 将所有字典预先载入内存
|
||||
- I/O型: 不载入内存,将字典使用文件流打开逐行遍历并运用php5.5生成器(yield)特性分配单行内存
|
||||
|
||||
|
||||
选项:
|
||||
|
||||
| 选项 | 描述 |
|
||||
| ------------- | ---------------------------------------------------|
|
||||
| `PINYIN_NONE` | 不带音调输出: `mei hao` |
|
||||
| `PINYIN_ASCII` | 带数字式音调: `mei3 hao3` |
|
||||
| `PINYIN_UNICODE` | UNICODE 式音调:`měi hǎo` |
|
||||
|
||||
### 生成用于链接的拼音字符串
|
||||
|
||||
```php
|
||||
$pinyin->permalink('带着希望去旅行'); // dai-zhe-xi-wang-qu-lv-xing
|
||||
$pinyin->permalink('带着希望去旅行', '.'); // dai.zhe.xi.wang.qu.lv.xing
|
||||
```
|
||||
|
||||
### 获取首字符字符串
|
||||
|
||||
```php
|
||||
$pinyin->abbr('带着希望去旅行'); // dzxwqlx
|
||||
$pinyin->abbr('带着希望去旅行', '-'); // d-z-x-w-q-l-x
|
||||
```
|
||||
|
||||
### 翻译整段文字为拼音
|
||||
|
||||
将会保留中文字符:`,。 ! ? : “ ” ‘ ’` 并替换为对应的英文符号。
|
||||
|
||||
```php
|
||||
$pinyin->sentence('带着希望去旅行,比到达终点更美好!');
|
||||
// dai zhe xi wang qu lv xing, bi dao da zhong dian geng mei hao!
|
||||
|
||||
$pinyin->sentence('带着希望去旅行,比到达终点更美好!', true);
|
||||
// dài zhe xī wàng qù lǚ xíng, bǐ dào dá zhōng diǎn gèng měi hǎo!
|
||||
```
|
||||
|
||||
### 翻译姓名
|
||||
|
||||
姓名的姓的读音有些与普通字不一样,比如 ‘单’ 常见的音为 `dan`,而作为姓的时候读 `shan`。
|
||||
|
||||
```php
|
||||
$pinyin->name('单某某'); // ['shan', 'mou', 'mou']
|
||||
$pinyin->name('单某某', PINYIN_UNICODE); // ["shàn","mǒu","mǒu"]
|
||||
```
|
||||
|
||||
## 在 Laravel 中使用
|
||||
|
||||
独立的包在这里:[overtrue/laravel-pinyin](https://github.com/overtrue/laravel-pinyin)
|
||||
|
||||
## Contribution
|
||||
欢迎提意见及完善补充词库 [`overtrue/pinyin-dictionary-maker`](https://github.com/overtrue/pinyin-dictionary-maker/tree/master/patches) :kiss:
|
||||
|
||||
## 参考
|
||||
|
||||
- [详细参考资料](https://github.com/overtrue/pinyin-resources)
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
33
vendor/overtrue/pinyin/composer.json
vendored
Executable file
33
vendor/overtrue/pinyin/composer.json
vendored
Executable file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "overtrue/pinyin",
|
||||
"description": "Chinese to pinyin translator.",
|
||||
"keywords": [
|
||||
"chinese",
|
||||
"pinyin",
|
||||
"cn2pinyin"
|
||||
],
|
||||
"homepage": "https://github.com/overtrue/pinyin",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Carlos",
|
||||
"homepage": "http://github.com/overtrue"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\Test\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php":">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8"
|
||||
}
|
||||
}
|
84
vendor/overtrue/pinyin/data/surnames
vendored
Normal file
84
vendor/overtrue/pinyin/data/surnames
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
return array (
|
||||
'万俟' => ' mò qí',
|
||||
'尉迟' => ' yù chí',
|
||||
'单于' => ' chán yú',
|
||||
'不' => ' fǒu',
|
||||
'沈' => ' shěn',
|
||||
'称' => ' chēng',
|
||||
'车' => ' chē',
|
||||
'万' => ' wàn',
|
||||
'汤' => ' tāng',
|
||||
'阿' => ' ā',
|
||||
'丁' => ' dīng',
|
||||
'强' => ' qiáng',
|
||||
'仇' => ' qiú',
|
||||
'叶' => ' yè',
|
||||
'阚' => ' kàn',
|
||||
'乐' => ' yuè',
|
||||
'乜' => ' niè',
|
||||
'陆' => ' lù',
|
||||
'殷' => ' yīn',
|
||||
'牟' => ' móu',
|
||||
'区' => ' ōu',
|
||||
'宿' => ' sù',
|
||||
'俞' => ' yú',
|
||||
'余' => ' yú',
|
||||
'齐' => ' qí',
|
||||
'许' => ' xǔ',
|
||||
'信' => ' xìn',
|
||||
'无' => ' wú',
|
||||
'浣' => ' wǎn',
|
||||
'艾' => ' ài',
|
||||
'浅' => ' qiǎn',
|
||||
'烟' => ' yān',
|
||||
'蓝' => ' lán',
|
||||
'於' => ' yú',
|
||||
'寻' => ' xún',
|
||||
'殳' => ' shū',
|
||||
'思' => ' sī',
|
||||
'鸟' => ' niǎo',
|
||||
'卜' => ' bǔ',
|
||||
'单' => ' shàn',
|
||||
'南' => ' nán',
|
||||
'柏' => ' bǎi',
|
||||
'朴' => ' piáo',
|
||||
'繁' => ' pó',
|
||||
'曾' => ' zēng',
|
||||
'瞿' => ' qú',
|
||||
'缪' => ' miào',
|
||||
'石' => ' shí',
|
||||
'冯' => ' féng',
|
||||
'覃' => ' qín',
|
||||
'幺' => ' yāo',
|
||||
'种' => ' chóng',
|
||||
'折' => ' shè',
|
||||
'燕' => ' yān',
|
||||
'纪' => ' jǐ',
|
||||
'过' => ' guō',
|
||||
'华' => ' huà',
|
||||
'冼' => ' xiǎn',
|
||||
'秘' => ' bì',
|
||||
'重' => ' chóng',
|
||||
'解' => ' xiè',
|
||||
'那' => ' nā',
|
||||
'和' => ' hé',
|
||||
'贾' => ' jiǎ',
|
||||
'塔' => ' tǎ',
|
||||
'盛' => ' shèng',
|
||||
'查' => ' zhā',
|
||||
'盖' => ' gě',
|
||||
'居' => ' jū',
|
||||
'哈' => ' hǎ',
|
||||
'的' => ' dē',
|
||||
'薄' => ' bó',
|
||||
'佴' => ' nài',
|
||||
'六' => ' lù',
|
||||
'都' => ' dū',
|
||||
'翟' => ' zhái',
|
||||
'扎' => ' zā',
|
||||
'藏' => ' zàng',
|
||||
'粘' => ' niàn',
|
||||
'难' => ' nàn',
|
||||
'若' => ' ruò',
|
||||
);
|
8003
vendor/overtrue/pinyin/data/words_0
vendored
Normal file
8003
vendor/overtrue/pinyin/data/words_0
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_1
vendored
Normal file
8003
vendor/overtrue/pinyin/data/words_1
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_2
vendored
Normal file
8003
vendor/overtrue/pinyin/data/words_2
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_3
vendored
Normal file
8003
vendor/overtrue/pinyin/data/words_3
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_4
vendored
Normal file
8003
vendor/overtrue/pinyin/data/words_4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2056
vendor/overtrue/pinyin/data/words_5
vendored
Normal file
2056
vendor/overtrue/pinyin/data/words_5
vendored
Normal file
File diff suppressed because it is too large
Load Diff
42
vendor/overtrue/pinyin/src/DictLoaderInterface.php
vendored
Normal file
42
vendor/overtrue/pinyin/src/DictLoaderInterface.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* Dict loader interface.
|
||||
*/
|
||||
interface DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* <pre>
|
||||
* [
|
||||
* '响应时间' => "[\t]xiǎng[\t]yìng[\t]shí[\t]jiān",
|
||||
* '长篇连载' => '[\t]cháng[\t]piān[\t]lián[\t]zǎi',
|
||||
* //...
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback);
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback);
|
||||
}
|
76
vendor/overtrue/pinyin/src/FileDictLoader.php
vendored
Normal file
76
vendor/overtrue/pinyin/src/FileDictLoader.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* Dict File loader.
|
||||
*/
|
||||
class FileDictLoader implements DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Words segment name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $segmentName = 'words_%s';
|
||||
|
||||
/**
|
||||
* Dict path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback)
|
||||
{
|
||||
for ($i = 0; $i < 100; ++$i) {
|
||||
$segment = $this->path.'/'.sprintf($this->segmentName, $i);
|
||||
|
||||
if (file_exists($segment)) {
|
||||
$dictionary = (array) include $segment;
|
||||
$callback($dictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback)
|
||||
{
|
||||
$surnames = $this->path.'/surnames';
|
||||
|
||||
if (file_exists($surnames)) {
|
||||
$dictionary = (array) include $surnames;
|
||||
$callback($dictionary);
|
||||
}
|
||||
}
|
||||
}
|
142
vendor/overtrue/pinyin/src/GeneratorFileDictLoader.php
vendored
Normal file
142
vendor/overtrue/pinyin/src/GeneratorFileDictLoader.php
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
use SplFileObject;
|
||||
use Generator;
|
||||
|
||||
/**
|
||||
* Generator syntax(yield) Dict File loader.
|
||||
*/
|
||||
class GeneratorFileDictLoader implements DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Data directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Words segment name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $segmentName = 'words_%s';
|
||||
|
||||
/**
|
||||
* SplFileObjects.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $handles = [];
|
||||
|
||||
/**
|
||||
* surnames.
|
||||
*
|
||||
* @var SplFileObject
|
||||
*/
|
||||
protected static $surnamesHandle;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
for ($i = 0; $i < 100; ++$i) {
|
||||
$segment = $this->path.'/'.sprintf($this->segmentName, $i);
|
||||
|
||||
if (file_exists($segment) && is_file($segment)) {
|
||||
array_push(static::$handles, $this->openFile($segment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new file object.
|
||||
*
|
||||
* @param string $filename file path
|
||||
*
|
||||
* @return SplFileObject
|
||||
*/
|
||||
protected function openFile($filename, $mode = 'r')
|
||||
{
|
||||
return new SplFileObject($filename, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* get Generator syntax.
|
||||
*
|
||||
* @param array $handles SplFileObjects
|
||||
*/
|
||||
protected function getGenerator(array $handles)
|
||||
{
|
||||
foreach ($handles as $handle) {
|
||||
$handle->seek(0);
|
||||
while ($handle->eof() === false) {
|
||||
$string = str_replace(['\'', ' ', PHP_EOL, ','], '', $handle->fgets());
|
||||
|
||||
if (strpos($string, '=>') === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($string, $pinyin) = explode('=>', $string);
|
||||
|
||||
yield $string => $pinyin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse the stream.
|
||||
*
|
||||
* @param Generator $generator
|
||||
* @param Closure $callback
|
||||
*
|
||||
* @author Seven Du <shiweidu@outlook.com>
|
||||
*/
|
||||
protected function traversing(Generator $generator, Closure $callback)
|
||||
{
|
||||
foreach ($generator as $string => $pinyin) {
|
||||
$callback([$string => $pinyin]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback)
|
||||
{
|
||||
$this->traversing($this->getGenerator(static::$handles), $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback)
|
||||
{
|
||||
if (!static::$surnamesHandle instanceof SplFileObject) {
|
||||
static::$surnamesHandle = $this->openFile($this->path.'/surnames');
|
||||
}
|
||||
|
||||
$this->traversing($this->getGenerator([static::$surnamesHandle]), $callback);
|
||||
}
|
||||
}
|
96
vendor/overtrue/pinyin/src/MemoryFileDictLoader.php
vendored
Normal file
96
vendor/overtrue/pinyin/src/MemoryFileDictLoader.php
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* Memory Dict File loader.
|
||||
*/
|
||||
class MemoryFileDictLoader implements DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Data directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Words segment name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $segmentName = 'words_%s';
|
||||
|
||||
/**
|
||||
* Segment files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $segments = array();
|
||||
|
||||
/**
|
||||
* Surname cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $surnames = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
for ($i = 0; $i < 100; ++$i) {
|
||||
$segment = $path.'/'.sprintf($this->segmentName, $i);
|
||||
|
||||
if (file_exists($segment)) {
|
||||
$this->segments[] = (array) include $segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback)
|
||||
{
|
||||
foreach ($this->segments as $dictionary) {
|
||||
$callback($dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback)
|
||||
{
|
||||
if (empty($this->surnames)) {
|
||||
$surnames = $this->path.'/surnames';
|
||||
|
||||
if (file_exists($surnames)) {
|
||||
$this->surnames = (array) include $surnames;
|
||||
}
|
||||
}
|
||||
|
||||
$callback($this->surnames);
|
||||
}
|
||||
}
|
309
vendor/overtrue/pinyin/src/Pinyin.php
vendored
Normal file
309
vendor/overtrue/pinyin/src/Pinyin.php
vendored
Normal file
@ -0,0 +1,309 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/*
|
||||
* Chinese to pinyin translator.
|
||||
*
|
||||
* @author overtrue <i@overtrue.me>
|
||||
* @copyright 2015 overtrue <i@overtrue.me>
|
||||
*
|
||||
* @link https://github.com/overtrue/pinyin
|
||||
* @link http://overtrue.me
|
||||
*/
|
||||
|
||||
define('PINYIN_NONE', 'none');
|
||||
define('PINYIN_ASCII', 'ascii');
|
||||
define('PINYIN_UNICODE', 'unicode');
|
||||
|
||||
class Pinyin
|
||||
{
|
||||
const NONE = 'none';
|
||||
const ASCII = 'ascii';
|
||||
const UNICODE = 'unicode';
|
||||
|
||||
/**
|
||||
* Dict loader.
|
||||
*
|
||||
* @var \Overtrue\Pinyin\DictLoaderInterface
|
||||
*/
|
||||
protected $loader;
|
||||
|
||||
/**
|
||||
* Punctuations map.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $punctuations = array(
|
||||
',' => ',',
|
||||
'。' => '.',
|
||||
'!' => '!',
|
||||
'?' => '?',
|
||||
':' => ':',
|
||||
'“' => '"',
|
||||
'”' => '"',
|
||||
'‘' => "'",
|
||||
'’' => "'",
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $loaderName
|
||||
*/
|
||||
public function __construct($loaderName = null)
|
||||
{
|
||||
$this->loader = $loaderName ?: 'Overtrue\\Pinyin\\FileDictLoader';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $option
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convert($string, $option = self::NONE)
|
||||
{
|
||||
$pinyin = $this->romanize($string);
|
||||
|
||||
return $this->splitWords($pinyin, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string (person name) to pinyin.
|
||||
*
|
||||
* @param string $stringName
|
||||
* @param string $option
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function name($stringName, $option = self::NONE)
|
||||
{
|
||||
$pinyin = $this->romanize($stringName, true);
|
||||
|
||||
return $this->splitWords($pinyin, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pinyin permalink from string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function permalink($string, $delimiter = '-')
|
||||
{
|
||||
if (!in_array($delimiter, array('_', '-', '.', ''), true)) {
|
||||
throw new InvalidArgumentException("Delimiter must be one of: '_', '-', '', '.'.");
|
||||
}
|
||||
|
||||
return implode($delimiter, $this->convert($string, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return first letters.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function abbr($string, $delimiter = '')
|
||||
{
|
||||
return implode($delimiter, array_map(function ($pinyin) {
|
||||
return $pinyin[0];
|
||||
}, $this->convert($string, false)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Chinese phrase to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
* @param string $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function phrase($string, $delimiter = ' ', $option = self::NONE)
|
||||
{
|
||||
return implode($delimiter, $this->convert($string, $option));
|
||||
}
|
||||
|
||||
/**
|
||||
* Chinese to pinyin sentense.
|
||||
*
|
||||
* @param string $sentence
|
||||
* @param bool $withTone
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sentence($sentence, $withTone = false)
|
||||
{
|
||||
$marks = array_keys($this->punctuations);
|
||||
$punctuationsRegex = preg_quote(implode(array_merge($marks, $this->punctuations)), '/');
|
||||
$regex = '/[^üāēīōūǖáéíóúǘǎěǐǒǔǚàèìòùǜa-z0-9'.$punctuationsRegex.'\s_]+/iu';
|
||||
|
||||
$pinyin = preg_replace($regex, '', $this->romanize($sentence));
|
||||
|
||||
$punctuations = array_merge($this->punctuations, array("\t" => ' ', ' ' => ' '));
|
||||
$pinyin = trim(str_replace(array_keys($punctuations), $punctuations, $pinyin));
|
||||
|
||||
return $withTone ? $pinyin : $this->format($pinyin, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader setter.
|
||||
*
|
||||
* @param \Overtrue\Pinyin\DictLoaderInterface $loader
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLoader(DictLoaderInterface $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return dict loader,.
|
||||
*
|
||||
* @return \Overtrue\Pinyin\DictLoaderInterface
|
||||
*/
|
||||
public function getLoader()
|
||||
{
|
||||
if (!($this->loader instanceof DictLoaderInterface)) {
|
||||
$dataDir = dirname(__DIR__).'/data/';
|
||||
|
||||
$loaderName = $this->loader;
|
||||
$this->loader = new $loaderName($dataDir);
|
||||
}
|
||||
|
||||
return $this->loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function prepare($string)
|
||||
{
|
||||
$string = preg_replace_callback('~[a-z0-9_-]+~i', function ($matches) {
|
||||
return "\t".$matches[0];
|
||||
}, $string);
|
||||
|
||||
return preg_replace("~[^\p{Han}\p{P}\p{Z}\p{M}\p{N}\p{L}\t]~u", '', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Chinese to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param bool $isName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function romanize($string, $isName = false)
|
||||
{
|
||||
$string = $this->prepare($string);
|
||||
|
||||
$dictLoader = $this->getLoader();
|
||||
|
||||
if ($isName) {
|
||||
$string = $this->convertSurname($string, $dictLoader);
|
||||
}
|
||||
|
||||
$dictLoader->map(function ($dictionary) use (&$string) {
|
||||
$string = strtr($string, $dictionary);
|
||||
});
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Chinese Surname to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param \Overtrue\Pinyin\DictLoaderInterface $dictLoader
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function convertSurname($string, $dictLoader)
|
||||
{
|
||||
$dictLoader->mapSurname(function ($dictionary) use (&$string) {
|
||||
foreach ($dictionary as $surname => $pinyin) {
|
||||
if (strpos($string, $surname) === 0) {
|
||||
$string = $pinyin.mb_substr($string, mb_strlen($surname, 'UTF-8'), mb_strlen($string, 'UTF-8') - 1, 'UTF-8');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split pinyin string to words.
|
||||
*
|
||||
* @param string $pinyin
|
||||
* @param string $option
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function splitWords($pinyin, $option)
|
||||
{
|
||||
$split = array_filter(preg_split('/[^üāēīōūǖáéíóúǘǎěǐǒǔǚàèìòùǜa-z\d]+/iu', $pinyin));
|
||||
|
||||
if ($option !== self::UNICODE) {
|
||||
foreach ($split as $index => $pinyin) {
|
||||
$split[$index] = $this->format($pinyin, $option === self::ASCII);
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($split);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format.
|
||||
*
|
||||
* @param string $pinyin
|
||||
* @param bool $tone
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function format($pinyin, $tone = false)
|
||||
{
|
||||
$replacements = array(
|
||||
'üē' => array('ue', 1), 'üé' => array('ue', 2), 'üě' => array('ue', 3), 'üè' => array('ue', 4),
|
||||
'ā' => array('a', 1), 'ē' => array('e', 1), 'ī' => array('i', 1), 'ō' => array('o', 1), 'ū' => array('u', 1), 'ǖ' => array('v', 1),
|
||||
'á' => array('a', 2), 'é' => array('e', 2), 'í' => array('i', 2), 'ó' => array('o', 2), 'ú' => array('u', 2), 'ǘ' => array('v', 2),
|
||||
'ǎ' => array('a', 3), 'ě' => array('e', 3), 'ǐ' => array('i', 3), 'ǒ' => array('o', 3), 'ǔ' => array('u', 3), 'ǚ' => array('v', 3),
|
||||
'à' => array('a', 4), 'è' => array('e', 4), 'ì' => array('i', 4), 'ò' => array('o', 4), 'ù' => array('u', 4), 'ǜ' => array('v', 4),
|
||||
);
|
||||
|
||||
foreach ($replacements as $unicde => $replacement) {
|
||||
if (false !== strpos($pinyin, $unicde)) {
|
||||
$pinyin = str_replace($unicde, $replacement[0], $pinyin).($tone ? $replacement[1] : '');
|
||||
}
|
||||
}
|
||||
|
||||
return $pinyin;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user