分配客户群二维码
This commit is contained in:
@@ -20,5 +20,5 @@ return [
|
||||
'app\common\command\Test',
|
||||
'app\common\command\BiddingDeal',
|
||||
'app\common\command\DemandDeal',
|
||||
'app\common\command\GroupChatFetch',
|
||||
'app\common\command\GroupChat',
|
||||
];
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\command;
|
||||
|
||||
use app\common\service\DemandGroupChatService;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\console\input\Argument;
|
||||
|
||||
/**
|
||||
* 企业微信沟通群管理
|
||||
*
|
||||
* 交互模式:php think groupChat:manage
|
||||
* 直接执行:php think groupChat:manage stat|sync|refresh|refreshOne|recycle
|
||||
*
|
||||
* 新增功能:在 $actions 里加一项,并实现同名方法即可
|
||||
*/
|
||||
class GroupChat extends Command
|
||||
{
|
||||
/**
|
||||
* 功能菜单 功能名 => [菜单说明, 处理方法]
|
||||
* @var array
|
||||
*/
|
||||
protected $actions = [
|
||||
'stat' => ['查看群池状态', 'stat'],
|
||||
'sync' => ['同步企业微信客户群,补充群池', 'syncList'],
|
||||
'refresh' => ['刷新所有已分配群的二维码', 'refreshAll'],
|
||||
'refreshOne' => ['刷新指定需求群的二维码', 'refreshOne'],
|
||||
'recycle' => ['回收指定需求占用的群,归还群池', 'recycle'],
|
||||
];
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('groupChat:manage')
|
||||
->addArgument('action', Argument::OPTIONAL, '要执行的功能:' . implode('|', array_keys($this->actions)))
|
||||
->setDescription('企业微信沟通群管理:群池同步 / 二维码刷新 / 回收 / 状态查看');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$action = trim((string)$input->getArgument('action'));
|
||||
if ($action === '') {
|
||||
$this->showMenu($input, $output);
|
||||
return;
|
||||
}
|
||||
$this->dispatch($action, $input, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交互菜单
|
||||
*/
|
||||
protected function showMenu(Input $input, Output $output)
|
||||
{
|
||||
$choices = array_merge(array_keys($this->actions), ['exit']);
|
||||
while (true) {
|
||||
$output->writeln('');
|
||||
$output->writeln('<info>企业微信沟通群管理</info>');
|
||||
foreach ($this->actions as $key => $item) {
|
||||
$output->writeln(sprintf(' %-12s%s', $key, $item[0]));
|
||||
}
|
||||
$output->writeln(sprintf(' %-12s%s', 'exit', '退出'));
|
||||
|
||||
$action = $output->choice($input, '请选择要执行的功能', $choices, 'stat');
|
||||
if ($action === 'exit') {
|
||||
$output->writeln('<info>已退出</info>');
|
||||
return;
|
||||
}
|
||||
$this->dispatch($action, $input, $output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调度到具体处理方法
|
||||
*/
|
||||
protected function dispatch($action, Input $input, Output $output)
|
||||
{
|
||||
if (!isset($this->actions[$action])) {
|
||||
$output->writeln("<error>未知功能:{$action}</error>");
|
||||
$output->writeln('可用功能:' . implode('、', array_keys($this->actions)));
|
||||
return;
|
||||
}
|
||||
$method = $this->actions[$action][1];
|
||||
try {
|
||||
$this->$method($input, $output);
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>执行失败:' . $e->getMessage() . '</error>');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看群池状态
|
||||
*/
|
||||
protected function stat(Input $input, Output $output)
|
||||
{
|
||||
$stat = DemandGroupChatService::stat();
|
||||
$output->writeln(sprintf(
|
||||
'群总数:%d 空闲:%d 已分配:%d 无二维码:%d',
|
||||
$stat['total'],
|
||||
$stat['free'],
|
||||
$stat['used'],
|
||||
$stat['no_qrcode']
|
||||
));
|
||||
if ($stat['free'] < 3) {
|
||||
$output->writeln('<comment>提示:空闲群不足 3 个,请先在企微建群,再执行 sync 补充</comment>');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步企业微信客户群
|
||||
*/
|
||||
protected function syncList(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln('<comment>正在从企业微信拉取客户群列表...</comment>');
|
||||
$num = DemandGroupChatService::syncList();
|
||||
$output->writeln($num > 0
|
||||
? "<info>已新入库 {$num} 个群</info>"
|
||||
: '<comment>没有新的群需要入库(群主名下暂无新增客户群)</comment>');
|
||||
$this->stat($input, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新所有已分配群的二维码
|
||||
*/
|
||||
protected function refreshAll(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln('<comment>正在刷新已分配群的二维码...</comment>');
|
||||
$res = DemandGroupChatService::refreshAll();
|
||||
$output->writeln(sprintf('共 %d 个:成功 %d,失败 %d', $res['total'], $res['success'], $res['fail']));
|
||||
if ($res['fail']) {
|
||||
$output->writeln('<error>失败的需求ID:' . implode(', ', $res['failDemandIds']) . ',详情见日志</error>');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新指定需求群的二维码
|
||||
*/
|
||||
protected function refreshOne(Input $input, Output $output)
|
||||
{
|
||||
$demandId = (int)$output->ask($input, '请输入需求ID', '');
|
||||
if (!$demandId) {
|
||||
$output->writeln('<error>需求ID不能为空</error>');
|
||||
return;
|
||||
}
|
||||
if (!DemandGroupChatService::refreshByDemand($demandId)) {
|
||||
$output->writeln("<error>需求 {$demandId} 没有已分配的沟通群,或刷新失败,详情见日志</error>");
|
||||
return;
|
||||
}
|
||||
$output->writeln("<info>需求 {$demandId} 的群二维码已刷新</info>");
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收指定需求占用的群
|
||||
*/
|
||||
protected function recycle(Input $input, Output $output)
|
||||
{
|
||||
$demandId = (int)$output->ask($input, '请输入要回收的需求ID', '');
|
||||
if (!$demandId) {
|
||||
$output->writeln('<error>需求ID不能为空</error>');
|
||||
return;
|
||||
}
|
||||
if (!$output->confirm($input, "确认回收需求 {$demandId} 占用的沟通群?", false)) {
|
||||
$output->writeln('<comment>已取消</comment>');
|
||||
return;
|
||||
}
|
||||
if (!DemandGroupChatService::recycle($demandId)) {
|
||||
$output->writeln("<error>需求 {$demandId} 没有已分配的沟通群</error>");
|
||||
return;
|
||||
}
|
||||
$output->writeln("<info>需求 {$demandId} 的沟通群已归还群池</info>");
|
||||
$this->stat($input, $output);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\command;
|
||||
|
||||
use app\common\service\DemandGroupChatService;
|
||||
use app\common\service\WorkWeChatService;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
class GroupChatFetch extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('groupChat:fetch')->setDescription('groupChat fetch command!');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln("groupChat fetch...");
|
||||
DemandGroupChatService::updateQrCode(8);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use app\common\model\demand\group\Chat;
|
||||
use app\common\traits\ServiceTrait;
|
||||
use Exception;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use think\Log;
|
||||
|
||||
class DemandGroupChatService
|
||||
{
|
||||
@@ -43,19 +44,22 @@ class DemandGroupChatService
|
||||
];
|
||||
|
||||
/**
|
||||
* 保存客户群列表
|
||||
* @return void
|
||||
* 保存客户群列表(只补充未入库的群,可重复执行)
|
||||
* @return int 新增数量
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public static function createList()
|
||||
public static function syncList(): int
|
||||
{
|
||||
$scene = 2;
|
||||
$state = '';
|
||||
$group_chat_list = WorkWeChatService::groupChatList();
|
||||
$dataList = [];
|
||||
foreach ($group_chat_list as $chat) {
|
||||
$chat_id = $chat['chat_id'] ?? 0;
|
||||
$chat_id = $chat['chat_id'] ?? '';
|
||||
if (!$chat_id) {
|
||||
continue;
|
||||
}
|
||||
$groupChatInfo = WorkWeChatService::groupChatInfo($chat_id);
|
||||
// $config_id = WorkWeChatService::groupChatAddJoinWay([$chat_id], $scene, $state);
|
||||
$dataList[] = [
|
||||
'demand_id' => 0,
|
||||
'chat_id' => $chat_id,
|
||||
@@ -66,18 +70,27 @@ class DemandGroupChatService
|
||||
'state' => $state,
|
||||
];
|
||||
}
|
||||
usort($dataList, function($a, $b) {
|
||||
//群名为空时不再排序,避免空列表导致报错
|
||||
if (!$dataList) {
|
||||
Log::warning(__METHOD__ . ' 企业微信未返回任何客户群,请检查群主配置与接口权限');
|
||||
return 0;
|
||||
}
|
||||
usort($dataList, function ($a, $b) {
|
||||
return (int)filter_var($a['name'], FILTER_SANITIZE_NUMBER_INT) <=> (int)filter_var($b['name'], FILTER_SANITIZE_NUMBER_INT);
|
||||
});
|
||||
$chatIdList = self::where('chat_id', '<>', '')->column('chat_id');
|
||||
$dataList = array_filter($dataList, function($value) use($chatIdList) {
|
||||
$dataList = array_filter($dataList, function ($value) use ($chatIdList) {
|
||||
return !in_array($value['chat_id'], $chatIdList);
|
||||
});
|
||||
$res = (new self::$Model)->saveAll($dataList);
|
||||
if (!$dataList) {
|
||||
return 0;
|
||||
}
|
||||
(new self::$Model)->saveAll($dataList);
|
||||
return count($dataList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新二维码
|
||||
* 分配一个空闲群给需求,并生成(或刷新)二维码
|
||||
* @param $demand_id
|
||||
* @param bool $refresh
|
||||
* @return mixed
|
||||
@@ -88,17 +101,113 @@ class DemandGroupChatService
|
||||
//分配一个未使用的群
|
||||
$info = self::getOne(['demand_id' => 0], [], ['id']);
|
||||
if (!$info) {
|
||||
Log::error(__METHOD__ . ' 群池已空,无法为需求分配沟通群,demand_id:' . $demand_id);
|
||||
return false;
|
||||
}
|
||||
$info->demand_id = $demand_id;
|
||||
if (!$info->qr_code || $refresh) {
|
||||
//更新config_id,防止设置群聊邀请确认后不生效
|
||||
$config_id = WorkWeChatService::groupChatAddJoinWay([$info['chat_id']]);
|
||||
$join_way = WorkWeChatService::groupChatGetJoinWay($config_id);
|
||||
$info->config_id = $config_id;
|
||||
$info->qr_code = $join_way['qr_code'] ?? '';
|
||||
}
|
||||
self::refreshQrCode($info, $refresh);
|
||||
return $info->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新生成群的入群二维码
|
||||
* 失败只记录日志并返回 false,不抛异常,避免影响确认接单等主流程
|
||||
* @param Chat|\think\Model $info
|
||||
* @param bool $refresh 已有二维码时是否强制刷新
|
||||
* @return bool
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public static function refreshQrCode($info, bool $refresh = false): bool
|
||||
{
|
||||
if ($info->qr_code && !$refresh) {
|
||||
return true;
|
||||
}
|
||||
//更新config_id,防止设置群聊邀请确认后不生效
|
||||
$config_id = WorkWeChatService::groupChatAddJoinWay([$info['chat_id']]);
|
||||
if (!$config_id) {
|
||||
Log::error(__METHOD__ . ' 生成入群方式失败,chat_id:' . $info['chat_id']);
|
||||
return false;
|
||||
}
|
||||
$join_way = WorkWeChatService::groupChatGetJoinWay($config_id);
|
||||
if (empty($join_way['qr_code'])) {
|
||||
Log::error(__METHOD__ . ' 获取群二维码失败,config_id:' . $config_id);
|
||||
return false;
|
||||
}
|
||||
$info->config_id = $config_id;
|
||||
$info->qr_code = $join_way['qr_code'];
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新所有已分配群的二维码
|
||||
* @return array
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public static function refreshAll(): array
|
||||
{
|
||||
$list = self::where('demand_id', '>', 0)->select();
|
||||
$result = ['total' => 0, 'success' => 0, 'fail' => 0, 'failDemandIds' => []];
|
||||
foreach ($list as $item) {
|
||||
$result['total']++;
|
||||
if (self::refreshQrCode($item, true) && $item->save()) {
|
||||
$result['success']++;
|
||||
} else {
|
||||
$result['fail']++;
|
||||
$result['failDemandIds'][] = $item->demand_id;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新指定需求群的二维码
|
||||
* @param $demand_id
|
||||
* @return bool
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public static function refreshByDemand($demand_id)
|
||||
{
|
||||
$info = self::getOne(['demand_id' => $demand_id]);
|
||||
if (!$info) {
|
||||
Log::error(__METHOD__ . ' 该需求没有已分配的沟通群,demand_id:' . $demand_id);
|
||||
return false;
|
||||
}
|
||||
if (!self::refreshQrCode($info, true)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)$info->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收需求占用的群,归还群池
|
||||
* @param $demand_id
|
||||
* @return bool
|
||||
*/
|
||||
public static function recycle($demand_id)
|
||||
{
|
||||
$info = self::getOne(['demand_id' => $demand_id]);
|
||||
if (!$info) {
|
||||
return false;
|
||||
}
|
||||
$info->demand_id = 0;
|
||||
$info->config_id = '';
|
||||
//旧二维码随需求作废,下次分配时重新生成
|
||||
$info->qr_code = '';
|
||||
return (bool)$info->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 群池状态
|
||||
* @return array
|
||||
*/
|
||||
public static function stat(): array
|
||||
{
|
||||
return [
|
||||
'total' => self::$Model::count(),
|
||||
'free' => self::where('demand_id', 0)->count(),
|
||||
'used' => self::where('demand_id', '>', 0)->count(),
|
||||
'no_qrcode' => self::where('qr_code', '')->count(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,3 +13,6 @@ PHP=/usr/local/bin/php
|
||||
# 确认收货超时(7 天自动收货)+ 订单收益解冻
|
||||
*/10 * * * * nginx cd ${APP_ROOT} && flock -n /tmp/cb-demand.lock ${PHP} think demand:deal >> ${APP_ROOT}/runtime/cron/demand-deal-$(date +\%Y\%m).log 2>&1
|
||||
|
||||
# 沟通群二维码续期(刷新所有已分配群的二维码,不会占用新的群)
|
||||
0 3 * * * nginx cd ${APP_ROOT} && flock -n /tmp/cb-groupchat.lock ${PHP} think groupChat:manage refresh >> ${APP_ROOT}/runtime/cron/groupchat-manage-$(date +\%Y\%m).log 2>&1
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ Page({
|
||||
freshPage: false,
|
||||
fromPreview: false, // 预览锁
|
||||
hasMore: true, // 新增字段,标记是否还有更多数据
|
||||
refreshing: false, // 刷新按钮是否处于加载中
|
||||
tabList: [
|
||||
{ text: '全部', key: -1 },
|
||||
{ text: '招标中', key: 1 },
|
||||
@@ -59,6 +60,13 @@ Page({
|
||||
}
|
||||
this.loadDemandList(true);
|
||||
},
|
||||
// 点击右侧刷新按钮
|
||||
async onRefreshTap() {
|
||||
if (this.data.refreshing) return;
|
||||
this.setData({ refreshing: true });
|
||||
await this.loadDemandList(true);
|
||||
this.setData({ refreshing: false });
|
||||
},
|
||||
//图片预览
|
||||
onImageView(e) {
|
||||
const { images, index } = e.currentTarget.dataset;
|
||||
@@ -77,7 +85,8 @@ Page({
|
||||
},
|
||||
|
||||
// 加载需求列表数据
|
||||
async loadDemandList(fresh = false) {
|
||||
async loadDemandList(fresh = false, options = {}) {
|
||||
const { silent = false } = options;
|
||||
if (fresh) {
|
||||
this.setData({
|
||||
page: 1,
|
||||
@@ -95,14 +104,19 @@ Page({
|
||||
try {
|
||||
const { page, status, keywords, opType } = this.data;
|
||||
let params = { page, status, keywords, opType };
|
||||
wx.showLoading({
|
||||
title: '加载中',
|
||||
});
|
||||
// 下拉刷新自带 loading 指示,不再叠加 showLoading
|
||||
if (!silent) {
|
||||
wx.showLoading({
|
||||
title: '加载中',
|
||||
});
|
||||
}
|
||||
const res = await fetchDemandList(params);
|
||||
const nextList = res.data.data;
|
||||
console.log(res)
|
||||
console.log(nextList)
|
||||
wx.hideLoading();
|
||||
if (!silent) {
|
||||
wx.hideLoading();
|
||||
}
|
||||
|
||||
// 判断是否还有更多数据
|
||||
const { current_page, last_page } = res.data;
|
||||
@@ -218,22 +232,26 @@ Page({
|
||||
return;
|
||||
}
|
||||
const bidDemandId = wx.getStorageSync('bidDemandId');
|
||||
console.log('bidDemandId:', bidDemandId);
|
||||
if (bidDemandId) {
|
||||
const index = this.data.demandList.findIndex(item => item.id === Number(bidDemandId));
|
||||
console.log('bidDemandId-index:', index);
|
||||
index >= 0 && this.setData({
|
||||
[`demandList[${index}].is_bid`]: true,
|
||||
[`demandList[${index}].btnName`]: '已投标',
|
||||
[`demandList[${index}].demand_biddings_count`]: this.data.demandList[index].demand_biddings_count + 1
|
||||
});
|
||||
// 先清除标记,避免同一条被重复处理
|
||||
wx.removeStorageSync('bidDemandId');
|
||||
} else {
|
||||
if (this.data.freshPage) {
|
||||
this.setData({ freshPage: false });
|
||||
console.log('freshing');
|
||||
const index = this.data.demandList.findIndex(item => item.id === Number(bidDemandId));
|
||||
if (index < 0) {
|
||||
// 当前列表里没有这条(例如「我投标的需求」页),交给接口重新拉取
|
||||
this.loadDemandList(true);
|
||||
} else {
|
||||
this.setData({
|
||||
[`demandList[${index}].is_bid`]: true,
|
||||
// 按钮渲染的是 item.button.name,只改 btnName 不会刷新文案
|
||||
[`demandList[${index}].button`]: { name: '已投标', theme: 'light' },
|
||||
[`demandList[${index}].demand_biddings_count`]: this.data.demandList[index].demand_biddings_count + 1,
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.data.freshPage) {
|
||||
this.setData({ freshPage: false });
|
||||
this.loadDemandList(true);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -254,8 +272,9 @@ Page({
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
this.loadDemandList(true);
|
||||
async onPullDownRefresh() {
|
||||
await this.loadDemandList(true, { silent: true });
|
||||
wx.stopPullDownRefresh();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundTextStyle": "dark",
|
||||
"onReachBottomDistance": 20,
|
||||
"usingComponents": {
|
||||
"t-search": "tdesign-miniprogram/search/search",
|
||||
"t-loading": "tdesign-miniprogram/loading/loading",
|
||||
|
||||
@@ -1,11 +1,25 @@
|
||||
<!--pages/demand/list/index.wxml-->
|
||||
<!-- <t-divider /> -->
|
||||
<view class="home-page-container">
|
||||
<view class="search" style="margin-bottom: 5rpx;" bind:tap="navToSearchPage">
|
||||
<t-search t-class-input="t-search__input" t-class-left="t-search__left-icon" placeholder="请输入关键词搜索" value="{{keywords}}" left-icon="{{null}}" bind:blur="onChangeInput" bind:change="onChangeInput" bind:submit="onChangeSearch">
|
||||
<t-icon slot="left-icon" prefix="" name="search" size="40rpx" color="#bbb" />
|
||||
<t-icon slot="action" bind:tap="onChangeSearch" prefix="" name="refresh" size="40rpx" color="#787878" />
|
||||
<view class="search-bar">
|
||||
<t-search
|
||||
t-class="search-bar__search"
|
||||
t-class-input-container="search-bar__box"
|
||||
t-class-input="search-bar__input"
|
||||
t-class-left="search-bar__left"
|
||||
shape="round"
|
||||
placeholder="搜索需求关键词"
|
||||
value="{{keywords}}"
|
||||
left-icon="{{null}}"
|
||||
bind:change="onChangeInput"
|
||||
bind:blur="onChangeInput"
|
||||
bind:submit="onChangeSearch"
|
||||
>
|
||||
<t-icon slot="left-icon" prefix="" name="search" size="36rpx" color="#b9bcc4" />
|
||||
</t-search>
|
||||
<view class="refresh-btn {{refreshing ? 'refresh-btn--loading' : ''}}" hover-class="refresh-btn--hover" bind:tap="onRefreshTap">
|
||||
<t-icon prefix="" name="refresh" size="38rpx" color="#787878" />
|
||||
</view>
|
||||
</view>
|
||||
<!-- <t-divider /> -->
|
||||
<view class="home-page-tabs">
|
||||
|
||||
@@ -22,15 +22,70 @@ page {
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.home-page-header .t-search__input-box {
|
||||
border-radius: 32rpx !important;
|
||||
height: 64rpx !important;
|
||||
margin-bottom: 8rpx;
|
||||
/* ===== 搜索区 ===== */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 18rpx 0 12rpx;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.home-page-header .t-search__input {
|
||||
.search-bar__search {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 0 !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.search-bar__box {
|
||||
height: 68rpx !important;
|
||||
border-radius: 34rpx !important;
|
||||
background: #fff !important;
|
||||
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.search-bar__input {
|
||||
font-size: 28rpx !important;
|
||||
color: rgb(116, 116, 116) !important;
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.search-bar__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
/* ===== 刷新按钮 ===== */
|
||||
.refresh-btn {
|
||||
flex-shrink: 0;
|
||||
width: 68rpx;
|
||||
height: 68rpx;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, opacity 0.15s ease;
|
||||
}
|
||||
|
||||
.refresh-btn--hover {
|
||||
transform: scale(0.92);
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.refresh-btn--loading {
|
||||
animation: refresh-spin 0.9s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes refresh-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.home-page-header .swiper-wrap {
|
||||
|
||||
@@ -38,24 +38,14 @@ Page({
|
||||
|
||||
onShow() {
|
||||
this.getTabBar().init();
|
||||
setTimeout(() => {
|
||||
fetchPerson().then((res) => {
|
||||
if (res.code === 1) {
|
||||
let { role } = res.data;
|
||||
this.setData({
|
||||
role,
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 3000);
|
||||
this.refreshRole();
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 先用本地缓存渲染入口按钮,避免接口返回前闪烁;随后由 onShow 用接口数据校正
|
||||
const role = (wx.getStorageSync('userInfo') || {}).role || '';
|
||||
this.setData({ role });
|
||||
this.init();
|
||||
let role = wx.getStorageSync('userInfo')?.role;
|
||||
if (role == 'dev') {
|
||||
this.toDemandHall();
|
||||
}
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
@@ -65,12 +55,31 @@ Page({
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.init();
|
||||
this.refreshRole();
|
||||
},
|
||||
|
||||
init() {
|
||||
this.loadHomePage();
|
||||
},
|
||||
|
||||
/**
|
||||
* 拉取最新角色并写回本地缓存
|
||||
* 入驻审核通过后,用户回到小程序触发 onShow 即可看到「进入接单大厅」入口
|
||||
*/
|
||||
refreshRole() {
|
||||
return fetchPerson().then((res) => {
|
||||
if (res.code === 1 && res.data) {
|
||||
const role = res.data.role || '';
|
||||
this.setData({ role });
|
||||
const userInfo = wx.getStorageSync('userInfo');
|
||||
if (userInfo && userInfo.role !== role) {
|
||||
userInfo.role = role;
|
||||
wx.setStorageSync('userInfo', userInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
loadHomePage() {
|
||||
wx.stopPullDownRefresh();
|
||||
this.setData({
|
||||
|
||||
Reference in New Issue
Block a user