From 73b874c72ad55eb9eef21c36160ac0de58f0189e Mon Sep 17 00:00:00 2001
From: quanwei <419654421@qq.com>
Date: Thu, 05 Feb 2026 10:30:43 +0800
Subject: [PATCH] 优化名片
---
shop_vue/src/views/plus/operations/setting/part/License.vue | 2
admin/app/common/service/order/OrderCompleteService.php | 4
agent_vue/src/store/index.js | 2
admin/app/common/model/plus/operations/Order.php | 178 ++++
admin/app/api/service/order/paysuccess/type/MasterPaySuccessService.php | 4
agent_vue/src/utils/base.js | 12
shop_vue/src/views/plus/operations/setting/part/Words.vue | 2
shop_vue/src/views/plus/operations/setting/part/Background.vue | 2
admin/app/api/model/plus/operations/Operations.php | 40 +
mobile/pages/plus/business/add.vue | 893 +++++++++++++++++------
mobile/pages/plus/business/index.vue | 32
admin/app/event.php | 4
admin/app/api/controller/plus/business/Template.php | 86 +
mobile/pages/plus/business/list.vue | 1
admin/app/job/event/OperationsOrder.php | 88 ++
shop_vue/src/views/plus/operations/setting/part/Condition.vue | 2
shop_vue/src/views/plus/operations/index.vue | 9
admin/app/api/model/plus/operations/Setting.php | 11
admin/app/job/event/JobScheduler.php | 2
shop_vue/src/views/plus/operations/setting/part/Basic.vue | 32
agent_vue/src/utils/request.js | 14
shop_vue/src/views/plus/operations/setting/Setting.vue | 4
agent_vue/src/api/statistics.js | 32
admin/app/api/model/plus/operations/Order.php | 39 +
shop_vue/src/views/plus/operations/setting/part/Settlement.vue | 2
operations_vue/static/css/common.css | 4
shop_vue/src/api/plus/operations.js | 186 ++++
mobile/pages/plus/business/detail.vue | 11
agent_vue/src/filters/index.js | 30
admin/app/shop/controller/plus/operations/Operations.php | 2
admin/app/shop/service/order/ExportService.php | 74 +
admin/app/common/service/business/Poster.php | 371 ++++++++-
admin/app/common/model/plus/operations/Setting.php | 2
admin/app/api/controller/plus/business/Business.php | 17
admin/app/shop/controller/plus/operations/Order.php | 33
admin/app/job/model/plus/operations/Order.php | 38 +
agent_vue/src/router/index.js | 4
agent_vue/src/permission.js | 2
shop_vue/src/views/plus/operations/setting/part/Bonus.vue | 2
39 files changed, 1,849 insertions(+), 424 deletions(-)
diff --git a/admin/app/api/controller/plus/business/Business.php b/admin/app/api/controller/plus/business/Business.php
index cc37f1a..2256fe4 100644
--- a/admin/app/api/controller/plus/business/Business.php
+++ b/admin/app/api/controller/plus/business/Business.php
@@ -116,6 +116,12 @@
if(!(new BusinessModel())->where(['user_id'=>$user['user_id'],'is_default'=>1])->find()){
$param['is_default'] = 1;
}
+ if (empty($param['name'])){
+ return $this->renderError('请输入姓名');
+ }
+ if (empty($param['mobile'])){
+ return $this->renderError('输入手机号');
+ }
if ((new BusinessModel())->add($param)) {
return $this->renderSuccess('添加成功');
}
@@ -257,12 +263,21 @@
$user = $this->getUser();
$param['user_id'] = $user['user_id'];
}
-
+ if (empty($param['name'])){
+ return $this->renderError('请填写姓名');
+ }
+ if (empty($param['mobile'])){
+ return $this->renderError('请填写手机号');
+ }
+ if (empty($param['unit'][0])){
+ return $this->renderError('请至少填写填写公司');
+ }
$param['unit'] = json_encode($param['unit'], JSON_UNESCAPED_UNICODE);
$param['duties'] = json_encode($param['duties'], JSON_UNESCAPED_UNICODE);
$param['address'] = json_encode($param['address'], JSON_UNESCAPED_UNICODE);
!empty($param['position'])?$param['position'] = json_encode($param['position'], JSON_UNESCAPED_UNICODE):'';
$param['position'] = $param['duties'];
+
if ($model->add($param)) {
return $this->renderSuccess('编辑成功');
}
diff --git a/admin/app/api/controller/plus/business/Template.php b/admin/app/api/controller/plus/business/Template.php
index 75ea06e..97da92d 100644
--- a/admin/app/api/controller/plus/business/Template.php
+++ b/admin/app/api/controller/plus/business/Template.php
@@ -12,40 +12,64 @@
public function getList()
{
$model = new TemplateModel();
- $param=$this->request->param();
- $list=$model->lists($param);
- foreach($list as $l=>$v ){
- $list[$l]['style']= json_decode($v['style'],true);
- $width=round($param['screenWidth']/$v['style']['backdrop']['width'],2);
- $v['width']=$width;
- foreach ($v['style'] as $key=>$item){
- if(is_array($item)){
- foreach ($item as $i=>$y){
- if($i!='color'&&$i!='src'&&$i!='style'&&$i!='display'&&$i!='type'||is_array($y)){
- if(is_array($y)&&count($y)){
- foreach ($y as $u=>$n){
- if($u!='color'&&$u!='src'&&$u!='style'&&$n!=0){
- $data[$l]['style'][$key][$i][$u]= round($n*$width,2);
- }else{
- $data[$l]['style'][$key][$i][$u]=$n;
- }
- }
- }else{
- $data[$l]['style'][$key][$i]= round($y*$width,2);
- }
- }else{
- $data[$l]['style'][$key][$i]=$y;
- }
- }
- }else{
- $data[$l]['style'][$key]=$item;
+ $param = $this->request->param();
+ $list = $model->lists($param);
+
+ // 获取屏幕宽度
+ $screenWidth = isset($param['screenWidth']) ? floatval($param['screenWidth']) : 375;
+
+ foreach($list as $index => $item) {
+ // 解析style JSON
+ $style = json_decode($item['style'], true);
+
+ if (!$style) {
+ $list[$index]['style'] = [];
+ continue;
+ }
+
+ // 计算缩放比例 (基于背景图宽度)
+ $backdropWidth = isset($style['backdrop']['width']) && $style['backdrop']['width'] > 0
+ ? floatval($style['backdrop']['width'])
+ : 375;
+
+ $scale = round($screenWidth / $backdropWidth, 4);
+
+ // 需要缩放的数值字段(排除这些字段名)
+ $excludeKeys = ['color', 'src', 'style', 'display', 'type', 'src'];
+
+ // 递归处理style数组,对所有数值字段进行缩放
+ $this->scaleStyleValues($style, $scale, $excludeKeys);
+
+ $list[$index]['style'] = $style;
+ }
+
+ return $this->renderSuccess('', $list);
+ }
+
+ /**
+ * 递归缩放style中的数值字段
+ * @param array &$data 数据数组(引用传递)
+ * @param float $scale 缩放比例
+ * @param array $excludeKeys 不需要缩放的键名
+ */
+ private function scaleStyleValues(&$data, $scale, $excludeKeys = [])
+ {
+ if (!is_array($data)) {
+ return;
+ }
+
+ foreach ($data as $key => &$value) {
+ if (is_array($value)) {
+ // 递归处理子数组
+ $this->scaleStyleValues($value, $scale, $excludeKeys);
+ } elseif (is_numeric($value) && !in_array($key, $excludeKeys)) {
+ // 对数值进行缩放(非0值)
+ if ($value != 0) {
+ $value = round($value * $scale, 2);
}
}
+ // 其他类型(字符串等)保持不变
}
- foreach ($data as $l=>$v ){
- $list[$l]['style']=$v['style'];
- }
- return $this->renderSuccess('',$list);
}
/**
diff --git a/admin/app/api/model/plus/operations/Operations.php b/admin/app/api/model/plus/operations/Operations.php
new file mode 100644
index 0000000..afe5d4e
--- /dev/null
+++ b/admin/app/api/model/plus/operations/Operations.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace app\api\model\plus\operations;
+use app\common\model\plus\operations\Operations as OperationsModel;
+/**
+ * 运营中心用户模型
+ */
+class Operations extends OperationsModel
+{
+ public static function getOrderOperations($order)
+ {
+ $model = new self;
+ $province_id=0;
+ $city_id=0;
+ $area_id=0;
+ if ($order['delivery_type']['value'] == 10){
+ $province_id=$order['address']['province_id'];
+ $city_id=$order['address']['city_id'];
+ $area_id=$order['address']['region_id'];
+ }else if($order['delivery_type']['value'] == 20||$order['delivery_type']['value'] == 40){
+ $province_id=$order['extractStore']['province_id'];
+ $city_id=$order['extractStore']['city_id'];
+ $area_id=$order['extractStore']['region_id'];
+ }
+ $province=$model->where('province_id', $province_id)->where(['operations_level'=>1])->find();
+ $city=$model->where('city_id', $city_id)->where(['operations_level'=>2])->find();
+ $area=$model->where('area_id', $area_id)->where(['operations_level'=>3])->find();
+ $data=['province_user_id'=>0,'city_user_id'=>0,'area_user_id'=>0];
+ if ($province){
+ $data['province_user_id']=$province['user_id'];
+ }
+ if($city){
+ $data['city_user_id']=$city['user_id'];
+ }
+ if($area){
+ $data['area_user_id']=$area['user_id'];
+ }
+ return $data;
+ }
+}
\ No newline at end of file
diff --git a/admin/app/api/model/plus/operations/Order.php b/admin/app/api/model/plus/operations/Order.php
new file mode 100644
index 0000000..dd5063d
--- /dev/null
+++ b/admin/app/api/model/plus/operations/Order.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace app\api\model\plus\operations;
+
+use app\common\model\plus\operations\Order as OrderModel;
+use app\common\service\order\OrderService;
+
+/**
+ * 运营中心订单模型
+ */
+class Order extends OrderModel
+{
+ /**
+ * 隐藏字段
+ */
+ protected $hidden = [
+ 'update_time',
+ ];
+
+ /**
+ * 获取运营中心订单列表
+ */
+ public function getList($user_id, $is_settled = -1)
+ {
+ $model = $this;
+ $is_settled > -1 && $model = $model->where('is_settled', '=', !!$is_settled);
+ $data = $model->with(['user'])
+ ->where('first_user_id|second_user_id|third_user_id', '=', $user_id)
+ ->order(['create_time' => 'desc'])
+ ->paginate(15);
+ if ($data->isEmpty()) {
+ return $data;
+ }
+ // 整理订单信息
+ $with = ['product' => ['image', 'refund'], 'address', 'user'];
+ return OrderService::getOrderList($data, 'order_master', $with);
+ }
+
+}
diff --git a/admin/app/api/model/plus/operations/Setting.php b/admin/app/api/model/plus/operations/Setting.php
new file mode 100644
index 0000000..3b9ecd6
--- /dev/null
+++ b/admin/app/api/model/plus/operations/Setting.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace app\api\model\plus\operations;
+use app\common\model\plus\operations\Setting as SettingModel;
+/**
+ * 运营中心设置模型
+ */
+class Setting extends SettingModel
+{
+
+}
\ No newline at end of file
diff --git a/admin/app/api/service/order/paysuccess/type/MasterPaySuccessService.php b/admin/app/api/service/order/paysuccess/type/MasterPaySuccessService.php
index 509392b..6f67056 100644
--- a/admin/app/api/service/order/paysuccess/type/MasterPaySuccessService.php
+++ b/admin/app/api/service/order/paysuccess/type/MasterPaySuccessService.php
@@ -20,7 +20,7 @@
use app\api\model\settings\Setting as SettingModel;
use app\common\model\supplier\Supplier as SupplierModel;
use app\common\model\plus\vip\Order as VipOrderModel;
-
+use app\api\model\plus\operations\Order as OperationsOrderModel;
/**
* 订单支付成功服务类
*/
@@ -107,6 +107,8 @@
TeamOrderModel::createOrder($detail);
// 记录VIP专区订单
VipOrderModel::createOrder($detail);
+ // 记录VIP专区订单
+ OperationsOrderModel::createOrder($detail);
event('PaySuccess', $detail);
}
diff --git a/admin/app/common/model/plus/operations/Order.php b/admin/app/common/model/plus/operations/Order.php
new file mode 100644
index 0000000..9e0c29e
--- /dev/null
+++ b/admin/app/common/model/plus/operations/Order.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace app\common\model\plus\operations;
+use app\common\enum\order\OrderTypeEnum;
+use app\common\model\BaseModel;
+use app\common\model\settings\Setting as SettingModel;
+use app\common\model\plus\operations\Operations as OperationsModel;
+/**
+ * 运营中心订单管理
+ */
+class Order extends BaseModel
+{
+ protected $name="operations_order";
+
+ /**
+ * 订单所属用户
+ * @return \think\model\relation\BelongsTo
+ */
+ public function user()
+ {
+ return $this->belongsTo('app\common\model\user\User');
+ }
+
+ /**
+ * 一级分销商用户
+ * @return \think\model\relation\BelongsTo
+ */
+ public function agentFirst()
+ {
+ return $this->belongsTo('app\common\model\user\User', 'first_user_id');
+ }
+
+ /**
+ * 二级分销商用户
+ * @return \think\model\relation\BelongsTo
+ */
+ public function agentSecond()
+ {
+ return $this->belongsTo('app\common\model\user\User', 'second_user_id');
+ }
+
+ /**
+ * 三级分销商用户
+ * @return \think\model\relation\BelongsTo
+ */
+ public function agentThird()
+ {
+ return $this->belongsTo('app\common\model\user\User', 'third_user_id');
+ }
+
+ /**
+ * 订单类型
+ * @param $value
+ * @return array
+ */
+ public function getOrderTypeAttr($value)
+ {
+ $types = OrderTypeEnum::getTypeName();
+ return ['text' => $types[$value], 'value' => $value];
+ }
+
+ /**
+ * 订单详情
+ */
+ public static function getDetailByOrderId($orderId, $orderType)
+ {
+ return (new static())->where('order_id', '=', $orderId)
+ ->where('order_type', '=', $orderType)
+ ->find();
+ }
+ public static function grantMoney($order, $orderType = OrderTypeEnum::MASTER)
+ {
+ // 订单是否已完成
+ if ($order['order_status']['value'] != 30) {
+ return false;
+ }
+ // 分销订单详情
+ $model = self::getDetailByOrderId($order['order_id'], $orderType);
+ if (!$model || $model['is_settled'] == 1) {
+ return false;
+ }
+ // 佣金结算天数
+ $settleDays = Setting::getItem('settlement', $order['app_id'])['settle_days'];
+ // 写入结算时间
+ $deadlineTime = $model['settle_end_time'];
+ if($deadlineTime == 0){
+ $deadlineTime = $order['receipt_time'] + $settleDays * 86400;
+ $model->save([
+ 'settle_end_time' => $deadlineTime
+ ]);
+ }
+ if ($deadlineTime > time()) {
+ return false;
+ }
+
+ // 重新计算分销佣金
+ $capital = $model->getCapitalByOrder($order);
+ // 发放一级分销商佣金
+ $model['first_user_id'] > 0 && OperationsModel::grantMoney($model['first_user_id'], $capital['first_money']);
+ // 发放二级分销商佣金
+ $model['second_user_id'] > 0 && OperationsModel::grantMoney($model['second_user_id'], $capital['second_money']);
+ // 发放三级分销商佣金
+ $model['third_user_id'] > 0 && OperationsModel::grantMoney($model['third_user_id'], $capital['third_money']);
+ // 更新分销订单记录
+ $model->save([
+ 'order_price' => $capital['orderPrice'],
+ 'first_money' => $model['first_user_id'] > 0? $capital['first_money']:0,
+ 'second_money' => $model['second_user_id'] > 0? $capital['second_money']:0,
+ 'third_money' => $model['third_user_id'] > 0? $capital['third_money']:0,
+ 'is_settled' => 1,
+ 'settle_time' => time()
+ ]);
+ event('AgentUserGrade', $model['first_user_id']);
+ event('AgentUserGrade', $model['second_user_id']);
+ event('AgentUserGrade', $model['third_user_id']);
+ // 更新队长等级 by lyzflash
+ event('TeamUserGrade', $model['first_user_id']);
+ event('TeamUserGrade', $model['second_user_id']);
+ event('TeamUserGrade', $model['third_user_id']);
+ // 更新股东等级 by lyzflash
+ event('ShareholderUserGrade', $model['first_user_id']);
+ event('ShareholderUserGrade', $model['second_user_id']);
+ event('ShareholderUserGrade', $model['third_user_id']);
+ return true;
+ }
+ /**
+ * 获取订单分销佣金数据
+ * @param $order
+ * @param string $source
+ * @param array $operations
+ * @return array
+ */
+ protected function getCapitalByOrder($order, $source = 'create',$operations=[])
+ {
+ $setting = Setting::getItem('bonus', $order['app_id']);
+ // 分销订单佣金数据
+ $capital = [
+ // 订单总金额(不含运费)
+ 'orderPrice' => bcsub($order['pay_price'], $order['express_price'], 2),
+ // 一级分销佣金
+ 'first_money' => 0.00,
+ // 二级分销佣金
+ 'second_money' => 0.00,
+ // 三级分销佣金
+ 'third_money' => 0.00,
+ // 是否记录
+ 'is_record' => true
+ ];
+ $total_count = count($order['product']);
+ // 计算分销佣金
+ foreach ($order['product'] as $product) {
+ // 商品实付款金额
+ $productPrice = min($capital['orderPrice'], $product['total_pay_price']);
+ // 计算商品实际佣金
+ $productCapital = $this->calculateProductCapital($setting, $productPrice,$product);
+ // 累积分销佣金
+ $capital['first_money'] += $productCapital['first_money'];
+ $capital['second_money'] += $productCapital['second_money'];
+ $capital['third_money'] += $productCapital['third_money'];
+ }
+ return $capital;
+ }
+ /**
+ * 计算商品实际佣金 by yj
+ * @param $setting
+ * @param $productPrice
+ * @return float[]|int[]
+ */
+ private function calculateProductCapital($setting, $productPrice,$product)
+ {
+ $storeSetting=SettingModel::getItem('store', $product['app_id']);
+ $productMoney=bcmul($productPrice, bcdiv($storeSetting['commission_rate'],100,2), 2);
+ $capital['first_money'] = bcmul($productMoney, bcdiv($setting['province_ratio'],100,2), 2);
+ $capital['second_money'] = bcmul($productMoney, bcdiv($setting['city_ratio'],100,2), 2);
+ $capital['third_money'] = bcmul($productMoney, bcdiv($setting['area_ratio'],100,2), 2);
+ return $capital;
+ }
+}
\ No newline at end of file
diff --git a/admin/app/common/model/plus/operations/Setting.php b/admin/app/common/model/plus/operations/Setting.php
index f05739a..221eb15 100644
--- a/admin/app/common/model/plus/operations/Setting.php
+++ b/admin/app/common/model/plus/operations/Setting.php
@@ -1 +1 @@
-<?php
namespace app\common\model\plus\operations;
use app\common\model\BaseModel;
use think\facade\Cache;
/**
* 区域代理设置模型
*/
class Setting extends BaseModel
{
protected $name = 'region_setting';
protected $createTime = false;
/**
* 转义数组格式
* @param $value
* @return mixed
*/
public function getValuesAttr($value)
{
return json_decode($value, true);
}
/**
* 转义成json格式
* @param $value
* @return false|string
*/
public function setValuesAttr($value)
{
return json_encode($value);
}
/**
* 获取指定项设置
* @param $key
* @param null $app_id
* @return array|mixed
*/
public static function getItem($key, $app_id = null)
{
$data = static::getAll($app_id);
return isset($data[$key]) ? $data[$key]['values'] : [];
}
/**
* 获取区域代理设置
*/
public static function getAll($app_id = null)
{
$self = new static;
is_null($app_id) && $app_id = $self::$app_id;
if (!$data = Cache::get('region_setting_' . $app_id)) {
$data = array_column($self->select()->toArray(), null, 'key');
Cache::tag('cache')->set('region_setting_' . $app_id, $data);
}
return array_merge_multiple($self->defaultData(), $data);
}
/**
* 获取设置项信息
*/
public static function detail($key)
{
return (new static())->find(compact('key'));
}
/**
* 是否开启分销功能
*/
public static function isOpen($app_id = null)
{
return static::getItem('basic', $app_id)['is_open'];
}
/**
* 分销中心页面名称
*/
public static function getregionTitle($app_id = null)
{
return static::getItem('words', $app_id)['index']['title']['value'];
}
/**
* 默认配置
*/
public function defaultData()
{
return [
'basic' => [
'key' => 'basic',
'describe' => '基础设置',
'values' => [
// 是否开启分红功能
'is_open' => '0', // 参数值:1开启 0关闭
//'jcaward' => '0', //级差奖
'pjaward' => '0', //平级奖
'pjaward_level' => '1', //平级奖奖励层级,默认往上1级
'become' => '10',
'total_rate' => '0',
// 分红结算方式
'bonus_type' => '20', // 10按周 20按月 30按年
'total_team_user' => 0, // 团队总人数
'self_buy_money' => 0, // 累计团队业绩是是否计算个人业绩
'one_expend_money' => 0, // 个人一次性消费
// 购买指定商品成为分销商 0关闭 1开启
'become__buy_product' => '0',
// 购买指定商品的id集
'become__buy_product_ids' => [],
'province_condition' => 0,
'city_condition' => 0,
'area_condition' => 0
],
],
'condition' => [
'key' => 'condition',
'describe' => '区域代理条件',
'values' => [
// 成为区域代理条件
'become' => '10', // 参数值:10填写申请信息(需后台审核) 20填写申请信息(无需审核)
// 购买指定商品成为区域代理 0关闭 1开启
'become__buy_product' => '0',
// 购买指定商品的id集
'become__buy_product_ids' => [],
]
],
'bonus' => [
'key' => 'bonus',
'describe' => '分红设置',
'values' => [
// 一级佣金
'province_ratio' => '0',
// 一级佣金
'city_ratio' => '0',
// 一级佣金
'area_ratio' => '0',
]
],
'settlement' => [
'key' => 'settlement',
'describe' => '结算',
'values' => [
// 提现方式
'pay_type' => [], // 参数值:10微信支付 20支付宝支付 30银行卡支付
// 微信支付自动打款
'wechat_pay_auto' => '0', // 微信支付自动打款:1开启 0关闭
'fee_rate' => 0, //手续费
// 最低提现额度
'min_money' => '10.00',
// 分红结算天数
'settle_days' => '10',
]
],
'words' => [
'key' => 'words',
'describe' => '自定义文字',
'values' => [
'index' => [
'title' => [
'default' => '区域代理',
'value' => '区域代理'
],
'words' => [
'region' => [
'default' => '区域代理',
'value' => '区域代理'
],
'not_region' => [
'default' => '很抱歉,您还不是区域代理',
'value' => '很抱歉,您还不是区域代理'
],
'apply_now' => [
'default' => '立即加入',
'value' => '立即加入'
],
'referee' => [
'default' => '推荐人',
'value' => '推荐人'
],
'money' => [
'default' => '可提现分红',
'value' => '可提现'
],
'freeze_money' => [
'default' => '待提现分红',
'value' => '待提现'
],
'total_money' => [
'default' => '已提现金额',
'value' => '已提现金额'
],
'cash' => [
'default' => '去提现',
'value' => '去提现'
],
]
],
'apply' => [
'title' => [
'default' => '申请成为区域代理',
'value' => '申请成为区域代理'
],
'words' => [
'title' => [
'default' => '请填写申请信息',
'value' => '请填写申请信息'
],
'license' => [
'default' => '区域代理申请协议',
'value' => '区域代理申请协议'
],
'submit' => [
'default' => '申请成为区域代理',
'value' => '申请成为区域代理'
],
'wait_audit' => [
'default' => '您的申请已受理,正在进行信息核验,请耐心等待。',
'value' => '您的申请已受理,正在进行信息核验,请耐心等待。'
],
'goto_mall' => [
'default' => '去商城逛逛',
'value' => '去商城逛逛'
],
'not_pass' => [
'default' => '很抱歉,您未达到申请条件',
'value' => '很抱歉,您未达到申请条件'
],
]
],
'bonus_list' => [
'title' => [
'default' => '结算明细',
'value' => '结算明细'
],
'words' => [
]
],
'cash_list' => [
'title' => [
'default' => '提现明细',
'value' => '提现明细'
],
'words' => [
'all' => [
'default' => '全部',
'value' => '全部'
],
'apply_10' => [
'default' => '审核中',
'value' => '审核中'
],
'apply_20' => [
'default' => '审核通过',
'value' => '审核通过'
],
'apply_40' => [
'default' => '已打款',
'value' => '已打款'
],
'apply_30' => [
'default' => '驳回',
'value' => '驳回'
],
]
],
'cash_apply' => [
'title' => [
'default' => '申请提现',
'value' => '申请提现'
],
'words' => [
'capital' => [
'default' => '可提现分红',
'value' => '可提现分红'
],
'money' => [
'default' => '提现金额',
'value' => '提现金额'
],
'money_placeholder' => [
'default' => '请输入要提取的金额',
'value' => '请输入要提取的金额'
],
'min_money' => [
'default' => '最低提现分红',
'value' => '最低提现分红'
],
'submit' => [
'default' => '提交申请',
'value' => '提交申请'
],
]
],
]
],
'license' => [
'key' => 'license',
'describe' => '申请协议',
'values' => [
'license' => ''
]
],
'background' => [
'key' => 'background',
'describe' => '页面背景图',
'values' => [
// 分销中心首页
'index' => self::$base_url . 'image/region/region-bg.jpg',
// 申请成为区域代理页
'apply' => self::$base_url . 'image/region/region-bg.jpg',
// 申请提现页
'cash_apply' => self::$base_url . 'image/region/region-bg.jpg',
// 权益说明
'description' => self::$base_url . 'image/region/description.png',
],
],
'template_msg' => [
'key' => 'template_msg',
'describe' => '模板消息',
'values' => [
'apply_tpl' => '', // 区域代理审核通知
'cash_tpl' => '', // 提现状态通知
]
],
];
}
}
\ No newline at end of file
+<?php
namespace app\common\model\plus\operations;
use app\common\model\BaseModel;
use think\facade\Cache;
/**
* 区域代理设置模型
*/
class Setting extends BaseModel
{
protected $name = 'operations_setting';
protected $createTime = false;
/**
* 转义数组格式
* @param $value
* @return mixed
*/
public function getValuesAttr($value)
{
return json_decode($value, true);
}
/**
* 转义成json格式
* @param $value
* @return false|string
*/
public function setValuesAttr($value)
{
return json_encode($value);
}
/**
* 获取指定项设置
* @param $key
* @param null $app_id
* @return array|mixed
*/
public static function getItem($key, $app_id = null)
{
$data = static::getAll($app_id);
return isset($data[$key]) ? $data[$key]['values'] : [];
}
/**
* 获取区域代理设置
*/
public static function getAll($app_id = null)
{
$self = new static;
is_null($app_id) && $app_id = $self::$app_id;
if (!$data = Cache::get('region_setting_' . $app_id)) {
$data = array_column($self->select()->toArray(), null, 'key');
Cache::tag('cache')->set('region_setting_' . $app_id, $data);
}
return array_merge_multiple($self->defaultData(), $data);
}
/**
* 获取设置项信息
*/
public static function detail($key)
{
return (new static())->find(compact('key'));
}
/**
* 是否开启分销功能
*/
public static function isOpen($app_id = null)
{
return static::getItem('basic', $app_id)['is_open'];
}
/**
* 分销中心页面名称
*/
public static function getregionTitle($app_id = null)
{
return static::getItem('words', $app_id)['index']['title']['value'];
}
/**
* 默认配置
*/
public function defaultData()
{
return [
'basic' => [
'key' => 'basic',
'describe' => '基础设置',
'values' => [
// 是否开启分红功能
'is_open' => '0', // 参数值:1开启 0关闭
//'jcaward' => '0', //级差奖
'pjaward' => '0', //平级奖
'pjaward_level' => '1', //平级奖奖励层级,默认往上1级
'become' => '10',
'total_rate' => '0',
// 分红结算方式
'bonus_type' => '20', // 10按周 20按月 30按年
'total_team_user' => 0, // 团队总人数
'self_buy_money' => 0, // 累计团队业绩是是否计算个人业绩
'one_expend_money' => 0, // 个人一次性消费
// 购买指定商品成为分销商 0关闭 1开启
'become__buy_product' => '0',
// 购买指定商品的id集
'become__buy_product_ids' => [],
'province_condition' => 0,
'city_condition' => 0,
'area_condition' => 0
],
],
'condition' => [
'key' => 'condition',
'describe' => '运营中心条件',
'values' => [
// 成为区域代理条件
'become' => '10', // 参数值:10填写申请信息(需后台审核) 20填写申请信息(无需审核)
// 购买指定商品成为区域代理 0关闭 1开启
'become__buy_product' => '0',
// 购买指定商品的id集
'become__buy_product_ids' => [],
]
],
'bonus' => [
'key' => 'bonus',
'describe' => '抽成设置',
'values' => [
// 一级佣金
'province_ratio' => '0',
// 一级佣金
'city_ratio' => '0',
// 一级佣金
'area_ratio' => '0',
]
],
'settlement' => [
'key' => 'settlement',
'describe' => '结算',
'values' => [
// 提现方式
'pay_type' => [], // 参数值:10微信支付 20支付宝支付 30银行卡支付
// 微信支付自动打款
'wechat_pay_auto' => '0', // 微信支付自动打款:1开启 0关闭
'fee_rate' => 0, //手续费
// 最低提现额度
'min_money' => '10.00',
// 分红结算天数
'settle_days' => '10',
]
],
'words' => [
'key' => 'words',
'describe' => '自定义文字',
'values' => [
'index' => [
'title' => [
'default' => '运营中心',
'value' => '运营中心'
],
'words' => [
'region' => [
'default' => '运营中心',
'value' => '运营中心'
],
'not_region' => [
'default' => '很抱歉,您还不是运营中心',
'value' => '很抱歉,您还不是运营中心'
],
'apply_now' => [
'default' => '立即加入',
'value' => '立即加入'
],
'referee' => [
'default' => '推荐人',
'value' => '推荐人'
],
'money' => [
'default' => '可提现分红',
'value' => '可提现'
],
'freeze_money' => [
'default' => '待提现分红',
'value' => '待提现'
],
'total_money' => [
'default' => '已提现金额',
'value' => '已提现金额'
],
'cash' => [
'default' => '去提现',
'value' => '去提现'
],
]
],
'apply' => [
'title' => [
'default' => '申请成为运营中心',
'value' => '申请成为运营中心'
],
'words' => [
'title' => [
'default' => '请填写申请信息',
'value' => '请填写申请信息'
],
'license' => [
'default' => '运营中心申请协议',
'value' => '运营中心申请协议'
],
'submit' => [
'default' => '申请成为运营中心',
'value' => '申请成为运营中心'
],
'wait_audit' => [
'default' => '您的申请已受理,正在进行信息核验,请耐心等待。',
'value' => '您的申请已受理,正在进行信息核验,请耐心等待。'
],
'goto_mall' => [
'default' => '去商城逛逛',
'value' => '去商城逛逛'
],
'not_pass' => [
'default' => '很抱歉,您未达到申请条件',
'value' => '很抱歉,您未达到申请条件'
],
]
],
'bonus_list' => [
'title' => [
'default' => '结算明细',
'value' => '结算明细'
],
'words' => [
]
],
'cash_list' => [
'title' => [
'default' => '提现明细',
'value' => '提现明细'
],
'words' => [
'all' => [
'default' => '全部',
'value' => '全部'
],
'apply_10' => [
'default' => '审核中',
'value' => '审核中'
],
'apply_20' => [
'default' => '审核通过',
'value' => '审核通过'
],
'apply_40' => [
'default' => '已打款',
'value' => '已打款'
],
'apply_30' => [
'default' => '驳回',
'value' => '驳回'
],
]
],
'cash_apply' => [
'title' => [
'default' => '申请提现',
'value' => '申请提现'
],
'words' => [
'capital' => [
'default' => '可提现分红',
'value' => '可提现分红'
],
'money' => [
'default' => '提现金额',
'value' => '提现金额'
],
'money_placeholder' => [
'default' => '请输入要提取的金额',
'value' => '请输入要提取的金额'
],
'min_money' => [
'default' => '最低提现分红',
'value' => '最低提现分红'
],
'submit' => [
'default' => '提交申请',
'value' => '提交申请'
],
]
],
]
],
'license' => [
'key' => 'license',
'describe' => '申请协议',
'values' => [
'license' => ''
]
],
'background' => [
'key' => 'background',
'describe' => '页面背景图',
'values' => [
// 分销中心首页
'index' => self::$base_url . 'image/region/region-bg.jpg',
// 申请成为区域代理页
'apply' => self::$base_url . 'image/region/region-bg.jpg',
// 申请提现页
'cash_apply' => self::$base_url . 'image/region/region-bg.jpg',
// 权益说明
'description' => self::$base_url . 'image/region/description.png',
],
],
'template_msg' => [
'key' => 'template_msg',
'describe' => '模板消息',
'values' => [
'apply_tpl' => '', // 区域代理审核通知
'cash_tpl' => '', // 提现状态通知
]
],
];
}
}
\ No newline at end of file
diff --git a/admin/app/common/service/business/Poster.php b/admin/app/common/service/business/Poster.php
index 1db14ca..374b465 100644
--- a/admin/app/common/service/business/Poster.php
+++ b/admin/app/common/service/business/Poster.php
@@ -113,13 +113,31 @@
private function savePoster($backdrop, $avatarUrl, $imageUrl, $logo)
{
- // 创建画布
- list($width, $height) = getimagesize($backdrop);
+ // 获取背景图信息,判断图片类型
+ $backdropInfo = getimagesize($backdrop);
+ $width = $backdropInfo[0];
+ $height = $backdropInfo[1];
+
+ // 根据原图类型创建对应类型的画布,提高质量
+ $imageType = $backdropInfo[2];
+
+ // 创建真彩色画布,确保足够的色彩深度
$newImage = imagecreatetruecolor($width, $height);
- $backdropIm = $this->imagEcr($backdrop);
+
+ // 启用抗锯齿
imageantialias($newImage, true);
- // 将第一张图片覆盖在新图像上
- imagecopy($newImage, $backdropIm, 0, 0, 0, 0, $width, $height);
+
+ // 启用alpha混合模式,确保透明度正常
+ imagealphablending($newImage, true);
+
+ // 保存透明度
+ imagesavealpha($newImage, true);
+
+ // 加载背景图
+ $backdropIm = $this->imagEcr($backdrop);
+
+ // 将背景图复制到画布(使用更好的插值方法)
+ imagecopyresampled($newImage, $backdropIm, 0, 0, 0, 0, $width, $height, $width, $height);
if (!empty($this->config['icon'])) {
foreach ($this->config['icon'] as $key => $value) {
$this->addImagecopy($newImage, $value);
@@ -127,9 +145,6 @@
}
// 脱敏处理
if($this->businessName=='desensitization'){
- // 保存原始数据以便后续可能需要使用
- $originalDealer = $this->dealer;
-
// 手机号脱敏:保留前3位和后4位
if(!empty($this->dealer['mobile'])){
$this->dealer['mobile'] = $this->maskPhoneNumber($this->dealer['mobile']);
@@ -167,6 +182,7 @@
$avatarY = $this->config['avatar']['top'];
// 打开用户头像
$avatarIm = $this->imagEcr($avatarUrl);
+ // 使用更好的插值方法复制头像(使用imagecopy保持原有质量)
imagecopy($newImage, $avatarIm, $avatarX, $avatarY, 0, 0, $avatarWidth, $avatarWidth);
}
if (is_file($logo) && $this->config['logo']['display'] == 1) {
@@ -182,43 +198,109 @@
$logoY = $this->config['logo']['top'];
// 打开用户logo
$logoImage = $this->imagEcr($logo);
+ // 使用更好的插值方法复制logo(使用imagecopy保持原有质量)
imagecopy($newImage, $logoImage, $logoX, $logoY, 0, 0, $logoWidth, $logoHeight);
}
// 写入用户昵称
- $this->addText($newImage, 'name');
+ $this->addText($newImage, 'name', '', 0, false, $width);
+ // 写入公司列表
+ $unitBaseTop = 0;
+ $unitFontSize = $this->config['unit'][0]['fontSize'];
foreach ($this->dealer['unit'] as $key => $value) {
- // 写入公司
- $this->addText($newImage, 'unit', '', $key, true);
+ if($key > 0){
+ $this->config['unit'][$key] = $this->config['unit'][0];
+ // 计算偏移量:每个公司增加基于前一个公司实际行数的距离
+ $this->config['unit'][$key]['top'] = $this->config['unit'][0]['top'] + $unitBaseTop;
+ }
+ // 写入公司,获取实际占用的行数
+ $lineCount = $this->addText($newImage, 'unit', '', $key, true, $width);
+ // 计算下一个公司的偏移量:(行数 - 1) * 行高 + 行间距
+ $unitLineHeight = $this->getLineHeight($unitFontSize);
+ $unitLineSpacing = $this->getLineSpacing($unitFontSize);
+ if ($key > 0) {
+ $unitBaseTop += ($lineCount * $unitLineHeight) + $unitLineSpacing;
+ } else {
+ $unitBaseTop = ($lineCount * $unitLineHeight) + $unitLineSpacing;
+ }
}
+ // 写入职位列表
if (!empty($this->dealer['duties']) && !empty($this->config['duties'])) {
- // 写入职位
- $this->addText($newImage, 'duties');
+ $dutiesBaseTop = 0;
+ $dutiesFontSize = $this->config['duties'][0]['fontSize'];
+ foreach ($this->dealer['duties'] as $key => $value) {
+ if($key > 0){
+ $this->config['duties'][$key] = $this->config['duties'][0];
+ // 计算偏移量:每个职位增加基于前一个职位实际行数的距离
+ $this->config['duties'][$key]['top'] = $this->config['duties'][0]['top'] + $dutiesBaseTop;
+ }
+ // 写入职位,获取实际占用的行数
+ $lineCount = $this->addText($newImage, 'duties','', $key, true, $width);
+ // 计算下一个职位的偏移量:(行数 - 1) * 行高 + 行间距
+ $dutiesLineHeight = $this->getLineHeight($dutiesFontSize);
+ $dutiesLineSpacing = $this->getLineSpacing($dutiesFontSize);
+ if ($key > 0) {
+ $dutiesBaseTop += ($lineCount * $dutiesLineHeight) + $dutiesLineSpacing;
+ } else {
+ $dutiesBaseTop = ($lineCount * $dutiesLineHeight) + $dutiesLineSpacing;
+ }
+ }
}
-
+
+ // 写入position列表(备用字段)
if (!empty($this->dealer['position']) && !empty($this->config['position'])) {
+ $positionBaseTop = 0;
+ $positionFontSize = $this->config['position'][0]['fontSize'];
foreach ($this->dealer['position'] as $key => $value) {
- // 写入公司
- $this->addText($newImage, 'position', '', $key, true);
+ if($key > 0){
+ $this->config['position'][$key] = $this->config['position'][0];
+ // 计算偏移量:每个position增加基于前一个实际行数的距离
+ $this->config['position'][$key]['top'] = $this->config['position'][0]['top'] + $positionBaseTop;
+ }
+ // 写入position,获取实际占用的行数
+ $lineCount = $this->addText($newImage, 'position', '', $key, true, $width);
+ // 计算下一个position的偏移量:(行数 - 1) * 行高 + 行间距
+ $positionLineHeight = $this->getLineHeight($positionFontSize);
+ $positionLineSpacing = $this->getLineSpacing($positionFontSize);
+ if ($key > 0) {
+ $positionBaseTop += ($lineCount * $positionLineHeight) + $positionLineSpacing;
+ } else {
+ $positionBaseTop = ($lineCount * $positionLineHeight) + $positionLineSpacing;
+ }
}
}
// 写入手机号
- $this->addText($newImage, 'mobile', '手机:');
+ $this->addText($newImage, 'mobile', '手机:', 0, false, $width);
if (!empty($this->dealer['wechat']) && !empty($this->config['wechat'])) {
// 写入微信
- $this->addText($newImage, 'wechat', '微信:');
+ $this->addText($newImage, 'wechat', '微信:', 0, false, $width);
}
// 写入邮箱
if ($this->dealer['mailbox']) {
// 写入邮箱
- $this->addText($newImage, 'mailbox', '邮箱:');
+ $this->addText($newImage, 'mailbox', '邮箱:', 0, false, $width);
}
if ($this->dealer['phone']) {
- $this->addText($newImage, 'phone', '电话:');
+ $this->addText($newImage, 'phone', '电话:', 0, false, $width);
}
// 保存图片
- imagejpeg($newImage, $this->getPosterPath($imageUrl),100); // 根据需要选择合适的函数(如imagepng、imagegif等)
+ // 根据背景图类型选择保存格式
+ $imageType = $backdropInfo[2];
+ $savePath = $this->getPosterPath($imageUrl);
+
+ if ($imageType == IMAGETYPE_PNG) {
+ // PNG格式,使用最高质量(9)
+ imagepng($newImage, $savePath, 9);
+ } elseif ($imageType == IMAGETYPE_GIF) {
+ // GIF格式
+ imagegif($newImage, $savePath);
+ } else {
+ // JPEG格式,使用最高质量(100)
+ imagejpeg($newImage, $savePath, 100);
+ }
+
// 清理内存
imagedestroy($newImage);
+ imagedestroy($backdropIm);
return $this->getPosterUrl($imageUrl);
}
@@ -256,9 +338,9 @@
imagecopyresampled($targetImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); // 保存时使用最高质量
$ext = pathinfo($imageUrl, PATHINFO_EXTENSION);
if ($ext == 'png'){
- imagepng($targetImage, $imageUrl,0); // 根据需要选择合适的函数(如imagepng、imagegif等)
+ imagepng($targetImage, $imageUrl, 9); // PNG使用最高质量(9)
}else{
- imagejpeg($targetImage, $imageUrl,100);
+ imagejpeg($targetImage, $imageUrl, 100); // JPEG使用最高质量
}
// 清理内存
@@ -289,35 +371,42 @@
* @param $key
* @param $type
* @param $width
- * @return array|bool
+ * @return array|bool|int 返回实际占用的行数(仅对type=true时有效)
*/
public function addText($editor, $name, $text = '', $key = 0, $type = false, $width = 0)
{
$fontPath = $_SERVER['DOCUMENT_ROOT']. '/fonts/MSYH.TTC';
if ($type) {
- list($fontSize, $fontX,$fontY) = self::SizeLeftTop($this->config[$name][$key]['fontSize'], $this->config[$name][$key]['left'],$this->config[$name][$key]['top']);
- $colorResource=self::colorResource($this->config[$name][$key]['color'],$editor);
- return imagettftext($editor, $fontSize, 0, $fontX, $fontY, $colorResource, $fontPath, $text . $this->dealer[$name][$key]);
+ // 确保配置数组存在该索引,不存在则使用索引0
+ $configKey = isset($this->config[$name][$key]) ? $key : 0;
+ list($fontSize, $fontX,$fontY) = self::SizeLeftTop($this->config[$name][$configKey]['fontSize'], $this->config[$name][$configKey]['left'],$this->config[$name][$configKey]['top']);
+ $colorResource=self::colorResource($this->config[$name][$configKey]['color'],$editor);
+ // 智能计算最大宽度
+ $maxWidth = $this->calculateFieldMaxWidth($this->config[$name][$configKey]['left'], $this->config[$name][$configKey]['top'], $width);
+ // 写入支持换行的文本
+ return $this->writeTextWithWrap($editor, $text . $this->dealer[$name][$key], $fontX, $fontY, $fontSize, $colorResource, $fontPath, $maxWidth);
} else if ($name == 'mobile') {
list($fontSize, $fontX,$fontY) = self::SizeLeftTop($this->config[$name]['fontSize'], $this->config[$name]['left'],$this->config[$name]['top']);
$text = $text . $this->dealer['mobile'];
-
+
if (!empty($this->dealer['mobile_phone'])) {
$text = $text . ' / ' . $this->dealer['mobile_phone'];
}
$colorResource=self::colorResource($this->config[$name]['color'],$editor);
- return imagettftext($editor, $fontSize, 0, $fontX, $fontY, $colorResource, $fontPath, $text);
+ // 智能计算最大宽度
+ $maxWidth = $this->calculateFieldMaxWidth($this->config[$name]['left'], $this->config[$name]['top'], $width);
+ // 写入支持换行的文本
+ $this->writeTextWithWrap($editor, $text, $fontX, $fontY, $fontSize, $colorResource, $fontPath, $maxWidth);
} else if ($name == 'duties') {
- list($fontSize, $fontX,$fontY) = self::SizeLeftTop($this->config[$name][$key]['fontSize'], $this->config[$name][$key]['left'],$this->config[$name][$key]['top']);
+ // 确保配置数组存在该索引,不存在则使用索引0
+ $configKey = isset($this->config[$name][$key]) ? $key : 0;
+ list($fontSize, $fontX,$fontY) = self::SizeLeftTop($this->config[$name][$configKey]['fontSize'], $this->config[$name][$configKey]['left'],$this->config[$name][$configKey]['top']);
$duties = $this->dealer['duties'][$key];
- if (!empty($this->dealer['duties'][1])) {
- $duties = $duties . ' / ' . $this->dealer['duties'][1];
- }
- if (!empty($this->dealer['duties'][2])) {
- $duties = $duties . ' / ' . $this->dealer['duties'][2];
- }
$colorResource=self::colorResource($this->config['duties'][0]['color'],$editor);
- return imagettftext($editor, $fontSize, 0, $fontX, $fontY, $colorResource, $fontPath, $text . $duties);
+ // 智能计算最大宽度
+ $maxWidth = $this->calculateFieldMaxWidth($this->config[$name][$configKey]['left'], $this->config[$name][$configKey]['top'], $width);
+ // 写入支持换行的文本
+ return $this->writeTextWithWrap($editor, $text . $duties, $fontX, $fontY, $fontSize, $colorResource, $fontPath, $maxWidth);
} else if ($name == 'address') {
list($fontSize, $fontX,$fontY) = self::SizeLeftTop($this->config[$name][$key]['fontSize'], $this->config[$name][$key]['left'],$this->config[$name][$key]['top']);
$title = $this->dealer['address'][0];
@@ -353,9 +442,11 @@
} else {
list($fontSize, $fontX,$fontY) = self::SizeLeftTop($this->config[$name]['fontSize'], $this->config[$name]['left'],$this->config[$name]['top']);
$colorResource=self::colorResource($this->config[$name]['color'],$editor);
- return imagettftext($editor, $fontSize, 0, $fontX, $fontY, $colorResource, $fontPath, $text . $this->dealer[$name]); // path/to/font.ttf为自定义字体路径
+ // 智能计算最大宽度
+ $maxWidth = $this->calculateFieldMaxWidth($this->config[$name]['left'], $this->config[$name]['top'], $width);
+ // 写入支持换行的文本
+ $this->writeTextWithWrap($editor, $text . $this->dealer[$name], $fontX, $fontY, $fontSize, $colorResource, $fontPath, $maxWidth);
}
-
}
/**
@@ -451,11 +542,10 @@
$areaCode = $parts[0]; // 区号
$number = end($parts); // 号码部分
$separator = strpos($phone, '-') !== false ? '-' : ' '; // 保持原始分隔符
-
+
$numLen = strlen($number);
if($numLen <= 4) return $phone; // 号码太短不脱敏
-
- $numPrefix = substr($number, 0, 0); // 号码部分前半段不显示
+
$numSuffix = substr($number, -4); // 保留号码后4位
$stars = str_repeat('*', $numLen - 4);
@@ -533,15 +623,200 @@
* @param $fontSize
* @param $left
* @param $top
- * @return array
+ * @return array [fontSizePt, left, top]
*/
private function SizeLeftTop($fontSize,$left,$top){
- // 正确的px到pt转换系数:1px = 0.75pt
- // 使用0.75而不是0.76以确保字体大小显示准确
- $data[0] = $fontSize * 0.75;
- $data[1] = (float)$left;
- $data[2] = (float)$top + $fontSize;
+ // px到pt转换系数:1px ≈ 0.75pt (GD库使用磅pt作为字体单位)
+ // 使用更精确的转换系数
+ $fontSizePt = $fontSize * 0.75;
+
+ // 调整top位置,使文字基线对齐
+ // imagettftext的y坐标是文字基线位置,不是文字顶部
+ // 需要加上字体大小来使文字显示在期望的位置
+ $data[0] = $fontSizePt; // 字体大小(pt)
+ $data[1] = (float)$left; // 左边距(px)
+ $data[2] = (float)$top + $fontSize; // 顶部位置(px),加字体大小以校正基线
return $data;
}
+ /**
+ * 获取文本实际高度
+ * @param $fontSizePx 字体大小(px)
+ * @return float 行高(px)
+ */
+ private function getLineHeight($fontSizePx) {
+ // 行高 = 字体大小 * 1.5 (更舒适的行间距)
+ return $fontSizePx * 1.5;
+ }
+
+ /**
+ * 获取行间距
+ * @param $fontSizePx 字体大小(px)
+ * @return float 行间距(px)
+ */
+ private function getLineSpacing($fontSizePx) {
+ // 行间距 = 字体大小 * 0.5 (50%的字体大小作为间距)
+ return $fontSizePx * 0.5;
+ }
+
+ /**
+ * 智能计算字段的最大宽度
+ * 根据右边是否有其他字段来动态计算maxWidth
+ * @param $left
+ * @param $top
+ * @param $backdropWidth
+ * @return float
+ */
+ private function calculateFieldMaxWidth($left, $top, $backdropWidth = 375)
+ {
+ $rightFields = [];
+ $tolerance = 20; // 容差:判断是否在同一行的像素范围
+
+ // 收集所有可能的字段
+ $fields = [];
+
+ // 公司
+ if (!empty($this->config['unit'][0])) {
+ $fields[] = [
+ 'name' => 'unit',
+ 'left' => $this->config['unit'][0]['left'],
+ 'top' => $this->config['unit'][0]['top']
+ ];
+ }
+
+ // 职位
+ if (!empty($this->config['duties'][0])) {
+ $fields[] = [
+ 'name' => 'duties',
+ 'left' => $this->config['duties'][0]['left'],
+ 'top' => $this->config['duties'][0]['top']
+ ];
+ }
+
+ // 姓名
+ if (!empty($this->config['name'])) {
+ $fields[] = [
+ 'name' => 'name',
+ 'left' => $this->config['name']['left'],
+ 'top' => $this->config['name']['top']
+ ];
+ }
+
+ // 地址
+ if (!empty($this->config['address'][0])) {
+ $fields[] = [
+ 'name' => 'address',
+ 'left' => $this->config['address'][0]['left'],
+ 'top' => $this->config['address'][0]['top']
+ ];
+ }
+
+ // 邮箱
+ if (!empty($this->config['mailbox'])) {
+ $fields[] = [
+ 'name' => 'mailbox',
+ 'left' => $this->config['mailbox']['left'],
+ 'top' => $this->config['mailbox']['top']
+ ];
+ }
+
+ // 手机
+ if (!empty($this->config['mobile'])) {
+ $fields[] = [
+ 'name' => 'mobile',
+ 'left' => $this->config['mobile']['left'],
+ 'top' => $this->config['mobile']['top']
+ ];
+ }
+
+ // 微信
+ if (!empty($this->config['wechat'])) {
+ $fields[] = [
+ 'name' => 'wechat',
+ 'left' => $this->config['wechat']['left'],
+ 'top' => $this->config['wechat']['top']
+ ];
+ }
+
+ // 电话
+ if (!empty($this->config['phone'])) {
+ $fields[] = [
+ 'name' => 'phone',
+ 'left' => $this->config['phone']['left'],
+ 'top' => $this->config['phone']['top']
+ ];
+ }
+
+ // 找出右边最近的字段
+ // 判断标准: left > 当前left, 且top在合理范围内(±20px)
+ foreach ($fields as $field) {
+ if ($field['left'] > $left && abs($field['top'] - $top) <= $tolerance) {
+ $rightFields[] = $field;
+ }
+ }
+
+ // 如果右边有字段,取最近的一个的左边距
+ if (count($rightFields) > 0) {
+ // 按left排序
+ usort($rightFields, function($a, $b) {
+ return $a['left'] - $b['left'];
+ });
+ return max($rightFields[0]['left'] - $left - 10, 50);
+ }
+
+ // 如果右边没有字段,使用名片边缘
+ return max($backdropWidth - $left - 10, 100);
+ }
+
+ /**
+ * 写入支持换行的文本
+ * @param $editor
+ * @param $text
+ * @param $x
+ * @param $y
+ * @param $fontSize
+ * @param $color
+ * @param $fontPath
+ * @param $maxWidth
+ * @return int 返回实际使用的行数
+ */
+ private function writeTextWithWrap($editor, $text, $x, $y, $fontSize, $color, $fontPath, $maxWidth)
+ {
+ $fontSizePt = $fontSize * 0.75; // px转pt
+ $lineHeight = $this->getLineHeight($fontSize); // 获取精确的行高
+ $lines = [];
+ $currentLine = '';
+
+ // 按字符分割文本
+ $chars = preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+ foreach ($chars as $char) {
+ $testLine = $currentLine . $char;
+ $bbox = imagettfbbox($fontSizePt, 0, $fontPath, $testLine);
+ $lineWidth = $bbox[2] - $bbox[0];
+
+ // 使用maxWidth减去一点边距,确保不超出边界
+ if ($lineWidth > $maxWidth - 2 && $currentLine !== '') {
+ $lines[] = $currentLine;
+ $currentLine = $char;
+ } else {
+ $currentLine = $testLine;
+ }
+ }
+
+ if ($currentLine !== '') {
+ $lines[] = $currentLine;
+ }
+
+ // 写入每一行
+ foreach ($lines as $index => $line) {
+ // 第一行使用原始y坐标,后续行加上行高偏移
+ $lineY = $y + ($index * $lineHeight);
+ imagettftext($editor, $fontSizePt, 0, $x, $lineY, $color, $fontPath, $line);
+ }
+
+ // 返回实际占用的行数
+ return count($lines);
+ }
+
}
\ No newline at end of file
diff --git a/admin/app/common/service/order/OrderCompleteService.php b/admin/app/common/service/order/OrderCompleteService.php
index b70d0d3..cdb66e5 100644
--- a/admin/app/common/service/order/OrderCompleteService.php
+++ b/admin/app/common/service/order/OrderCompleteService.php
@@ -26,7 +26,7 @@
use app\common\model\plus\shareholder\Setting as ShareholderSettingModel;
use app\common\model\plus\shareholder\Bonus as ShareholderBonusModel;
use app\common\model\plus\vip\Order as VipOrderModel;
-
+use app\common\model\plus\operations\Order as OperationsOrderModel;
/**
* 已完成订单结算服务类
*/
@@ -110,6 +110,8 @@
}
}
AgentOrderModel::grantMoney($order, $this->orderType);
+ // 发放运营中心佣金
+ OperationsOrderModel::grantMoney($order, $this->orderType);
// 发放团队分红 by yj
TeamOrderModel::grantMoney($order, $this->orderType);
// 发放会员分红
diff --git a/admin/app/event.php b/admin/app/event.php
index 8bb972a..71a8c0f 100644
--- a/admin/app/event.php
+++ b/admin/app/event.php
@@ -83,6 +83,10 @@
'VipUserGrade' => [
\app\job\event\VipUserGrade::class
],
+ /*运营中心订单*/
+ 'OperationsOrder' => [
+ \app\job\event\OperationsOrder::class
+ ],
],
'subscribe' => [
diff --git a/admin/app/job/event/JobScheduler.php b/admin/app/job/event/JobScheduler.php
index 6ad6376..84c3ed0 100644
--- a/admin/app/job/event/JobScheduler.php
+++ b/admin/app/job/event/JobScheduler.php
@@ -41,6 +41,8 @@
event('LiveRoom');
// 分会
event('Branch');
+ // 运营中心订单
+ event('OperationsOrder');
return true;
}
diff --git a/admin/app/job/event/OperationsOrder.php b/admin/app/job/event/OperationsOrder.php
new file mode 100644
index 0000000..e7391f4
--- /dev/null
+++ b/admin/app/job/event/OperationsOrder.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace app\job\event;
+
+use think\facade\Cache;
+use app\job\model\plus\operations\Order as OperationsOrderModel;
+
+/**
+ * 运营中心订单事件管理
+ */
+class OperationsOrder
+{
+ // 模型
+ private $model;
+
+ /**
+ * 执行函数
+ */
+ public function handle()
+ {
+ try {
+ $this->model = new OperationsOrderModel();
+ $cacheKey = "task_space_OperationsOrder";
+ if (!Cache::has($cacheKey)) {
+ $this->model->startTrans();
+ try {
+ // 发放运营中心订单佣金
+ $this->grantMoney();
+ $this->model->commit();
+ } catch (\Exception $e) {
+ $this->model->rollback();
+ }
+ Cache::set($cacheKey, time(), 60);
+ }
+ } catch (\Throwable $e) {
+ echo 'ERROR OperationsOrder: ' . $e->getMessage() . PHP_EOL;
+ log_write('OperationsOrder TASK : ' . '__ ' . $e->getMessage(), 'task');
+ }
+ return true;
+ }
+
+ /**
+ * 发放运营中心订单佣金
+ */
+ private function grantMoney()
+ {
+ // 获取未结算佣金的订单列表
+ $list = $this->model->getUnSettledList();
+ if ($list->isEmpty()) return false;
+ // 整理id集
+ $invalidIds = [];
+ $grantIds = [];
+ // 发放运营中心订单佣金
+ foreach ($list->toArray() as $item) {
+ // 已失效的订单
+ if ($item['order_master']['order_status']['value'] == 20) {
+ $invalidIds[] = $item['id'];
+ }
+ // 已完成的订单
+ if ($item['order_master']['order_status']['value'] == 30) {
+ $grantIds[] = $item['id'];
+ OperationsOrderModel::grantMoney($item['order_master'], $item['order_type']['value']);
+ }
+
+ }
+
+ // 标记已失效的订单
+ $this->model->setInvalid($invalidIds);
+
+ // 记录日志
+ $this->dologs('invalidIds', ['Ids' => $invalidIds]);
+ $this->dologs('grantMoney', ['Ids' => $grantIds]);
+ return true;
+ }
+
+ /**
+ * 记录日志
+ */
+ private function dologs($method, $params = [])
+ {
+ $value = 'behavior OperationsOrder --' . $method;
+ foreach ($params as $key => $val) {
+ $value .= ' --' . $key . ' ' . (is_array($val) ? json_encode($val) : $val);
+ }
+ return log_write($value, 'task');
+ }
+
+}
\ No newline at end of file
diff --git a/admin/app/job/model/plus/operations/Order.php b/admin/app/job/model/plus/operations/Order.php
new file mode 100644
index 0000000..0d739f8
--- /dev/null
+++ b/admin/app/job/model/plus/operations/Order.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace app\job\model\plus\operations;
+
+use app\common\model\plus\operations\Order as OrderModel;
+use app\common\service\order\OrderService;
+
+/**
+ * 运营中心订单模型
+ */
+class Order extends OrderModel
+{
+ /**
+ * 获取未结算的运营中心订单
+ */
+ public function getUnSettledList()
+ {
+ $list = $this->where('is_invalid', '=', 0)
+ ->where('is_settled', '=', 0)
+ ->select();
+ if ($list->isEmpty()) {
+ return $list;
+ }
+ // 整理订单信息
+ $with = ['product' => ['refund']];
+ return OrderService::getOrderList($list, 'order_master', $with);
+ }
+
+ /**
+ * 标记订单已失效(批量)
+ */
+ public function setInvalid($ids)
+ {
+ return $this->where('id', 'in', $ids)
+ ->save(['is_invalid' => 1]);
+ }
+
+}
\ No newline at end of file
diff --git a/admin/app/shop/controller/plus/operations/Operations.php b/admin/app/shop/controller/plus/operations/Operations.php
index 8546979..3817b98 100644
--- a/admin/app/shop/controller/plus/operations/Operations.php
+++ b/admin/app/shop/controller/plus/operations/Operations.php
@@ -7,7 +7,7 @@
use app\shop\model\plus\operations\Grade as GradeModel;
use app\shop\model\plus\agent\Referee as RefereeModel;
use app\shop\model\plus\operations\Setting as SettingModel;
-use app\shop\model\plus\operations\User as UserModel;
+use app\shop\model\plus\operations\operations as UserModel;
/**
* 分销控制器
diff --git a/admin/app/shop/controller/plus/operations/Order.php b/admin/app/shop/controller/plus/operations/Order.php
new file mode 100644
index 0000000..284ec88
--- /dev/null
+++ b/admin/app/shop/controller/plus/operations/Order.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace app\shop\controller\plus\operations;
+
+use app\shop\controller\Controller;
+use app\shop\model\plus\operations\Order as OrderModel;
+
+/**
+ * 运营中心订单
+ */
+class Order extends Controller
+{
+
+ /**
+ * 运营中心订单列表
+ */
+ public function index($user_id = null, $is_settled = -1, $list_rows = 15)
+ {
+ $model = new OrderModel;
+ $list = $model->getList($user_id, $is_settled, $list_rows);
+ return $this->renderSuccess('', compact('list'));
+ }
+
+ /**
+ * 订单导出
+ */
+ public function export($user_id = null, $is_settled = -1)
+ {
+ $model = new OrderModel();
+ return $model->exportList($user_id, $is_settled);
+ }
+
+}
diff --git a/admin/app/shop/service/order/ExportService.php b/admin/app/shop/service/order/ExportService.php
index ec07d02..4b4fdb2 100644
--- a/admin/app/shop/service/order/ExportService.php
+++ b/admin/app/shop/service/order/ExportService.php
@@ -181,6 +181,80 @@
}
/**
+ * 运营中心订单导出
+ */
+ public function operationsOrderList($list)
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+
+ //列宽
+ $sheet->getColumnDimension('B')->setWidth(30);
+
+ //设置工作表标题名称
+ $sheet->setTitle('运营中心订单明细');
+
+ $sheet->setCellValue('A1', '订单号');
+ $sheet->setCellValue('B1', '商品信息');
+ $sheet->setCellValue('C1', '订单总额');
+ $sheet->setCellValue('D1', '实付款金额');
+ $sheet->setCellValue('E1', '支付方式');
+ $sheet->setCellValue('F1', '下单时间');
+ $sheet->setCellValue('G1', '省级运营中心');
+ $sheet->setCellValue('H1', '省级佣金');
+ $sheet->setCellValue('I1', '市级运营中心');
+ $sheet->setCellValue('J1', '市级佣金');
+ $sheet->setCellValue('K1', '区级运营中心');
+ $sheet->setCellValue('L1', '区级佣金');
+ $sheet->setCellValue('M1', '买家');
+ $sheet->setCellValue('N1', '付款状态');
+ $sheet->setCellValue('O1', '付款时间');
+ $sheet->setCellValue('P1', '发货状态');
+ $sheet->setCellValue('Q1', '发货时间');
+ $sheet->setCellValue('R1', '收货状态');
+ $sheet->setCellValue('S1', '收货时间');
+ $sheet->setCellValue('T1', '订单状态');
+ $sheet->setCellValue('U1', '佣金结算');
+ $sheet->setCellValue('V1', '结算时间');
+ //填充数据
+ $index = 0;
+ foreach ($list as $operations) {
+ $order = $operations['order_master'];
+ $sheet->setCellValue('A' . ($index + 2), "\t" . $order['order_no'] . "\t");
+ $sheet->setCellValue('B' . ($index + 2), $this->filterProductInfo($order));
+ $sheet->setCellValue('C' . ($index + 2), $order['total_price']);
+ $sheet->setCellValue('D' . ($index + 2), $order['pay_price']);
+ $sheet->setCellValue('E' . ($index + 2), $order['pay_type']['text']);
+ $sheet->setCellValue('F' . ($index + 2), $order['create_time']);
+ $sheet->setCellValue('G' . ($index + 2), isset($operations['agent_first'])?$operations['agent_first']['nickName']:'');
+ $sheet->setCellValue('H' . ($index + 2), $operations['first_money']);
+ $sheet->setCellValue('I' . ($index + 2), isset($operations['agent_second'])?$operations['agent_second']['nickName']:'');
+ $sheet->setCellValue('J' . ($index + 2), $operations['second_money']);
+ $sheet->setCellValue('K' . ($index + 2), isset($operations['agent_third'])?$operations['agent_third']['nickName']:'');
+ $sheet->setCellValue('L' . ($index + 2), $operations['third_money']);
+ $sheet->setCellValue('M' . ($index + 2), $order['user']['nickName']);
+ $sheet->setCellValue('N' . ($index + 2), $order['pay_status']['text']);
+ $sheet->setCellValue('O' . ($index + 2), $this->filterTime($order['pay_time']));
+ $sheet->setCellValue('P' . ($index + 2), $order['delivery_status']['text']);
+ $sheet->setCellValue('Q' . ($index + 2), $this->filterTime($order['delivery_time']));
+ $sheet->setCellValue('R' . ($index + 2), $order['receipt_status']['text']);
+ $sheet->setCellValue('S' . ($index + 2), $this->filterTime($order['receipt_time']));
+ $sheet->setCellValue('T' . ($index + 2), $order['order_status']['text']);
+ $sheet->setCellValue('U' . ($index + 2), $operations['is_settled'] == 1 ? '已结算' : '未结算');
+ $sheet->setCellValue('V' . ($index + 2), $this->filterTime($operations['settle_time']));
+ $index++;
+ }
+
+ //保存文件
+ $filename = iconv("UTF-8", "GB2312//IGNORE", '运营中心订单') . '-' . date('YmdHis') . '.xlsx';
+ header('Content-Type: application/vnd.ms-excel');
+ header('Content-Disposition: attachment;filename="' . $filename . '"');
+ header('Cache-Control: max-age=0');
+ $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
+ $writer->save('php://output');
+ }
+
+ /**
* 提现订单导出
*/
public function cashList($list)
diff --git a/agent_vue/src/api/statistics.js b/agent_vue/src/api/statistics.js
index 857a865..cf5c811 100644
--- a/agent_vue/src/api/statistics.js
+++ b/agent_vue/src/api/statistics.js
@@ -3,47 +3,47 @@
let StatisticsApi = {
/*订单数据统计*/
getOrderTotal(data, errorback) {
- return request._post('/region/statistics.sales/index', data, errorback);
+ return request._post('/shop/statistics.sales/index', data, errorback);
},
- /*订单时间段统�?/
+ /*订单时间段统计*/
getOrderByDate(data, errorback) {
- return request._post('/region/statistics.sales/order', data, errorback);
+ return request._post('/shop/statistics.sales/order', data, errorback);
},
- /*商品时间段统�?/
+ /*商品时间段统计*/
getProductByDate(data, errorback) {
- return request._post('/region/statistics.sales/product', data, errorback);
+ return request._post('/shop/statistics.sales/product', data, errorback);
},
/*会员数据统计*/
getUserTotal(data, errorback) {
- return request._post('/region/statistics.user/index', data, errorback);
+ return request._post('/shop/statistics.user/index', data, errorback);
},
/*成交占比*/
getUserScale(data, errorback) {
- return request._post('/region/statistics.user/scale', data, errorback);
+ return request._post('/shop/statistics.user/scale', data, errorback);
},
/*新增会员*/
getNewUser(data, errorback) {
- return request._post('/region/statistics.user/new_user', data, errorback);
+ return request._post('/shop/statistics.user/new_user', data, errorback);
},
- /*成交会员�?/
+ /*成交会员数*/
getPayUser(data, errorback) {
- return request._post('/region/statistics.user/pay_user', data, errorback);
+ return request._post('/shop/statistics.user/pay_user', data, errorback);
},
- /*供应商统�?/
+ /*供应商统计*/
getSupplierTotal(data, errorback) {
- return request._post('/region/statistics.supplier/index', data, errorback);
+ return request._post('/shop/statistics.supplier/index', data, errorback);
},
/*供应商时间段统计*/
getSupplierByDate(data, errorback) {
- return request._post('/region/statistics.supplier/data', data, errorback);
+ return request._post('/shop/statistics.supplier/data', data, errorback);
},
/*访问统计*/
getAccessTotal(data, errorback) {
- return request._post('/region/statistics.access/index', data, errorback);
+ return request._post('/shop/statistics.access/index', data, errorback);
},
- /*访问时间段统�?/
+ /*访问时间段统计*/
getAccessByDate(data, errorback) {
- return request._post('/region/statistics.access/data', data, errorback);
+ return request._post('/shop/statistics.access/data', data, errorback);
},
}
diff --git a/agent_vue/src/filters/index.js b/agent_vue/src/filters/index.js
index 45fcb0f..ccfd910 100644
--- a/agent_vue/src/filters/index.js
+++ b/agent_vue/src/filters/index.js
@@ -5,7 +5,7 @@
return 'vip'+val;
},
- /*判断字段是否为空,为空的话先�?*/
+ /*判断字段是否为空,为空的话先说-*/
isNull:function(val){
if(val==null||val==undefined||val===""||val==="null"||val=='undefined'){
@@ -18,7 +18,7 @@
}
},
- /*百分�?/
+ /*百分比*/
returnPercentage:function(val){
if(val!==null&&val!==''&&val!==undefined){
let num=(val*100).toFixed(2);
@@ -28,7 +28,7 @@
}
},
- /*小数点后面保留位�?/
+ /*小数点后面保留位数*/
returnToFixed:function(val,num){
if(val!=null){
let nums=val.toFixed(num);
@@ -42,7 +42,7 @@
}
},
- /*取万�?/
+ /*取万元*/
tenThousand:function(val){
if(val!=null&&val!=''){
var x=(val/10000).toFixed(2);
@@ -54,7 +54,7 @@
}
},
- /*数字换成�?/
+ /*数字换成周*/
numTabWeek: function(val) {
let ch = '';
@@ -63,22 +63,22 @@
ch = '一';
break;
case 2:
- ch = '�?;
+ ch = '二';
break;
case 3:
- ch = '�?;
+ ch = '三';
break;
case 4:
- ch = '�?;
+ ch = '四';
break;
case 5:
- ch = '�?;
+ ch = '五';
break;
case 6:
- ch = '�?;
+ ch = '六';
break;
case 7:
- ch = '�?;
+ ch = '日';
break;
}
return ch;
@@ -90,10 +90,10 @@
let sex = '';
switch(num) {
case 0:
- sex = '�?;
+ sex = '女';
break;
case 1:
- sex= '�?;
+ sex= '男';
break;
default:
sex = '其他';
@@ -110,7 +110,7 @@
}
},
- /*判断有没有空�?/
+ /*判断有没有空格*/
hasSpace:function(val){
if(val!=undefined){
let patt=/\s/g;
@@ -130,7 +130,7 @@
}
},
- /*判断字符串是否全是空�?/
+ /*判断字符串是否全是空格*/
isAllSpace(val){
if(val.match(/^[ ]*$/)){
return true;
diff --git a/agent_vue/src/permission.js b/agent_vue/src/permission.js
index b83fb1e..31d6def 100644
--- a/agent_vue/src/permission.js
+++ b/agent_vue/src/permission.js
@@ -14,7 +14,7 @@
} from '@/utils/base'
const whiteList = ['/login', '/test', '/fonticon']
-// 在每个路由生效之前,先进行一些处理,请参�?vue-router官方文档-导航钩子
+// 在每个路由生效之前,先进行一些处理,请参考 vue-router官方文档-导航钩子
router.beforeEach((to, from, next) => {
const isLogin = getCookie('isLogin');
diff --git a/agent_vue/src/router/index.js b/agent_vue/src/router/index.js
index b30d1a9..b5d3e3a 100644
--- a/agent_vue/src/router/index.js
+++ b/agent_vue/src/router/index.js
@@ -151,7 +151,7 @@
}
]
},
- /*----代理商列�?---*/
+ /*----代理商列表----*/
{
path: '/agent',
redirect: { name: 'agent_Index' },
@@ -166,7 +166,7 @@
path: 'Index',
name: 'agent_Index',
meta: {
- title: '代理商管�?
+ title: '代理商管理'
},
component: () =>
import('@/views/agent/Index')
diff --git a/agent_vue/src/store/index.js b/agent_vue/src/store/index.js
index 6d76563..32ad212 100644
--- a/agent_vue/src/store/index.js
+++ b/agent_vue/src/store/index.js
@@ -67,7 +67,7 @@
generateRoutes: async function(context, str) {
/*返回理由*/
return new Promise((resolve, reject) => {
- /*判断本地缓存是否有菜单数�?/
+ /*判断本地缓存是否有菜单数据*/
if(res.status&&res.data){
let temps=null;
let accessRoutes=temps.concat(menu);
diff --git a/agent_vue/src/utils/base.js b/agent_vue/src/utils/base.js
index fc33494..5a3a52a 100644
--- a/agent_vue/src/utils/base.js
+++ b/agent_vue/src/utils/base.js
@@ -38,7 +38,7 @@
}
/*
- * 通过参数获取sessionStorage的数�?
+ * 通过参数获取sessionStorage的数据
*/
export const getSessionStorage = (name) => {
if(sessionStorage.hasOwnProperty(name)) {
@@ -49,7 +49,7 @@
}
/*
- * 附加sessionStorage, type==true 则是整个修改�?
+ * 附加sessionStorage, type==true 则是整个修改,
*/
export const addSessionStorage = (name, val) => {
if(sessionStorage.hasOwnProperty(name)) {
@@ -80,7 +80,7 @@
}
/*
- * 通过参数获取localStorage的数�?
+ * 通过参数获取localStorage的数据
*/
export const getLocalStorage = (name) => {
if(localStorage.hasOwnProperty(name)) {
@@ -91,7 +91,7 @@
}
/*
- * 附加localStorage, type==true 则是整个修改�?
+ * 附加localStorage, type==true 则是整个修改,
*/
export const addLocalStorage = (name, val) => {
if(localStorage.hasOwnProperty(name)) {
@@ -115,7 +115,7 @@
}
/*
- *深拷�?
+ *深拷贝
*/
export const deepClone = (obj) => {
var objClone = Array.isArray(obj) ? [] : {};
@@ -135,7 +135,7 @@
/*
- *深合�?
+ *深合并
*/
export const deepMerger = (obj1, obj2) => {
for (var key in obj2) {
diff --git a/agent_vue/src/utils/request.js b/agent_vue/src/utils/request.js
index 66bbe24..ddb432b 100644
--- a/agent_vue/src/utils/request.js
+++ b/agent_vue/src/utils/request.js
@@ -8,29 +8,29 @@
import { delCookie } from '@/utils/base.js';
//axios.defaults.timeout = 5000; //响应时间
-axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置请求�?
+axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置请求头
//axios.defaults.baseURL = 'http://www.jjj-shop.com/'; //配置接口地址
axios.defaults.baseURL = '/index.php'; //配置接口地址
axios.defaults.withCredentials = true;
axios.defaults.responseType = 'json';
-//POST传参序列�?添加请求拦截�?
+//POST传参序列化(添加请求拦截器)
axios.interceptors.request.use((config) => {
- //在发送请求之前做某件�?
+ //在发送请求之前做某件事
if (config.method === 'post') {
config.data = qs.stringify(config.data);
}
return config;
}, (error) => {
- console.log('错误的传�?)
+ console.log('错误的传参')
return Promise.reject(error);
});
-//返回状态判�?添加响应拦截�?
+//返回状态判断(添加响应拦截器)
axios.interceptors.response.use((res) => {
- //未登�?
+ //未登陆
if (res.data.code !== 1) {
- console.log('未登录状�?)
+ console.log('未登录状态')
if(res.data.code===0){
Message({
showClose: true,
diff --git a/mobile/pages/plus/business/add.vue b/mobile/pages/plus/business/add.vue
index f3e00fc..c2193c7 100644
--- a/mobile/pages/plus/business/add.vue
+++ b/mobile/pages/plus/business/add.vue
@@ -1,244 +1,293 @@
-<template>
- <view>
+ <template>
+ <view>
<form @submit="add">
- <view
- style="display: flex;justify-content: center;position: relative;overflow: hidden;border-radius: 30rpx;"
- v-for="(item,index) in templateList" v-if="item.template_id==template_id" :key="index">
- <view v-for="(item,index) in item.style.icon" :key="index"
- :style="'position:absolute;display: flex;left:'+item.left+'px;top:'+item.top+'px;width:'+item.width+'px;height:'+item.height+'px;'">
- <image :src="item.src" :style="'width:'+item.width+'px;height:'+item.height+'px;'"></image>
- </view>
- <view v-for="(item,index) in item.style.address" :key="index"
- :style="'position:absolute;left:'+item.left+'px;top:'+item.top+'px;color:'+item.color+';font-size:'+item.fontSize+'px;'">
- 地址:{{(business.address[index]||selectCity!='选择省 市 区')?(selectCity!='选择省 市 区'?selectCity:'')+business.address[index]:'未填写地址'}}
- </view>
- <view v-for="(item,index) in item.style.unit" :key="index"
- :style="'position:absolute;left:'+item.left+'px;top:'+item.top+'px;color:'+item.color+';font-size:'+item.fontSize+'px;'">
- {{business.unit[index]?business.unit[index]:'未填写公司'}}
- </view>
- <!-- <view v-for="(item,index) in item.style.position" :key="index"
- :style="'position:absolute;left:'+item.left+'px;top:'+item.top+'px;color:'+item.color+';font-size:'+item.fontSize+'px;'">
- {{business.position[index]?business.position[index]:'未填职位'}}
- </view> -->
- <view
- :style="'position:absolute;left:'+item.style.duties[0].left+'px;top:'+item.style.duties[0].top+'px;color:'+item.style.duties[0].color+';font-size:'+item.style.duties[0].fontSize+'px;'">
- {{business.duties[0]?business.duties[0]:'未填写职位'}}
- </view>
- <view v-if="business.mailbox"
- :style="'position:absolute;left:'+item.style.mailbox.left+'px;top:'+item.style.mailbox.top+'px;color:'+item.style.mailbox.color+';font-size:'+item.style.mailbox.fontSize+'px;'">
- 邮箱:{{business.mailbox?business.mailbox:'未填写邮箱'}}
- </view>
- <view
- :style="'position:absolute;left:'+item.style.mobile.left+'px;top:'+item.style.mobile.top+'px;color:'+item.style.mobile.color+';font-size:'+item.style.mobile.fontSize+'px;'">
- 手机:{{business.mobile?business.mobile:'未填写手机'}}{{business.mobile_phone?' / '+business.mobile_phone:''}}
- </view>
- <view
- :style="'position:absolute;left:'+item.style.wechat.left+'px;top:'+item.style.wechat.top+'px;color:'+item.style.wechat.color+';font-size:'+item.style.wechat.fontSize+'px;'">
- 微信:{{business.wechat?business.wechat:'未填写微信'}}
- </view>
- <view
- :style="'position:absolute;left:'+item.style.name.left+'px;top:'+item.style.name.top+'px;color:'+item.style.name.color+';font-size:'+item.style.name.fontSize+'px;'">
- {{business.name?business.name:'未填写姓名'}}
- </view>
- <view v-if="business.phone"
- :style="'position:absolute;left:'+item.style.phone.left+'px;top:'+item.style.phone.top+'px;color:'+item.style.phone.color+';font-size:'+item.style.phone.fontSize+'px;'">
- 电话:{{business.phone?business.phone:'未填写电话'}}
- </view>
- <image class="tup"
- :style="'width:'+item.style.backdrop.width+'px;height:'+item.style.backdrop.height+'px;'"
- :src="item.style.backdrop.src"></image>
- <view v-if="item.style.avatar.display==1"
- :style="'position:absolute;left:'+item.style.avatar.left+'px;top:'+item.style.avatar.top+'px;width:'+item.style.avatar.width+'px;height:'+item.style.avatar.width+'px;'+(item.style.avatar.style=='circle'?'border-radius:'+item.style.avatar.width+'px;overflow: hidden;':'overflow: hidden;')">
- <image :src="file_path?file_path:item.style.avatar.src"
- :style="'width:'+item.style.avatar.width+'px;height:'+item.style.avatar.width+'px;'">
- </image>
- </view>
- <view v-if="item.style.logo.display==1" class="logo_h" ref="logo_h"
- :style="'position:absolute;left:'+item.style.logo.left+'px;top:'+item.style.logo.top+'px;width:'+item.style.logo.width+'px;height:'+item.style.logo.height+'px;'+(item.style.logo.style=='circle'?'border-radius:'+item.style.logo.width+'px;overflow: hidden;':'overflow: hidden;')">
- <image :src="logo_path?logo_path:item.style.logo.src" class="logo_h" ref="logo_h"></image>
- </view>
+ <!-- 名片预览区域 -->
+ <view class="business-card-preview"
+ v-for="(templateItem,templateIndex) in templateList" v-if="templateItem.template_id==template_id" :key="templateIndex">
+
+ <!-- 图标装饰 -->
+ <view v-for="(item,index) in templateItem.style.icon" :key="index"
+ class="card-icon"
+ :style="{position:'absolute',display:'flex',left:item.left+'px',top:item.top+'px',width:item.width+'px',height:item.height+'px'}">
+ <image :src="item.src" :style="{width:item.width+'px',height:item.height+'px'}"></image>
+ </view>
+
+ <!-- 预览区域 - 支持多个公司和职位 -->
+ <scroll-view scroll-y="true" class="card-scroll-unit"
+ :style="{position:'absolute',left:(templateItem.style.unit[0].left||0)+'px',top:(templateItem.style.unit[0].top||0)+'px',width:unitWidth+'px',height:unitHeight+'px'}">
+ <view v-for="(companyItem, idx) in business.unit" :key="idx"
+ class="card-text-item"
+ :style="{color:(templateItem.style.unit[0].color||'#333'),fontSize:(templateItem.style.unit[0].fontSize||14)+'px',marginBottom:((templateItem.style.unit[0].fontSize||14)*0.5)+'px'}">
+ {{companyItem||'未填写公司'}}
+ </view>
+ </scroll-view>
+
+ <scroll-view scroll-y="true" class="card-scroll-duties"
+ :style="{position:'absolute',left:(templateItem.style.duties[0].left||0)+'px',top:(templateItem.style.duties[0].top||0)+'px',width:dutiesWidth+'px',height:dutiesHeight+'px'}">
+ <view v-for="(dutiesItem, idx) in business.duties" :key="idx"
+ class="card-text-item"
+ :style="{color:(templateItem.style.duties[0].color||'#333'),fontSize:(templateItem.style.duties[0].fontSize||14)+'px',lineHeight:1.5,marginBottom:((templateItem.style.duties[0].fontSize||14)*0.5)+'px'}">
+ {{dutiesItem||'未填写职位'}}
+ </view>
+ </scroll-view>
+
+ <!-- 地址 -->
+ <view v-for="(item,index) in templateItem.style.address" :key="index"
+ class="card-text"
+ :style="{position:'absolute',left:item.left+'px',top:item.top+'px',color:item.color,fontSize:item.fontSize+'px',maxWidth:addressMaxWidth+'px'}">
+ 地址:{{(business.address[index]||selectCity!='选择省 市 区')?(selectCity!='选择省 市 区'?selectCity:'')+business.address[index]:'未填写地址'}}
+ </view>
+
+ <!-- 邮箱 -->
+ <view v-if="business.mailbox"
+ class="card-text"
+ :style="{position:'absolute',left:templateItem.style.mailbox.left+'px',top:templateItem.style.mailbox.top+'px',color:templateItem.style.mailbox.color,fontSize:templateItem.style.mailbox.fontSize+'px',maxWidth:mailboxMaxWidth+'px'}">
+ 邮箱:{{business.mailbox?business.mailbox:'未填写邮箱'}}
+ </view>
+
+ <!-- 手机 -->
+ <view class="card-text"
+ :style="{position:'absolute',left:templateItem.style.mobile.left+'px',top:templateItem.style.mobile.top+'px',color:templateItem.style.mobile.color,fontSize:templateItem.style.mobile.fontSize+'px',maxWidth:mobileMaxWidth+'px'}">
+ 手机:{{business.mobile?business.mobile:'未填写手机'}}{{business.mobile_phone?' / '+business.mobile_phone:''}}
+ </view>
+
+ <!-- 微信 -->
+ <view class="card-text"
+ :style="{position:'absolute',left:templateItem.style.wechat.left+'px',top:templateItem.style.wechat.top+'px',color:templateItem.style.wechat.color,fontSize:templateItem.style.wechat.fontSize+'px',maxWidth:wechatMaxWidth+'px'}">
+ 微信:{{business.wechat?business.wechat:'未填写微信'}}
+ </view>
+
+
+ <!-- 姓名 -->
+ <view class="card-text"
+ :style="{position:'absolute',left:templateItem.style.name.left+'px',top:templateItem.style.name.top+'px',color:templateItem.style.name.color,fontSize:templateItem.style.name.fontSize+'px',maxWidth:nameMaxWidth+'px'}">
+ {{business.name?business.name:'未填写姓名'}}
+ </view>
+
+ <!-- 电话 -->
+ <view v-if="business.phone"
+ class="card-text"
+ :style="{position:'absolute',left:templateItem.style.phone.left+'px',top:templateItem.style.phone.top+'px',color:templateItem.style.phone.color,fontSize:templateItem.style.phone.fontSize+'px',maxWidth:phoneMaxWidth+'px'}">
+ 电话:{{business.phone?business.phone:'未填写电话'}}
+ </view>
+
+ <!-- 背景图 -->
+ <image class="tup card-backdrop"
+ :style="{width:templateItem.style.backdrop.width+'px',height:templateItem.style.backdrop.height+'px'}"
+ :src="templateItem.style.backdrop.src"></image>
+
+ <!-- 头像 -->
+ <view v-if="templateItem.style.avatar.display==1"
+ class="card-avatar"
+ :class="{'avatar-circle': templateItem.style.avatar.style==='circle'}"
+ style="position:absolute"
+ :style="{left:templateItem.style.avatar.left+'px',top:templateItem.style.avatar.top+'px',width:templateItem.style.avatar.width+'px',height:templateItem.style.avatar.width+'px'}">
+ <image :src="file_path?file_path:templateItem.style.avatar.src"
+ :style="{width:templateItem.style.avatar.width+'px',height:templateItem.style.avatar.width+'px'}">
+ </image>
+ </view>
+
+ <!-- Logo -->
+ <view v-if="templateItem.style.logo.display==1"
+ class="card-logo"
+ :class="{'logo-circle': templateItem.style.logo.style==='circle'}"
+ ref="logo_h"
+ style="position:absolute"
+ :style="{left:templateItem.style.logo.left+'px',top:templateItem.style.logo.top+'px',width:templateItem.style.logo.width+'px',height:templateItem.style.logo.height+'px'}">
+ <image :src="logo_path?logo_path:templateItem.style.logo.src" class="logo_h" ref="logo_h"></image>
+ </view>
</view>
<view class="fds">
<view>
- <scroll-view scroll-x="true">
- <view style="width: 100%;white-space: nowrap;">
- <view class="mpxz" v-for="(item,index) in templateList" :key="index"
- @tap="radioChange(index)">
- <view class="zjc" v-if="item.template_id==template_id">
+ <scroll-view scroll-x="true">
+ <view style="width: 100%;white-space: nowrap;">
+ <view class="mpxz" v-for="(item,index) in templateList" :key="index"
+ @tap="radioChange(index)">
+ <view class="zjc" v-if="item.template_id==template_id">
+ </view>
+ <image class="mpxz-image" :src="item.image" mode="aspectFit"></image>
+ </view>
+ </view>
+ </scroll-view>
+ </view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti">名片类型:</view>
+ <view class="lxfxnrr">
+ <picker @change="changeIlk" :range="ilkList" :range-key="'name'" class="lxfxneirong"
+ mode="selector">
+ <view class="picker-content">
+ {{selectedIlk.name || '请选择名片类型'}}
+ <text class="icon iconfont icon-jiantou"></text>
+ </view>
+ <input style="display: none;" name='ilk' v-model="business.ilk" type="text">
+ </picker>
+ </view>
+ </view>
+ <view class="grxx" @click="is_avatar=true" v-show="avatar_display==1" style="overflow: hidden;">
+ <view class="biaoti">
+ 头像
+ </view>
+ <view class="tx" style="margin-left: 30rpx;">
+ <image class="logo" :src="file_path||'@/static/shop/login/qietu_1054.png'" mode="heightFix"></image>
+ <Upload v-if="is_avatar" @getImgs="handleAvatarUpload" :imageList="[file_path]"></Upload>
+ </view>
+ </view>
+ <view @click="is_logo=true" v-show="logo_display==1">
+ <view class="biaoti">
+ logo
+ </view>
+ <view class="logo" style="overflow: hidden;">
+ <image class="logo" :src="logo_path||'@/static/shop/login/qietu_1054.png'" mode="heightFix"></image>
+ <Upload v-if="is_logo" @getImgs="handleLogoUpload" :imageList="[logo_path]"></Upload>
+ </view>
+ </view>
+ <view>
+ <view class="biaoti">
+ 联系方式
+ </view>
+ <view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti"><text style="color: #fa3534;">*</text>姓名:</view>
+ <view class="lxfxnrr">
+ <input placeholder="请输入姓名" name='name' v-model="business.name" class="lxfxneirong"
+ type="text">
+ </view>
+ </view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti"><text style="color: #fa3534;">*</text>手机:</view>
+ <view class="lxfxnrr">
+ <input @input="sjh" placeholder="输入手机号" v-model="mobile" class="lxfxneirong"
+ type="text">
+ <input style="display: none;" name="mobile" v-model="business.mobile"
+ class="lxfxneirong" type="text">
+ <input style="display: none;" name="mobile_phone" v-model="business.mobile_phone"
+ class="lxfxneirong" type="text">
+ </view>
+ </view>
+
+ <view class="lxfx">
+ <view class="lxfxbiaoti">座机:</view>
+ <view class="lxfxnrr"><input placeholder="请输入电话" v-model="business.phone" name="phone"
+ class="lxfxneirong" type="text">
+ </view>
+ </view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti">微信:</view>
+ <view class="lxfxnrr"><input class="lxfxneirong" name="wechat" v-model="business.wechat"
+ placeholder="请输入微信" type="text">
+ </view>
+ </view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti">邮箱:</view>
+ <view class="lxfxnrr"><input class="lxfxneirong" name="mailbox" v-model="business.mailbox"
+ placeholder="请输入邮箱" type="text">
+ </view>
+ </view>
+ </view>
+ </view>
+ <view style="padding-bottom: 300rpx;">
+ <view class="biaoti">
+ 详细信息
+ </view>
+ <view>
+ <view v-for="(item,index) in companyList" :key="index" class="company-item">
+ <view class="company-header">
+ <text class="company-title">公司/职位 {{index+1}}</text>
+ <text class="delete-btn" v-if="companyList.length > 1" @tap="deleteCompany(index)">删除</text>
+ </view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti">公司名称:</view>
+ <view class="lxfxnrr">
+ <input placeholder="请输入公司名称" :name="'unit['+index+']'"
+ v-model="companyList[index].unit" @input="syncBusinessFromCompanyList"
+ class="lxfxneirong" type="text">
+ </view>
+ </view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti">职位:</view>
+ <view class="lxfxnrr">
+ <input placeholder="请输入职位" :name="'duties['+index+']'"
+ v-model="companyList[index].duties" @input="syncBusinessFromCompanyList"
+ class="lxfxneirong" type="text">
+ </view>
+ </view>
+ </view>
+ <view class="add-company-btn" @tap="addCompany">
+ <text class="icon iconfont icon-add"></text>
+ <text>添加公司/职位</text>
+ </view>
+ <view class="lxfx" @tap="industryClose">
+ <view class="lxfxbiaoti">行业:</view>
+ <view class="lxfxnrr">
+ <input class="lxfxneirong" :value="industryNmae" disabled readonly>
+ <input style="display: none;" type="hidden" name="industry_id"
+ v-model="business.industry_id">
+ </view>
+ </view>
+ <view class="lxfx" >
+ <view class="lxfxbiaoti">所在地区:</view>
+ <view class="lxfxnrr">
+ <input class="lxfxneirong" :value="selectCity" disabled="true"
+ @click="chooseLocation" placeholder="请选择省市区">
+ <input style="display: none;" type="hidden" name="province_id"
+ v-model="business.province_id">
+ <input style="display: none;" type="hidden" name="city_id" v-model="business.city_id">
+ <input style="display: none;" type="hidden" name="region_id"
+ v-model="business.region_id">
+ </view>
+ </view>
+ <view class="lxfx" >
+ <view class="lxfxbiaoti"><text style="color: #fa3534;">*</text>地址:</view>
+ <view class="lxfxnrr">
+ <input placeholder="请输入详细地址" name="address[0]" v-model="business.address[0]"
+ class="lxfxneirong" type="text">
+ </view>
+ </view>
+ <view class="lxfx">
+ <view class="lxfxbiaoti">简介:</view>
+ <view class="lxfxnrr">
+ <textarea placeholder="请输入个人或公司简介" maxlength="-1" name="Introduction" v-model="business.Introduction"
+ class="lxfxneirong" :auto-height="true"></textarea>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view class="anu">
+ <button form-type="submit" class="tijiao">保存名片</button>
+ <input type="text" style="display: none;" name="file_id" :value="file_id">
+ <input type="text" style="display: none;" name="logo" :value="logo_id">
+ <input type="text" style="display: none;" name="logo_height" :value="logo_height">
+ <input type="text" style="display: none;" name="logo_width" :value="logo_width">
+ <input type="text" style="display: none;" name="longitude" :value="business.longitude">
+ <input type="text" style="display: none;" name="latitude" :value="business.latitude">
+ </view>
+ <Popup :show="industryShow" :width="screenWidth" type="bottom" :closeable="true" @close="industryClose">
+ <view class="industry-popup">
+ <view class="industry-title">选择行业</view>
+ <scroll-view scroll-y="true" style="height: 600rpx;">
+ <!-- 递归展示行业树形结构 -->
+ <view v-for="item in industryList" :key="item.industry_id">
+ <view class="industry-item" @tap="selectIndustry" :data-id="item.industry_id"
+ :class="{ 'selected': business.industry_id == item.industry_id }">
+ {{ item.name }}
+ </view>
+ <!-- 显示子行业 -->
+ <view v-if="item.child && item.child.length > 0" class="industry-child">
+ <view class="industry-item industry-child-item" v-for="child in item.child"
+ :key="child.industry_id" @tap="selectIndustry" :data-id="child.industry_id"
+ :class="{ 'selected': business.industry_id == child.industry_id }">
+ {{ child.name }}
</view>
- <image class="mpxz-image" :src="item.image" mode="aspectFit"></image>
</view>
</view>
</scroll-view>
</view>
- <view class="lxfx">
- <view class="lxfxbiaoti">名片类型:</view>
- <view class="lxfxnrr">
- <picker @change="changeIlk" :range="ilkList" :range-key="'name'" class="lxfxneirong"
- mode="selector">
- <view class="picker-content">
- {{selectedIlk.name || '请选择名片类型'}}
- <text class="icon iconfont icon-jiantou"></text>
- </view>
- <input style="display: none;" name='ilk' v-model="business.ilk" type="text">
- </picker>
- </view>
- </view>
- <view class="grxx" @click="is_avatar=true" v-show="avatar_display==1" style="overflow: hidden;">
- <view class="biaoti">
- 头像
- </view>
- <view class="tx" style="margin-left: 30rpx;">
- <image class="logo" :src="file_path||'@/static/shop/login/qietu_1054.png'" mode="heightFix"></image>
- <Upload v-if="is_avatar" @getImgs="handleAvatarUpload" :imageList="[file_path]"></Upload>
- </view>
- </view>
- <view @click="is_logo=true" v-show="logo_display==1">
- <view class="biaoti">
- logo
- </view>
- <view class="logo" style="overflow: hidden;">
- <image class="logo" :src="logo_path||'@/static/shop/login/qietu_1054.png'" mode="heightFix"></image>
- <Upload v-if="is_logo" @getImgs="handleLogoUpload" :imageList="[logo_path]"></Upload>
- </view>
- </view>
- <view>
- <view class="biaoti">
- 联系方式
- </view>
- <view>
- <view class="lxfx">
- <view class="lxfxbiaoti"><text style="color: #fa3534;">*</text>姓名:</view>
- <view class="lxfxnrr">
- <input placeholder="请输入姓名" name='name' v-model="business.name" class="lxfxneirong"
- type="text">
- </view>
- </view>
- <view class="lxfx">
- <view class="lxfxbiaoti"><text style="color: #fa3534;">*</text>手机:</view>
- <view class="lxfxnrr">
- <input @input="sjh" placeholder="输入手机号" v-model="mobile" class="lxfxneirong"
- type="text">
- <input style="display: none;" name="mobile" v-model="business.mobile"
- class="lxfxneirong" type="text">
- <input style="display: none;" name="mobile_phone" v-model="business.mobile_phone"
- class="lxfxneirong" type="text">
- </view>
- </view>
-
- <view class="lxfx">
- <view class="lxfxbiaoti">座机:</view>
- <view class="lxfxnrr"><input placeholder="请输入电话" v-model="business.phone" name="phone"
- class="lxfxneirong" type="text">
- </view>
- </view>
- <view class="lxfx">
- <view class="lxfxbiaoti">微信:</view>
- <view class="lxfxnrr"><input class="lxfxneirong" name="wechat" v-model="business.wechat"
- placeholder="请输入微信" type="text">
- </view>
- </view>
- <view class="lxfx">
- <view class="lxfxbiaoti">邮箱:</view>
- <view class="lxfxnrr"><input class="lxfxneirong" name="mailbox" v-model="business.mailbox"
- placeholder="请输入邮箱" type="text">
- </view>
- </view>
- </view>
- </view>
- <view style="padding-bottom: 120rpx;">
- <view class="biaoti">
- 详细信息
- </view>
- <view>
- <view v-for="(item,index) in unit" :key="index">
- <view class="lxfx">
- <view class="lxfxbiaoti">单位名称:</view>
- <view class="lxfxnrr">
- <input placeholder="请输入单位名称" :name="'unit['+index+']'"
- v-model="business.unit[index]" class="lxfxneirong" type="text">
- </view>
- </view>
- <view class="lxfx">
- <view class="lxfxbiaoti">职位:</view>
- <view class="lxfxnrr">
- <input placeholder="请输入职位" :name="'duties['+index+']'"
- v-model="business.duties[index]" class="lxfxneirong" type="text">
- </view>
- </view>
- </view>
- <view class="lxfx" @tap="industryClose">
- <view class="lxfxbiaoti">行业:</view>
- <view class="lxfxnrr">
- <input class="lxfxneirong" :value="industryNmae" disabled readonly>
- <input style="display: none;" type="hidden" name="industry_id"
- v-model="business.industry_id">
- </view>
- </view>
- <view class="lxfx" >
- <view class="lxfxbiaoti">所在地区:</view>
- <view class="lxfxnrr">
- <input class="lxfxneirong" :value="selectCity" disabled="true"
- @click="chooseLocation" placeholder="请选择省市区">
- <input style="display: none;" type="hidden" name="province_id"
- v-model="business.province_id">
- <input style="display: none;" type="hidden" name="city_id" v-model="business.city_id">
- <input style="display: none;" type="hidden" name="region_id"
- v-model="business.region_id">
- </view>
- </view>
- <view class="lxfx" >
- <view class="lxfxbiaoti"><text style="color: #fa3534;">*</text>地址:</view>
- <view class="lxfxnrr">
- <input placeholder="请输入详细地址" name="address[0]" v-model="business.address[0]"
- class="lxfxneirong" type="text">
- </view>
- </view>
- <view class="lxfx">
- <view class="lxfxbiaoti">简介:</view>
- <view class="lxfxnrr">
- <textarea placeholder="请输入个人或公司简介" name="Introduction" v-model="business.Introduction"
- class="lxfxneirong" :auto-height="true"></textarea>
- </view>
- </view>
- </view>
- </view>
- <view class="anu">
- <button form-type="submit" class="tijiao">保存名片</button>
- <input type="text" style="display: none;" name="file_id" :value="file_id">
- <input type="text" style="display: none;" name="logo" :value="logo_id">
- <input type="text" style="display: none;" name="logo_height" :value="logo_height">
- <input type="text" style="display: none;" name="logo_width" :value="logo_width">
- <input type="text" style="display: none;" name="longitude" :value="business.longitude">
- <input type="text" style="display: none;" name="latitude" :value="business.latitude">
- </view>
- <Popup :show="industryShow" :width="screenWidth" type="bottom" :closeable="true" @close="industryClose">
- <view class="industry-popup">
- <view class="industry-title">选择行业</view>
- <scroll-view scroll-y="true" style="height: 600rpx;">
- <!-- 递归展示行业树形结构 -->
- <view v-for="item in industryList" :key="item.industry_id">
- <view class="industry-item" @tap="selectIndustry" :data-id="item.industry_id"
- :class="{ 'selected': business.industry_id == item.industry_id }">
- {{ item.name }}
- </view>
- <!-- 显示子行业 -->
- <view v-if="item.child && item.child.length > 0" class="industry-child">
- <view class="industry-item industry-child-item" v-for="child in item.child"
- :key="child.industry_id" @tap="selectIndustry" :data-id="child.industry_id"
- :class="{ 'selected': business.industry_id == child.industry_id }">
- {{ child.name }}
- </view>
- </view>
- </view>
- </scroll-view>
- </view>
- </Popup>
- <mpvue-city-picker v-if="is_load" ref="mpvueCityPicker" :province="province" :city="city" :area="area"
- :pickerValueDefault="cityPickerValueDefault" @onConfirm="onConfirm"></mpvue-city-picker>
- </view>
- </form>
- </view>
+ </Popup>
+ <mpvue-city-picker v-if="is_load" ref="mpvueCityPicker" :province="province" :city="city" :area="area"
+ :pickerValueDefault="cityPickerValueDefault" @onConfirm="onConfirm"></mpvue-city-picker>
+ </view>
+ </form>
+</view>
</template>
<script>
@@ -296,6 +345,8 @@
logo_height: 0, // Logo高度
logo_width: 0, // Logo宽度
avatar_width: 0, // 头像宽度
+ // 公司职位列表
+ companyList: [], // 公司职位列表
// 显示控制
avatar_display: 1, // 头像显示状态
logo_display: 1, // Logo显示状态
@@ -327,6 +378,9 @@
})
this.business_card_id = e.business_card_id
this.getBusiness(e.business_card_id)
+ } else {
+ // 新增时默认添加一个公司职位
+ this.addCompany();
}
this.getTemplate();
this.getIndustryList();
@@ -334,7 +388,201 @@
// 初始化区域选择器数据
this.initRegionData();
},
+ computed: {
+ // 计算公司列表高度
+ unitHeight() {
+ const fontSize = (this.templateList.find(t => t.template_id === this.template_id)?.style?.unit?.[0]?.fontSize) || 14;
+ const lineHeight = fontSize * 1.5; // 行高 = 字体大小 * 1.5
+ const lineSpacing = fontSize * 0.5; // 行间距 = 字体大小 * 0.5
+ const itemCount = this.business.unit ? this.business.unit.length : 0;
+ // 估算高度:每个公司可能占用最多3行,乘以行高,加上行间距,再加上padding
+ const estimatedLinesPerItem = 3;
+ const height = (lineHeight * estimatedLinesPerItem + lineSpacing) * itemCount + 20;
+ return Math.max(height, 80); // 确保最小高度为80px
+ },
+ // 计算职位列表高度
+ dutiesHeight() {
+ const fontSize = (this.templateList.find(t => t.template_id === this.template_id)?.style?.duties?.[0]?.fontSize) || 14;
+ const lineHeight = fontSize * 1.5; // 行高 = 字体大小 * 1.5
+ const lineSpacing = fontSize * 0.5; // 行间距 = 字体大小 * 0.5
+ const itemCount = this.business.duties ? this.business.duties.length : 0;
+ // 估算高度:每个职位可能占用最多3行,乘以行高,加上行间距,再加上padding
+ const estimatedLinesPerItem = 3;
+ const height = (lineHeight * estimatedLinesPerItem + lineSpacing) * itemCount + 20;
+ return Math.max(height, 80); // 确保最小高度为80px
+ },
+ // 计算公司容器的合适宽度(智能判断右边是否有其他字段)
+ unitWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.unit?.[0]) return 150;
+ return this.calculateFieldMaxWidth(template.style.unit[0].left, template.style.unit[0].top);
+ },
+ // 计算职位容器的合适宽度(智能判断右边是否有其他字段)
+ dutiesWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.duties?.[0]) return 150;
+ return this.calculateFieldMaxWidth(template.style.duties[0].left, template.style.duties[0].top);
+ },
+ // 地址字段的最大宽度
+ addressMaxWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.address?.[0]) return 200;
+ return this.calculateFieldMaxWidth(template.style.address[0].left, template.style.address[0].top);
+ },
+ // 邮箱字段的最大宽度
+ mailboxMaxWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.mailbox) return 200;
+ return this.calculateFieldMaxWidth(template.style.mailbox.left, template.style.mailbox.top);
+ },
+ // 手机字段的最大宽度
+ mobileMaxWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.mobile) return 200;
+ return this.calculateFieldMaxWidth(template.style.mobile.left, template.style.mobile.top);
+ },
+ // 微信字段的最大宽度
+ wechatMaxWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.wechat) return 200;
+ return this.calculateFieldMaxWidth(template.style.wechat.left, template.style.wechat.top);
+ },
+ // 姓名字段的最大宽度
+ nameMaxWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.name) return 200;
+ return this.calculateFieldMaxWidth(template.style.name.left, template.style.name.top);
+ },
+ // 电话字段的最大宽度
+ phoneMaxWidth() {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.phone) return 200;
+ return this.calculateFieldMaxWidth(template.style.phone.left, template.style.phone.top);
+ }
+ },
+ watch: {
+ // 监听companyList变化,同步到business对象
+ // 不使用deep监听,只在数组引用变化时同步
+ // 这样可以避免深度监听导致的多次同步
+ companyList: {
+ handler(newVal, oldVal) {
+ if (newVal && newVal.length > 0) {
+ this.syncBusinessFromCompanyList();
+ }
+ }
+ }
+ },
methods: {
+ // 智能计算文本字段的最大宽度(供computed调用)
+ // 根据右边是否有其他字段来动态计算maxWidth
+ calculateFieldMaxWidth(left, top) {
+ const template = this.templateList.find(t => t.template_id === this.template_id);
+ if (!template || !template.style?.backdrop) return 200;
+
+ const backdropWidth = template.style.backdrop.width || 375;
+ const rightFields = [];
+
+ // 收集所有可能的字段
+ const fields = [];
+
+ // 公司
+ if (template.style.unit && template.style.unit[0]) {
+ fields.push({
+ name: 'unit',
+ left: template.style.unit[0].left,
+ top: template.style.unit[0].top,
+ width: template.style.unit[0].width
+ });
+ }
+
+ // 职位
+ if (template.style.duties && template.style.duties[0]) {
+ fields.push({
+ name: 'duties',
+ left: template.style.duties[0].left,
+ top: template.style.duties[0].top,
+ width: template.style.duties[0].width
+ });
+ }
+
+ // 姓名
+ if (template.style.name) {
+ fields.push({
+ name: 'name',
+ left: template.style.name.left,
+ top: template.style.name.top,
+ width: template.style.name.width
+ });
+ }
+
+ // 地址
+ if (template.style.address && template.style.address[0]) {
+ fields.push({
+ name: 'address',
+ left: template.style.address[0].left,
+ top: template.style.address[0].top,
+ width: template.style.address[0].width
+ });
+ }
+
+ // 邮箱
+ if (template.style.mailbox) {
+ fields.push({
+ name: 'mailbox',
+ left: template.style.mailbox.left,
+ top: template.style.mailbox.top,
+ width: template.style.mailbox.width
+ });
+ }
+
+ // 手机
+ if (template.style.mobile) {
+ fields.push({
+ name: 'mobile',
+ left: template.style.mobile.left,
+ top: template.style.mobile.top,
+ width: template.style.mobile.width
+ });
+ }
+
+ // 微信
+ if (template.style.wechat) {
+ fields.push({
+ name: 'wechat',
+ left: template.style.wechat.left,
+ top: template.style.wechat.top,
+ width: template.style.wechat.width
+ });
+ }
+
+ // 电话
+ if (template.style.phone) {
+ fields.push({
+ name: 'phone',
+ left: template.style.phone.left,
+ top: template.style.phone.top,
+ width: template.style.phone.width
+ });
+ }
+
+ // 找出右边最近的字段
+ // 判断标准: left > 当前left, 且top在合理范围内(±20px)
+ const TOLERANCE = 20;
+ for (let field of fields) {
+ if (field.left > left && Math.abs(field.top - top) <= TOLERANCE) {
+ rightFields.push(field);
+ }
+ }
+
+ // 如果右边有字段,取最近的一个的左边距
+ if (rightFields.length > 0) {
+ rightFields.sort((a, b) => a.left - b.left);
+ return Math.max(rightFields[0].left - left, 50);
+ }
+
+ // 如果右边没有字段,使用名片边缘
+ return Math.max(backdropWidth - left - 10, 100);
+ },
// 打开地图选择地址 by lyzflash
chooseLocation(n) {
let self=this;
@@ -482,10 +730,13 @@
},
getTemplate() {
let _this = this;
- const systemInfo = uni.getSystemInfoSync()
- this.screenWidth = systemInfo.screenWidth * 2 - 70;
+ const systemInfo = uni.getSystemInfoSync();
+ // 使用实际屏幕宽度减去左右边距 (20rpx * 2 = 40rpx = 20px)
+ const displayWidth = systemInfo.screenWidth - 20;
+ this.screenWidth = displayWidth * 2; // 保存为rpx宽度
+
this._post('plus.business.template/getList', {
- screenWidth: systemInfo.screenWidth
+ screenWidth: displayWidth // 传递实际显示宽度(px)
}, res => {
this.templateList = res.data;
this.template_id ? '' : this.template_id = this.templateList[0].template_id
@@ -526,6 +777,10 @@
this.template_id = res.data.template_id;
this.unit = res.data.unit;
this.position = res.data.position;
+
+ // 初始化公司职位列表
+ this.initCompanyList();
+
this.mobile = this.business.mobile + (this.business.mobile_phone ? '/' + this.business
.mobile_phone : '');
this.business.duties.forEach(function(item, index) {
@@ -623,13 +878,61 @@
this.is_business = templateList.style.is_business;
},
+ // 初始化公司职位列表
+ initCompanyList() {
+ let unitLength = Array.isArray(this.business.unit) ? this.business.unit.length : 0;
+ if (unitLength > 0) {
+ // 根据现有数据生成公司职位列表
+ this.companyList = [];
+ for (let i = 0; i < unitLength; i++) {
+ this.companyList.push({
+ unit: this.business.unit[i] || '',
+ duties: this.business.duties[i] || ''
+ });
+ }
+ } else {
+ // 如果没有数据,至少添加一个
+ this.companyList = [{ unit: '', duties: '' }];
+ }
+
+ // 不在这里调用syncBusinessFromCompanyList,因为watch会自动同步
+ // 这样可以避免数据被意外重置
+ },
+
+ // 添加公司职位
+ addCompany() {
+ this.companyList.push({
+ unit: '',
+ duties: ''
+ });
+ // 移除syncBusinessFromCompanyList调用,watch会处理
+ },
+
+ // 删除公司职位
+ deleteCompany(index) {
+ if (this.companyList.length <= 1) {
+ this.showError('至少保留一个公司/职位');
+ return;
+ }
+ this.companyList.splice(index, 1);
+ // 移除syncBusinessFromCompanyList调用,watch会处理
+ },
+
+ // 从公司职位列表同步到business对象
+ syncBusinessFromCompanyList() {
+ if (this.companyList && this.companyList.length > 0) {
+ this.business.unit = this.companyList.map(item => item.unit);
+ this.business.duties = this.companyList.map(item => item.duties);
+ }
+ }
+
}
}
</script>
<style>
.lxfx {
- height: 100rpx;
+ min-height: 100rpx;
align-items: center;
display: flex;
border-bottom: #dce3ec 1rpx solid;
@@ -749,6 +1052,75 @@
border-radius: 30rpx;
}
+ /* 名片预览样式优化 */
+ .business-card-preview {
+ position: sticky;
+ top: 0;
+ z-index: 99999;
+ overflow: visible;
+ border-radius: 30rpx;
+ margin: 20rpx;
+ background-color: #f5f5f5;
+ width: calc(100% - 40rpx);
+ min-height: 450rpx;
+ }
+
+ .card-backdrop {
+ border-radius: 30rpx;
+ }
+
+ .card-icon {
+ z-index: 10;
+ }
+
+ .card-text {
+ white-space: normal;
+ word-break: break-word;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ overflow: hidden;
+ max-width: 100%;
+ line-height: 1.5;
+ }
+
+ .card-scroll-unit,
+ .card-scroll-duties {
+ overflow: hidden;
+ overflow-y: auto;
+ background-color: transparent;
+ box-sizing: border-box;
+ }
+
+ .card-text-item {
+ word-break: break-word;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ white-space: normal;
+ padding: 2px 4px;
+ line-height: 1.5;
+ margin-bottom: 4px; /* 行间距 */
+ }
+
+ .card-avatar,
+ .card-logo {
+ overflow: hidden;
+ }
+
+ .card-avatar.avatar-circle {
+ border-radius: 50%;
+ }
+
+ .card-logo.logo-circle {
+ border-radius: 50%;
+ }
+
+ .card-avatar image,
+ .card-logo image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+
.picker-content {
display: flex;
justify-content: space-between;
@@ -809,4 +1181,53 @@
font-size: 30rpx;
color: #666;
}
+
+ /* 公司职位样式 */
+ .company-item {
+ background-color: #f9f9f9;
+ border-radius: 12rpx;
+ padding: 20rpx;
+ margin-bottom: 20rpx;
+ }
+
+ .company-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16rpx;
+ padding-bottom: 12rpx;
+ border-bottom: 1rpx solid #e5e5e5;
+ }
+
+ .company-title {
+ font-size: 28rpx;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .delete-btn {
+ font-size: 26rpx;
+ color: #fa3534;
+ padding: 4rpx 12rpx;
+ background-color: rgba(250, 53, 52, 0.1);
+ border-radius: 4rpx;
+ }
+
+ .add-company-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24rpx;
+ margin-top: 20rpx;
+ border: 2rpx dashed #D41003;
+ border-radius: 12rpx;
+ color: #D41003;
+ font-size: 28rpx;
+ background-color: rgba(212, 16, 3, 0.05);
+ }
+
+ .add-company-btn .icon {
+ margin-right: 8rpx;
+ font-size: 32rpx;
+ }
</style>
\ No newline at end of file
diff --git a/mobile/pages/plus/business/detail.vue b/mobile/pages/plus/business/detail.vue
index 9ccb912..076c033 100644
--- a/mobile/pages/plus/business/detail.vue
+++ b/mobile/pages/plus/business/detail.vue
@@ -194,7 +194,7 @@
} else {
this.showError('暂未填写微信');
}
- },
+ },/*
// 通过聊天联系
contactWithChat() {
console.log(this.businessInfo);
@@ -203,7 +203,7 @@
uni.navigateTo({
url: `/pages/plus/business/chat/chat?user_id=${this.businessInfo.user_id}&business_card_id=${this.business_card_id}&nickName=${this.businessInfo.name}`
});
- },
+ }, */
// 打开地图
openLocation(businessInfo) {
let address = businessInfo.region.province + ' ' + businessInfo.region.city + ' ' + businessInfo.region
@@ -498,6 +498,13 @@
font-size: 28rpx;
color: #666;
line-height: 1.6;
+ white-space: normal;
+ word-break: break-word;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ overflow: hidden;
+ max-width: 100%;
+ line-height: 1.4;
}
}
}
diff --git a/mobile/pages/plus/business/index.vue b/mobile/pages/plus/business/index.vue
index 6fd9929..67c8ff1 100644
--- a/mobile/pages/plus/business/index.vue
+++ b/mobile/pages/plus/business/index.vue
@@ -65,8 +65,10 @@
<uni-swipe-action-item :right-options="rightOptions" @click="handleDel(index, card)">
<view @click="selectCard(index)" class="card-item">
<view :class="{active: card.is_default==1}" class="card-preview">
- <image style="width: 650rpx;border-radius: 12rpx;" :src="card.mp" mode="widthFix"></image>
- <image v-show="card.is_default==1" src="@/static/icon/mrmp.png" class="mrmp"></image>
+ <image style="width: 650rpx;border-radius: 12rpx;" :src="card.mp"
+ mode="widthFix"></image>
+ <image v-show="card.is_default==1" src="@/static/icon/mrmp.png" class="mrmp">
+ </image>
</view>
</view>
</uni-swipe-action-item>
@@ -110,8 +112,8 @@
<script>
import Popup from '@/components/uni-popup.vue';
-import uniSwipeAction from '@/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue';
-import uniSwipeActionItem from '@/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue';
+ import uniSwipeAction from '@/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue';
+ import uniSwipeActionItem from '@/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue';
export default {
components: {
Popup,
@@ -143,6 +145,9 @@
},
onLoad() {
this.screenWidth = uni.getSystemInfoSync().windowWidth * 2 - 70;
+
+ },
+ onShow() {
this.getbusinessList();
this.getVisitorList();
},
@@ -156,9 +161,9 @@
}, function(res) {
_this.businessList = res.data.data;
if (_this.businessList.length > 0) {
- for(let i in _this.businessList){
- if(_this.businessList[i].is_default==1){
- _this.current=i;
+ for (let i in _this.businessList) {
+ if (_this.businessList[i].is_default == 1) {
+ _this.current = i;
}
}
_this.getbusiness(_this.businessList[_this.current].user_id)
@@ -236,7 +241,7 @@
this.gotoPage(
`/pages/plus/business/add?business_card_id=${this.businessList[this.current].business_card_id}`
);
- }else{
+ } else {
this.gotoPage(
`/pages/plus/business/add`
);
@@ -261,13 +266,13 @@
},
shareCard() {
// 分享名片逻辑
-
+
},
viewAllVisitors() {
// 查看全部访客
this.gotoPage('/pages/plus/business/visitors');
},
-
+
// 跳转到聊天记录页面
gotoChatList() {
uni.navigateTo({
@@ -354,7 +359,7 @@
this.showToast('默认名片不能删除');
return;
}
-
+
uni.showModal({
title: '提示',
content: '确定要删除这个名片吗?',
@@ -368,12 +373,13 @@
// 删除成功,更新列表
this.businessList.splice(index, 1);
this.showToast('删除成功');
-
+
// 如果删除的是当前选中的名片,切换到第一个名片
if (index === this.current) {
if (this.businessList.length > 0) {
this.current = 0;
- this.getStatistics(this.businessList[this.current].business_card_id);
+ this.getStatistics(this.businessList[this.current]
+ .business_card_id);
}
} else if (index < this.current) {
// 如果删除的是当前选中名片之前的,current减1
diff --git a/mobile/pages/plus/business/list.vue b/mobile/pages/plus/business/list.vue
index c1d64a0..969bae9 100644
--- a/mobile/pages/plus/business/list.vue
+++ b/mobile/pages/plus/business/list.vue
@@ -739,6 +739,7 @@
.card-list {
width: calc(100% - 40rpx);
+ height: calc(100vh - 94rpx - 80rpx);
padding: 0 20rpx 20rpx;
.card-item {
diff --git a/operations_vue/static/css/common.css b/operations_vue/static/css/common.css
index 6254d64..7425a78 100644
--- a/operations_vue/static/css/common.css
+++ b/operations_vue/static/css/common.css
@@ -28,7 +28,7 @@
input,
select,
figure,
-figcaption,
+figcaption
{
padding: 0;
margin: 0;
@@ -873,4 +873,4 @@
.sel-width {
width: 280px !important;
-}
\ No newline at end of file
+}
diff --git a/shop_vue/src/api/plus/operations.js b/shop_vue/src/api/plus/operations.js
new file mode 100644
index 0000000..73feab1
--- /dev/null
+++ b/shop_vue/src/api/plus/operations.js
@@ -0,0 +1,186 @@
+import request from '@/utils/request'
+
+let OperationsApi = {
+
+ /*插件列表*/
+ plusList(data, errorback) {
+ return request._post('/shop/plus.plus/index', data, errorback);
+ },
+ /*入驻申请列表*/
+ applyList(data, errorback) {
+ return request._post('/shop/plus.operations.apply/index', data, errorback);
+ },
+ /*运营中心审核*/
+ editApplyStatus(data, errorback) {
+ return request._post('/shop/plus.operations.apply/editApplyStatus', data, errorback);
+ },
+ /*运营中心列表*/
+ operationsList(data, errorback) {
+ return request._post('/shop/plus.operations.operations/index', data, errorback);
+ },
+ /*查看下级用户*/
+ operationsUserFans(data, errorback) {
+ return request._post('/shop/plus.operations.operations/fans', data, errorback);
+ },
+ /*修改运营中心*/
+ toOperationsEdit(data, errorback) {
+ return request._get('/shop/plus.operations.operations/edit', data, errorback);
+ },
+ /*修改运营中心*/
+ operationsEdit(data, errorback) {
+ return request._post('/shop/plus.operations.operations/edit', data, errorback);
+ },
+ /*删除运营中心用户*/
+ deleteOperations(data, errorback) {
+ return request._post('/shop/plus.operations.operations/delete', data, errorback);
+ },
+ /*添加运营中心*/
+ addOperationsUser(data, errorback) {
+ return request._post('/shop/plus.operations.operations/add', data, errorback);
+ },
+ /*提现申请*/
+ cash(data, errorback) {
+ return request._post('/shop/plus.operations.cash/index', data, errorback);
+ },
+ /*运营中心提现审核*/
+ cashSubmit(data, errorback) {
+ return request._post('/shop/plus.operations.cash/submit', data, errorback);
+ },
+ /*微信打款*/
+ WxPay(data, errorback) {
+ return request._post('/shop/plus.operations.cash/wechat_pay', data, errorback);
+ },
+ /*运营中心确认打款*/
+ money(data, errorback) {
+ return request._post('/shop/plus.operations.cash/money', data, errorback);
+ },
+
+ /*运营中心设置*/
+ operationsSet(data, errorback) {
+ return request._post('/shop/plus.operations.setting/index', data, errorback);
+ },
+ /*运营中心设置-基础设置*/
+ basic(data, errorback) {
+ return request._post('/shop/plus.operations.setting/basic', data, errorback);
+ },
+ /*运营中心设置-条件*/
+ condition(data, errorback) {
+ return request._post('/shop/plus.operations.setting/condition', data, errorback);
+ },
+ /*运营中心设置-分红设置*/
+ bonus(data, errorback) {
+ return request._post('/shop/plus.operations.setting/bonus', data, errorback);
+ },
+ /*运营中心设置-结算设置*/
+ settlement(data, errorback) {
+ return request._post('/shop/plus.operations.setting/settlement', data, errorback);
+ },
+ /*运营中心设置-自定义文字*/
+ words(data, errorback) {
+ return request._post('/shop/plus.operations.setting/words', data, errorback);
+ },
+ /*运营中心设置-申请协议*/
+ license(data, errorback) {
+ return request._post('/shop/plus.operations.setting/license', data, errorback);
+ },
+ /*运营中心设置-页面背景*/
+ background(data, errorback) {
+ return request._post('/shop/plus.operations.setting/background', data, errorback);
+ },
+
+ /*运营中心权限管理*/
+ /*权限列表*/
+ operationsAccessList(data, errorback) {
+ return request._post('/shop/plus.operations.access/index', data, errorback);
+ },
+ /*添加权限*/
+ operationsAccessAdd(data, errorback) {
+ return request._post('/shop/plus.operations.access/add', data, errorback);
+ },
+ /*修改权限*/
+ operationsAccessEdit(data, errorback) {
+ return request._post('/shop/plus.operations.access/edit', data, errorback);
+ },
+ /*删除权限*/
+ operationsAccessDelete(data, errorback) {
+ return request._post('/shop/plus.operations.access/delete', data, errorback);
+ },
+ /*权限状态修改*/
+ operationsAccessStatus(data, errorback) {
+ return request._post('/shop/plus.operations.access/status', data, errorback);
+ },
+
+ /*运营中心角色管理*/
+ /*角色列表*/
+ operationsRoleList(data, errorback) {
+ return request._post('/shop/plus.operations.role/index', data, errorback);
+ },
+ /*添加角色需要的数据*/
+ operationsRoleAddInfo(data, errorback) {
+ return request._get('/shop/plus.operations.role/addInfo', data, errorback);
+ },
+ /*添加角色*/
+ operationsRoleAdd(data, errorback) {
+ return request._post('/shop/plus.operations.role/add', data, errorback);
+ },
+ /*修改角色需要的数据*/
+ operationsRoleEditInfo(data, errorback) {
+ return request._get('/shop/plus.operations.role/editInfo', data, errorback);
+ },
+ /*修改角色*/
+ operationsRoleEdit(data, errorback) {
+ return request._post('/shop/plus.operations.role/edit', data, errorback);
+ },
+ /*删除角色*/
+ operationsRoleDelete(data, errorback) {
+ return request._post('/shop/plus.operations.role/delete', data, errorback);
+ },
+
+ /*运营中心管理员管理*/
+ /*管理员列表*/
+ operationsAdminList(data, errorback) {
+ return request._post('/shop/plus.operations.user/index', data, errorback);
+ },
+ /*添加管理员*/
+ operationsAdminAdd(data, errorback) {
+ return request._post('/shop/plus.operations.user/add', data, errorback);
+ },
+ /*修改管理员需要的数据*/
+ operationsAdminEditInfo(data, errorback) {
+ return request._get('/shop/plus.operations.user/edit', data, errorback);
+ },
+ /*修改管理员*/
+ operationsAdminEdit(data, errorback) {
+ return request._post('/shop/plus.operations.user/edit', data, errorback);
+ },
+ /*删除管理员*/
+ operationsAdminDelete(data, errorback) {
+ return request._post('/shop/plus.operations.user/delete', data, errorback);
+ },
+
+ /*等级管理*/
+ /*等级列表*/
+ operationsGradeList(data, errorback) {
+ return request._post('/shop/plus.operations.grade/index', data, errorback);
+ },
+ /*添加等级*/
+ operationsGradeAdd(data, errorback) {
+ return request._post('/shop/plus.operations.grade/add', data, errorback);
+ },
+ /*修改等级*/
+ operationsGradeEdit(data, errorback) {
+ return request._post('/shop/plus.operations.grade/edit', data, errorback);
+ },
+ /*删除等级*/
+ operationsGradeDelete(data, errorback) {
+ return request._post('/shop/plus.operations.grade/delete', data, errorback);
+ },
+
+ /*运营中心订单*/
+ /*订单列表*/
+ operationsOrder(data, errorback) {
+ return request._post('/shop/plus.operations.order/index', data, errorback);
+ },
+}
+
+export default OperationsApi;
diff --git a/shop_vue/src/views/plus/operations/index.vue b/shop_vue/src/views/plus/operations/index.vue
index 9457e25..7ab9657 100644
--- a/shop_vue/src/views/plus/operations/index.vue
+++ b/shop_vue/src/views/plus/operations/index.vue
@@ -11,6 +11,8 @@
<User v-if="activeName == 'user'"></User>
<!--提现申请-->
<Cash v-if="activeName == 'cash'"></Cash>
+ <!--运营中心订单-->
+ <Order v-if="activeName == 'order'"></Order>
<!--分销设置-->
<Setting v-if="activeName == 'setting'"></Setting>
<Auth v-if="activeName == 'auth'"></Auth>
@@ -26,6 +28,7 @@
import Apply from './apply/Apply';
import User from './user/User';
import Cash from './cash/Cash';
+import Order from './order/Order';
import Setting from './setting/Setting';
import Grade from './grade/index';
import Auth from './auth/index';
@@ -35,6 +38,7 @@
Apply,
User,
Cash,
+ Order,
Setting,
Grade,
Auth
@@ -65,6 +69,11 @@
value: '提现申请',
path:'/plus/operations/cash/index'
},
+ {
+ key: 'order',
+ value: '运营订单',
+ path:'/plus/operations/order/index'
+ },
// {
// key: 'grade',
// value: '等级管理',
diff --git a/shop_vue/src/views/plus/operations/setting/Setting.vue b/shop_vue/src/views/plus/operations/setting/Setting.vue
index 3c4e69f..2997407 100644
--- a/shop_vue/src/views/plus/operations/setting/Setting.vue
+++ b/shop_vue/src/views/plus/operations/setting/Setting.vue
@@ -39,7 +39,7 @@
</div>
</template>
<script>
-import PlusApi from '@/api/plus/region.js';
+import PlusApi from '@/api/plus/operations.js';
import Basic from './part/Basic';
import Condition from './part/Condition';
import Bonus from './part/Bonus';
@@ -82,7 +82,7 @@
/*获取数据*/
getData() {
let self = this;
- PlusApi.regionSet({}, true)
+ PlusApi.operationsSet({}, true)
.then(res => {
self.settingData = res.data;
self.loading=false;
diff --git a/shop_vue/src/views/plus/operations/setting/part/Background.vue b/shop_vue/src/views/plus/operations/setting/part/Background.vue
index 659c7b4..0945934 100644
--- a/shop_vue/src/views/plus/operations/setting/part/Background.vue
+++ b/shop_vue/src/views/plus/operations/setting/part/Background.vue
@@ -38,7 +38,7 @@
<script>
import Upload from '@/components/file/Upload';
-import PlusApi from '@/api/plus/region.js';
+import PlusApi from '@/api/plus/operations.js';
export default {
components: {
Upload: Upload
diff --git a/shop_vue/src/views/plus/operations/setting/part/Basic.vue b/shop_vue/src/views/plus/operations/setting/part/Basic.vue
index af52801..fcf3945 100644
--- a/shop_vue/src/views/plus/operations/setting/part/Basic.vue
+++ b/shop_vue/src/views/plus/operations/setting/part/Basic.vue
@@ -13,42 +13,12 @@
<el-radio v-model="form.is_open" label="0">关闭</el-radio>
</div>
</el-form-item>
- <el-form-item label="订单总分收益比例">
- <el-input v-model="form.total_rate" type="number" class="max-w460">
- <template slot="append">%</template>
- </el-input>
- <div class="tips">订单总分红比例 * 订单实付金额 = 可被所有代理瓜分的分红总金额</div>
- </el-form-item>
- <!-- <el-form-item label="是否开启平级分红">
- <div>
- <el-radio v-model="form.pjaward" label="1">开启</el-radio>
- <el-radio v-model="form.pjaward" label="0">关闭</el-radio>
- </div>
- </el-form-item> -->
- <!-- <el-form-item label="平级奖励层级" v-if="form.pjaward==1">
- <div>
- <el-input v-model="form.pjaward_level" type="number" class="max-w460"></el-input>
- <div class="tips">默认1级,即只往上找一个平级(根据分销关系查找)</div>
- </div>
- </el-form-item> -->
- <el-form-item label="分红结算周期">
- <div>
- <el-radio v-model="form.bonus_type" label="10">按周</el-radio>
- <el-radio v-model="form.bonus_type" label="20">按月</el-radio>
- <!-- <el-radio v-model="form.bonus_type" label="30">按年</el-radio> -->
- </div>
- </el-form-item>
<el-form-item label="可申请成为代理条件">
<div>
<el-radio-group @change="chooseBecomeType" v-model="form.become">
<el-radio :label="10">无条件</el-radio>
- <!-- <el-radio v-model="form.become" label="100">购买商品</el-radio> -->
- <!-- <el-radio v-model="form.become" label="20">无需审核</el-radio> -->
- <!-- <el-radio v-model="form.become" label="30">下线人数</el-radio> -->
<el-radio :label="40">下级分销商总数</el-radio>
<el-radio :label="50">累计佣金总数</el-radio>
- <!-- <el-radio v-model="form.become" label="70">累计团队业绩</el-radio>
- <el-radio v-model="form.become" label="80">团队总人数</el-radio> -->
<el-radio :label="90">单次消费</el-radio>
</el-radio-group>
</div>
@@ -82,7 +52,7 @@
</template>
<script>
-import PlusApi from '@/api/plus/region.js';
+import PlusApi from '@/api/plus/operations.js';
import Product from '@/components/product/Product';
export default {
components: {
diff --git a/shop_vue/src/views/plus/operations/setting/part/Bonus.vue b/shop_vue/src/views/plus/operations/setting/part/Bonus.vue
index d62aeaf..86a292e 100644
--- a/shop_vue/src/views/plus/operations/setting/part/Bonus.vue
+++ b/shop_vue/src/views/plus/operations/setting/part/Bonus.vue
@@ -36,7 +36,7 @@
</template>
<script>
- import PlusApi from '@/api/plus/region.js';
+ import PlusApi from '@/api/plus/operations.js';
export default {
data() {
diff --git a/shop_vue/src/views/plus/operations/setting/part/Condition.vue b/shop_vue/src/views/plus/operations/setting/part/Condition.vue
index aab1f25..6de1b87 100644
--- a/shop_vue/src/views/plus/operations/setting/part/Condition.vue
+++ b/shop_vue/src/views/plus/operations/setting/part/Condition.vue
@@ -47,7 +47,7 @@
</template>
<script>
-import PlusApi from '@/api/plus/region.js';
+import PlusApi from '@/api/plus/operations.js';
import Product from '@/components/product/Product';
export default {
components: {
diff --git a/shop_vue/src/views/plus/operations/setting/part/License.vue b/shop_vue/src/views/plus/operations/setting/part/License.vue
index f1892b0..99dec79 100644
--- a/shop_vue/src/views/plus/operations/setting/part/License.vue
+++ b/shop_vue/src/views/plus/operations/setting/part/License.vue
@@ -21,7 +21,7 @@
</template>
<script>
- import PlusApi from '@/api/plus/region.js';
+ import PlusApi from '@/api/plus/operations.js';
export default {
data() {
diff --git a/shop_vue/src/views/plus/operations/setting/part/Settlement.vue b/shop_vue/src/views/plus/operations/setting/part/Settlement.vue
index 89ca8f7..24aca80 100644
--- a/shop_vue/src/views/plus/operations/setting/part/Settlement.vue
+++ b/shop_vue/src/views/plus/operations/setting/part/Settlement.vue
@@ -43,7 +43,7 @@
</template>
<script>
- import PlusApi from '@/api/plus/region.js';
+ import PlusApi from '@/api/plus/operations.js';
export default {
data() {
diff --git a/shop_vue/src/views/plus/operations/setting/part/Words.vue b/shop_vue/src/views/plus/operations/setting/part/Words.vue
index b08c6d2..53782d7 100644
--- a/shop_vue/src/views/plus/operations/setting/part/Words.vue
+++ b/shop_vue/src/views/plus/operations/setting/part/Words.vue
@@ -80,7 +80,7 @@
</template>
<script>
-import PlusApi from '@/api/plus/region.js';
+import PlusApi from '@/api/plus/operations.js';
export default {
data() {
--
Gitblit v1.9.2