更新
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\controller\qywx;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\lists\qywx\MsgArchiveLists;
|
||||
use app\adminapi\lists\qywx\MsgSendTaskLists;
|
||||
use app\adminapi\lists\qywx\MsgSessionLists;
|
||||
use app\adminapi\logic\qywx\MessageLogic;
|
||||
use app\adminapi\validate\qywx\MessageValidate;
|
||||
use app\common\service\wechat\QywxMsgArchiveService;
|
||||
use app\common\service\wechat\WechatWorkService;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 企业微信 员工↔客户 消息收发
|
||||
*
|
||||
* 接口一览:
|
||||
* GET qywx.message/session_list 会话列表(左侧)
|
||||
* GET qywx.message/archive_list 会话消息历史(中间)
|
||||
* POST qywx.message/mark_read 清零会话未读
|
||||
* POST qywx.message/send 创建企业群发(员工代发)任务
|
||||
* GET qywx.message/send_task_list 群发任务列表
|
||||
* GET qywx.message/send_task_detail 任务送达详情(会回调企微查询)
|
||||
* GET qywx.message/staff_list 可代发员工(admin 表 work_wechat_userid 不空者)
|
||||
* GET qywx.message/customer_of_staff 某员工已添加的客户
|
||||
* POST qywx.message/upload_to_qywx 上传媒体文件到企微,返回 media_id(供附件使用)
|
||||
* POST qywx.message/pull_archive 手动触发一次存档拉取(便于调试;cron 正常也会跑)
|
||||
* GET qywx.message/archive_status 会话存档模块状态(SDK/私钥诊断)
|
||||
*/
|
||||
class MessageController extends BaseAdminController
|
||||
{
|
||||
public function session_list()
|
||||
{
|
||||
return $this->dataLists(new MsgSessionLists());
|
||||
}
|
||||
|
||||
public function archive_list()
|
||||
{
|
||||
return $this->dataLists(new MsgArchiveLists());
|
||||
}
|
||||
|
||||
public function mark_read()
|
||||
{
|
||||
$sessionId = (int) $this->request->post('session_id', 0);
|
||||
if ($sessionId <= 0) {
|
||||
return $this->fail('session_id 无效');
|
||||
}
|
||||
MessageLogic::markSessionRead($sessionId);
|
||||
|
||||
return $this->success('ok');
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
$params = (new MessageValidate())->post()->goCheck('send');
|
||||
$result = MessageLogic::createSendTask($params, $this->adminId);
|
||||
if ($result === false) {
|
||||
return $this->fail(MessageLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('已提交,员工手机端确认后将发出', $result);
|
||||
}
|
||||
|
||||
public function send_task_list()
|
||||
{
|
||||
return $this->dataLists(new MsgSendTaskLists());
|
||||
}
|
||||
|
||||
public function send_task_detail()
|
||||
{
|
||||
$taskId = (int) $this->request->get('task_id', 0);
|
||||
$cursor = (string) $this->request->get('cursor', '');
|
||||
if ($taskId <= 0) {
|
||||
return $this->fail('task_id 无效');
|
||||
}
|
||||
|
||||
return $this->data(MessageLogic::querySendTaskResult($taskId, $cursor));
|
||||
}
|
||||
|
||||
public function staff_list()
|
||||
{
|
||||
$keyword = trim((string) $this->request->get('keyword', ''));
|
||||
|
||||
return $this->data(MessageLogic::staffList($keyword));
|
||||
}
|
||||
|
||||
public function customer_of_staff()
|
||||
{
|
||||
$staff = trim((string) $this->request->get('staff_userid', ''));
|
||||
$keyword = trim((string) $this->request->get('keyword', ''));
|
||||
$limit = (int) $this->request->get('limit', 200);
|
||||
|
||||
return $this->data(MessageLogic::customerOfStaff($staff, $keyword, $limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传素材到企业微信,返回 media_id(3 天有效)
|
||||
*
|
||||
* 入参:multipart 文件字段 file,query / form 字段 type = image|voice|video|file
|
||||
*
|
||||
* 使用场景:前端先上传本地文件到自家服务器(/upload/image 等)得到本地 URL 用于预览;
|
||||
* 确认发送时再调本接口上传到企微拿 media_id,填入 add_msg_template 的 attachments。
|
||||
*/
|
||||
public function upload_to_qywx()
|
||||
{
|
||||
$type = (string) $this->request->param('type', 'image');
|
||||
if (!in_array($type, ['image', 'voice', 'video', 'file'], true)) {
|
||||
return $this->fail('不支持的媒体类型');
|
||||
}
|
||||
$file = $this->request->file('file');
|
||||
if (!$file) {
|
||||
return $this->fail('未上传文件');
|
||||
}
|
||||
|
||||
try {
|
||||
$tempDir = runtime_path() . 'qywx_upload_tmp' . DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($tempDir)) {
|
||||
@mkdir($tempDir, 0755, true);
|
||||
}
|
||||
$savePath = $tempDir . uniqid('qywx_', true) . '_' . $file->getOriginalName();
|
||||
// @phpstan-ignore-next-line move returns File
|
||||
move_uploaded_file($file->getPathname(), $savePath);
|
||||
|
||||
$service = new WechatWorkService('customer_contact');
|
||||
$resp = $service->uploadMedia($type, $savePath, $file->getOriginalName());
|
||||
@unlink($savePath);
|
||||
|
||||
$errcode = isset($resp['errcode']) ? (int) $resp['errcode'] : -1;
|
||||
if ($errcode !== 0 || empty($resp['media_id'])) {
|
||||
Log::warning('企微上传素材失败: ' . json_encode($resp, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return $this->fail('企微上传失败: ' . ($resp['errmsg'] ?? '未知错误'));
|
||||
}
|
||||
|
||||
return $this->success('ok', [
|
||||
'media_id' => (string) $resp['media_id'],
|
||||
'type' => $resp['type'] ?? $type,
|
||||
'created_at' => $resp['created_at'] ?? time(),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('upload_to_qywx 异常: ' . $e->getMessage());
|
||||
|
||||
return $this->fail($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function pull_archive()
|
||||
{
|
||||
$maxBatches = (int) $this->request->param('max_batches', 5);
|
||||
$download = (bool) $this->request->param('download', false);
|
||||
|
||||
$pull = QywxMsgArchiveService::pullLoop(max(1, $maxBatches));
|
||||
$media = null;
|
||||
if ($download && $pull['enabled']) {
|
||||
$media = QywxMsgArchiveService::downloadPendingMedia(200);
|
||||
}
|
||||
|
||||
return $this->data([
|
||||
'pull' => $pull,
|
||||
'media' => $media,
|
||||
]);
|
||||
}
|
||||
|
||||
public function archive_status()
|
||||
{
|
||||
return $this->data(MessageLogic::archiveStatus());
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ class PrescriptionOrderController extends BaseAdminController
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('paidPayOrders');
|
||||
$exceptPo = (int) $this->request->get('prescription_order_id', 0);
|
||||
|
||||
$lists = OrderLogic::listPaidOrdersForDiagnosis(
|
||||
(int) $params['diagnosis_id'],
|
||||
$this->adminId,
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\qywx;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\QywxExternalContact;
|
||||
use app\common\model\QywxMsgArchive;
|
||||
use app\common\model\QywxMsgArchiveMedia;
|
||||
|
||||
/**
|
||||
* 单会话消息历史
|
||||
*
|
||||
* 两种查询模式,二选一:
|
||||
* 1) session_id 传 QywxMsgSession.id(推荐)
|
||||
* 2) staff_userid + external_userid(单聊)/ roomid(群聊)
|
||||
*
|
||||
* 消息默认按 send_time 升序,便于前端从下往上追加。
|
||||
* 支持 before_time / after_time 游标翻页。
|
||||
*/
|
||||
class MsgArchiveLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['roomid', 'msgtype'],
|
||||
];
|
||||
}
|
||||
|
||||
private function resolveScope(): array
|
||||
{
|
||||
$sessionId = (int) ($this->params['session_id'] ?? 0);
|
||||
if ($sessionId > 0) {
|
||||
$session = \app\common\model\QywxMsgSession::find($sessionId);
|
||||
if ($session) {
|
||||
return [
|
||||
'staff_userid' => (string) $session['staff_userid'],
|
||||
'external_userid' => (string) $session['external_userid'],
|
||||
'roomid' => (string) $session['roomid'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'staff_userid' => trim((string) ($this->params['staff_userid'] ?? '')),
|
||||
'external_userid' => trim((string) ($this->params['external_userid'] ?? '')),
|
||||
'roomid' => trim((string) ($this->params['roomid'] ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
private function baseQuery()
|
||||
{
|
||||
$scope = $this->resolveScope();
|
||||
$query = QywxMsgArchive::where($this->searchWhere);
|
||||
|
||||
if ($scope['roomid'] !== '') {
|
||||
$query->where('roomid', $scope['roomid']);
|
||||
} else {
|
||||
// 单聊:两端顺序不定,from_user/tolist 都可能为员工或客户
|
||||
$staff = $scope['staff_userid'];
|
||||
$external = $scope['external_userid'];
|
||||
if ($staff === '' && $external === '') {
|
||||
$query->where('id', 0);
|
||||
} else {
|
||||
$query->where('roomid', '');
|
||||
if ($staff !== '' && $external !== '') {
|
||||
$query->where(function ($q) use ($staff, $external) {
|
||||
$q->where(function ($sub) use ($staff, $external) {
|
||||
$sub->where('from_user', $staff)->whereLike('to_list', '%"' . $external . '"%');
|
||||
})->whereOr(function ($sub) use ($staff, $external) {
|
||||
$sub->where('from_user', $external)->whereLike('to_list', '%"' . $staff . '"%');
|
||||
});
|
||||
});
|
||||
} elseif ($staff !== '') {
|
||||
$query->where(function ($q) use ($staff) {
|
||||
$q->where('from_user', $staff)->whereOr('to_list', 'like', '%"' . $staff . '"%');
|
||||
});
|
||||
} else {
|
||||
$query->where(function ($q) use ($external) {
|
||||
$q->where('from_user', $external)->whereOr('to_list', 'like', '%"' . $external . '"%');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->params['before_time'])) {
|
||||
$query->where('send_time', '<', (int) $this->params['before_time']);
|
||||
}
|
||||
if (!empty($this->params['after_time'])) {
|
||||
$query->where('send_time', '>', (int) $this->params['after_time']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$rows = $this->baseQuery()
|
||||
->order('send_time', 'desc')
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
if (empty($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = array_reverse($rows); // 前端按时间升序渲染
|
||||
|
||||
$users = [];
|
||||
foreach ($rows as $r) {
|
||||
$users[$r['from_user']] = true;
|
||||
$toList = $r['to_list'];
|
||||
if (is_array($toList)) {
|
||||
foreach ($toList as $to) {
|
||||
$users[$to] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$users = array_keys(array_filter($users, fn ($_, $k) => $k !== '', ARRAY_FILTER_USE_BOTH));
|
||||
|
||||
$adminMap = [];
|
||||
$extMap = [];
|
||||
if ($users) {
|
||||
$adminMap = Admin::whereIn('work_wechat_userid', $users)
|
||||
->column('id,name,avatar,work_wechat_userid', 'work_wechat_userid');
|
||||
$extMap = QywxExternalContact::whereIn('external_userid', $users)
|
||||
->column('external_userid,name,avatar,type,unionid', 'external_userid');
|
||||
}
|
||||
|
||||
$msgIds = array_column($rows, 'msgid');
|
||||
$mediaMap = [];
|
||||
if ($msgIds) {
|
||||
$mediaList = QywxMsgArchiveMedia::whereIn('msgid', $msgIds)->select()->toArray();
|
||||
foreach ($mediaList as $m) {
|
||||
$mediaMap[$m['msgid']][] = $m;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($rows as &$r) {
|
||||
$fromId = (string) $r['from_user'];
|
||||
$r['from_is_staff'] = isset($adminMap[$fromId]);
|
||||
$r['from_profile'] = $adminMap[$fromId] ?? ($extMap[$fromId] ?? null);
|
||||
$r['media'] = $mediaMap[$r['msgid']] ?? [];
|
||||
}
|
||||
unset($r);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->baseQuery()->count();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\qywx;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\QywxMsgSendTask;
|
||||
|
||||
class MsgSendTaskLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['sender_userid', 'status', 'admin_id'],
|
||||
];
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
return QywxMsgSendTask::where($this->searchWhere)
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return QywxMsgSendTask::where($this->searchWhere)->count();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\qywx;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\QywxExternalContact;
|
||||
use app\common\model\QywxMsgSession;
|
||||
|
||||
/**
|
||||
* 企微消息会话列表
|
||||
*
|
||||
* 查询参数:
|
||||
* staff_userid - 过滤某员工的会话(支持传 admin_id 反查)
|
||||
* external_userid- 过滤某客户
|
||||
* keyword - 按客户名 / 摘要 模糊搜索
|
||||
* only_unread - 仅未读
|
||||
*/
|
||||
class MsgSessionLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['staff_userid', 'external_userid', 'roomid', 'session_type'],
|
||||
];
|
||||
}
|
||||
|
||||
private function baseQuery()
|
||||
{
|
||||
$query = QywxMsgSession::where($this->searchWhere);
|
||||
|
||||
$adminId = (int) ($this->params['admin_id'] ?? 0);
|
||||
if ($adminId > 0) {
|
||||
$wxId = Admin::where('id', $adminId)->value('work_wechat_userid');
|
||||
if ($wxId) {
|
||||
$query->where('staff_userid', $wxId);
|
||||
} else {
|
||||
// 找不到对应企微 userid 时不返回任何会话
|
||||
$query->where('id', 0);
|
||||
}
|
||||
}
|
||||
|
||||
$keyword = trim((string) ($this->params['keyword'] ?? ''));
|
||||
if ($keyword !== '') {
|
||||
$kw = addcslashes($keyword, '%_\\');
|
||||
$extIds = QywxExternalContact::whereLike('name', '%' . $kw . '%')->column('external_userid');
|
||||
$query->where(function ($q) use ($kw, $extIds) {
|
||||
$q->whereLike('last_msg_summary', '%' . $kw . '%');
|
||||
if ($extIds) {
|
||||
$q->whereOr('external_userid', 'in', $extIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!empty($this->params['only_unread'])) {
|
||||
$query->where('unread_staff', '>', 0);
|
||||
}
|
||||
|
||||
return $query->order('last_msg_time', 'desc');
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$rows = $this->baseQuery()
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
if (empty($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$extIds = array_values(array_unique(array_filter(array_map(
|
||||
fn ($r) => (string) ($r['external_userid'] ?? ''),
|
||||
$rows
|
||||
))));
|
||||
$extMap = [];
|
||||
if ($extIds) {
|
||||
$extMap = QywxExternalContact::whereIn('external_userid', $extIds)
|
||||
->column('name,avatar,type,gender,corp_name,unionid', 'external_userid');
|
||||
}
|
||||
|
||||
$staffIds = array_values(array_unique(array_filter(array_map(
|
||||
fn ($r) => (string) ($r['staff_userid'] ?? ''),
|
||||
$rows
|
||||
))));
|
||||
$staffMap = [];
|
||||
if ($staffIds) {
|
||||
$staffMap = Admin::whereIn('work_wechat_userid', $staffIds)
|
||||
->column('id,name,avatar', 'work_wechat_userid');
|
||||
}
|
||||
|
||||
foreach ($rows as &$r) {
|
||||
$r['customer'] = $extMap[$r['external_userid']] ?? null;
|
||||
$r['staff'] = $staffMap[$r['staff_userid']] ?? null;
|
||||
}
|
||||
unset($r);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->baseQuery()->count();
|
||||
}
|
||||
}
|
||||
@@ -924,9 +924,47 @@ class OrderLogic
|
||||
return count(array_intersect($myRoles, $supervisorRoles)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务订单可关联支付单列表:仅展示创建时间在此日 0 点及之后的支付单(编辑时当前单已关联的旧单仍保留在列表中)
|
||||
*/
|
||||
private static function payOrderLinkableMinCreateTs(): int
|
||||
{
|
||||
return strtotime('2026-04-20 00:00:00');
|
||||
}
|
||||
|
||||
/**
|
||||
* zyt_order.create_time 可能为 int 时间戳或 datetime 字符串,不可直接 (int) 强转(字符串会得到 0)
|
||||
*/
|
||||
private static function orderCreateTimeToUnix(mixed $value): int
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return 0;
|
||||
}
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
return $value->getTimestamp();
|
||||
}
|
||||
if (is_int($value)) {
|
||||
return $value;
|
||||
}
|
||||
if (is_float($value)) {
|
||||
return (int) $value;
|
||||
}
|
||||
if (is_string($value)) {
|
||||
if (is_numeric($value) && strlen($value) <= 12) {
|
||||
return (int) $value;
|
||||
}
|
||||
$ts = strtotime($value);
|
||||
|
||||
return $ts !== false ? $ts : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 某诊单下可关联的支付单(待支付/已支付),供关联业务订单多选(主管/诊单医助看该诊单全部;否则仅本人创建)
|
||||
* 已占用(关联到未撤回/未取消的业务订单)的支付单会排除;编辑某业务订单时传 $exceptPrescriptionOrderId 以保留当前单已选中的项
|
||||
* 列表仅含 2026-04-20 及之后创建的支付单(已关联到当前编辑业务订单的除外)
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
@@ -974,6 +1012,7 @@ class OrderLogic
|
||||
);
|
||||
}
|
||||
|
||||
$minCreateTs = self::payOrderLinkableMinCreateTs();
|
||||
$out = [];
|
||||
foreach ($rows as $row) {
|
||||
$oid = (int) ($row['id'] ?? 0);
|
||||
@@ -985,6 +1024,10 @@ class OrderLogic
|
||||
if ($busy && ! $allowed) {
|
||||
continue;
|
||||
}
|
||||
$ct = self::orderCreateTimeToUnix($row['create_time'] ?? null);
|
||||
if ($ct < $minCreateTs && ! $allowed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$out[] = $row;
|
||||
}
|
||||
@@ -994,11 +1037,17 @@ class OrderLogic
|
||||
|
||||
/**
|
||||
* 校验支付单均可关联到指定诊单(已支付、归属与权限)
|
||||
* 默认仅允许关联 2026-04-20 及之后创建的支付单;编辑业务订单时传入 $prescriptionOrderIdForDateGrace,已关联到该业务订单的旧单除外
|
||||
*
|
||||
* @param int[] $ids zyt_order.id
|
||||
*/
|
||||
public static function assertPayOrdersLinkable(array $ids, int $diagnosisId, int $adminId, array $adminInfo): ?string
|
||||
{
|
||||
public static function assertPayOrdersLinkable(
|
||||
array $ids,
|
||||
int $diagnosisId,
|
||||
int $adminId,
|
||||
array $adminInfo,
|
||||
?int $prescriptionOrderIdForDateGrace = null
|
||||
): ?string {
|
||||
$ids = array_values(array_unique(array_filter(array_map('intval', $ids), static fn(int $v): bool => $v > 0)));
|
||||
if ($diagnosisId <= 0) {
|
||||
return '诊单无效';
|
||||
@@ -1021,6 +1070,7 @@ class OrderLogic
|
||||
return '部分支付单不存在或已删除';
|
||||
}
|
||||
|
||||
$minTs = self::payOrderLinkableMinCreateTs();
|
||||
foreach ($orders as $o) {
|
||||
if ((int) $o->patient_id !== $diagnosisId) {
|
||||
return '支付单与诊单不匹配';
|
||||
@@ -1031,6 +1081,18 @@ class OrderLogic
|
||||
if (! $supervisor && ! $isDiagAssistant && (int) $o->creator_id !== $adminId) {
|
||||
return '无权限关联所选支付单';
|
||||
}
|
||||
$ct = self::orderCreateTimeToUnix($o->create_time ?? null);
|
||||
if ($ct < $minTs) {
|
||||
$grace = false;
|
||||
if ($prescriptionOrderIdForDateGrace !== null && $prescriptionOrderIdForDateGrace > 0) {
|
||||
$grace = PrescriptionOrderPayOrder::where('prescription_order_id', $prescriptionOrderIdForDateGrace)
|
||||
->where('pay_order_id', (int) $o->id)
|
||||
->count() > 0;
|
||||
}
|
||||
if (! $grace) {
|
||||
return '仅可关联 2026年4月20日及之后创建的支付单';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -595,9 +595,36 @@ class CustomerLogic extends BaseLogic
|
||||
}
|
||||
|
||||
$service = new WechatWorkService();
|
||||
$detail = $service->getExternalContactDetail($externalUserId);
|
||||
$detail = [];
|
||||
$lastError = null;
|
||||
// 接口偶发抖动:最多重试 1 次(共 2 次请求),间隔 1.2s。仅对「非预期错误 / 空响应」重试,
|
||||
// 业务预期错误(如 84061 客户未通过、60011/60111 无权限、41068 非法 ID)不重试,避免无谓压力。
|
||||
$maxAttempts = 2;
|
||||
for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
|
||||
$err = null;
|
||||
$detail = $service->getExternalContactDetail($externalUserId, $err);
|
||||
if (!empty($detail['external_contact']) && is_array($detail['external_contact'])) {
|
||||
break;
|
||||
}
|
||||
$lastError = $err;
|
||||
$errcode = is_array($err) ? ($err['errcode'] ?? null) : null;
|
||||
$shouldRetry = $attempt < $maxAttempts
|
||||
&& !in_array($errcode, [84061, 41068, 60011, 60111], true);
|
||||
if (!$shouldRetry) {
|
||||
break;
|
||||
}
|
||||
usleep(1_200_000);
|
||||
}
|
||||
|
||||
if (empty($detail['external_contact']) || !is_array($detail['external_contact'])) {
|
||||
Log::warning('qywx external contact callback: 拉取详情为空', ['external_userid' => $externalUserId]);
|
||||
$errcode = is_array($lastError) ? ($lastError['errcode'] ?? null) : null;
|
||||
$errmsg = is_array($lastError) ? (string) ($lastError['errmsg'] ?? '') : '';
|
||||
Log::warning(sprintf(
|
||||
'qywx external contact callback: 拉取详情为空,跳过 UPSERT errcode=%s errmsg=%s ext=%s',
|
||||
$errcode === null ? '?' : (string) $errcode,
|
||||
$errmsg !== '' ? $errmsg : '-',
|
||||
$externalUserId
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\logic\qywx;
|
||||
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\QywxExternalContact;
|
||||
use app\common\model\QywxMsgSendTask;
|
||||
use app\common\model\QywxMsgSession;
|
||||
use app\common\service\wechat\WeComFinanceSdkClient;
|
||||
use app\common\service\wechat\WechatWorkService;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 企业微信消息业务逻辑
|
||||
*
|
||||
* - 员工代发消息:企业群发 add_msg_template(客户端显示为员工本人,员工手机端需确认)
|
||||
* - 消息历史:来自会话内容存档落库(见 QywxMsgArchiveService)
|
||||
* - 本类只封装"创建任务 + 查询送达 + 辅助接口",不处理拉取
|
||||
*/
|
||||
class MessageLogic extends BaseLogic
|
||||
{
|
||||
/**
|
||||
* 创建企业群发任务
|
||||
*
|
||||
* @param array{sender_userid:string, external_userids:string[], msg_payload:array, chat_type?:string} $params
|
||||
* @param int $adminId 后台发起人
|
||||
*
|
||||
* @return array{task_id:int, msg_template_id:string, fail_list: array}|false
|
||||
*/
|
||||
public static function createSendTask(array $params, int $adminId)
|
||||
{
|
||||
$chatType = (string) ($params['chat_type'] ?? 'single');
|
||||
$sender = (string) $params['sender_userid'];
|
||||
$externalIds = array_values(array_filter(array_map('strval', $params['external_userids'] ?? [])));
|
||||
$payload = (array) $params['msg_payload'];
|
||||
|
||||
if ($externalIds === []) {
|
||||
self::setError('请至少选择 1 位客户');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$body = self::buildAddMsgTemplateBody($chatType, $sender, $externalIds, $payload);
|
||||
if ($body === null) {
|
||||
// setError 已在 buildAddMsgTemplateBody 内调
|
||||
return false;
|
||||
}
|
||||
|
||||
$task = QywxMsgSendTask::create([
|
||||
'admin_id' => $adminId,
|
||||
'sender_userid' => $sender,
|
||||
'external_userids' => $externalIds,
|
||||
'chat_type' => $chatType === 'group' ? 2 : 1,
|
||||
'msg_payload' => $payload,
|
||||
'status' => QywxMsgSendTask::STATUS_PENDING,
|
||||
'create_time' => time(),
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
try {
|
||||
$service = new WechatWorkService('customer_contact');
|
||||
$resp = $service->addMsgTemplate($body);
|
||||
$errcode = isset($resp['errcode']) ? (int) $resp['errcode'] : -1;
|
||||
$errmsg = (string) ($resp['errmsg'] ?? '');
|
||||
$msgid = (string) ($resp['msgid'] ?? '');
|
||||
$failList = isset($resp['fail_list']) && is_array($resp['fail_list']) ? $resp['fail_list'] : [];
|
||||
|
||||
if ($errcode !== 0 || $msgid === '') {
|
||||
QywxMsgSendTask::where('id', $task['id'])->update([
|
||||
'status' => QywxMsgSendTask::STATUS_FAILED,
|
||||
'error' => sprintf('errcode=%d errmsg=%s', $errcode, $errmsg),
|
||||
'fail_list' => $failList,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
self::setError(sprintf('企微群发失败: [%d] %s', $errcode, $errmsg ?: '未知错误'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QywxMsgSendTask::where('id', $task['id'])->update([
|
||||
'status' => QywxMsgSendTask::STATUS_SUBMITTED,
|
||||
'msg_template_id' => $msgid,
|
||||
'fail_list' => $failList,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
return [
|
||||
'task_id' => (int) $task['id'],
|
||||
'msg_template_id' => $msgid,
|
||||
'fail_list' => $failList,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('企微群发创建异常: ' . $e->getMessage());
|
||||
QywxMsgSendTask::where('id', $task['id'])->update([
|
||||
'status' => QywxMsgSendTask::STATUS_FAILED,
|
||||
'error' => mb_substr('exception: ' . $e->getMessage(), 0, 500),
|
||||
'update_time' => time(),
|
||||
]);
|
||||
self::setError($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询群发任务送达结果(企业微信返回每客户的确认/送达状态)
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function querySendTaskResult(int $taskId, string $cursor = ''): array
|
||||
{
|
||||
$task = QywxMsgSendTask::find($taskId);
|
||||
if (!$task || $task['msg_template_id'] === '') {
|
||||
return ['detail_list' => [], 'next_cursor' => '', 'task' => $task];
|
||||
}
|
||||
$service = new WechatWorkService('customer_contact');
|
||||
$resp = $service->getGroupMsgSendResult($task['msg_template_id'], $task['sender_userid'], $cursor, 500);
|
||||
$errcode = isset($resp['errcode']) ? (int) $resp['errcode'] : -1;
|
||||
if ($errcode !== 0) {
|
||||
return [
|
||||
'detail_list' => [],
|
||||
'next_cursor' => '',
|
||||
'task' => $task,
|
||||
'errcode' => $errcode,
|
||||
'errmsg' => (string) ($resp['errmsg'] ?? ''),
|
||||
];
|
||||
}
|
||||
$detailList = $resp['detail_list'] ?? [];
|
||||
$nextCursor = (string) ($resp['next_cursor'] ?? '');
|
||||
|
||||
if (is_array($detailList) && !empty($detailList)) {
|
||||
$sentCount = 0;
|
||||
foreach ($detailList as $d) {
|
||||
if (($d['status'] ?? 0) == 1) { // 1=已送达
|
||||
$sentCount++;
|
||||
}
|
||||
}
|
||||
if ($sentCount > 0 && $task['status'] == QywxMsgSendTask::STATUS_SUBMITTED) {
|
||||
QywxMsgSendTask::where('id', $task['id'])->update([
|
||||
'status' => QywxMsgSendTask::STATUS_SENT,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'detail_list' => $detailList,
|
||||
'next_cursor' => $nextCursor,
|
||||
'task' => $task->refresh(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 可代发员工列表(只返回已绑定企微 userid 的 admin)
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function staffList(string $keyword = ''): array
|
||||
{
|
||||
$query = Admin::where('work_wechat_userid', '<>', '')
|
||||
->whereNotNull('work_wechat_userid');
|
||||
if ($keyword !== '') {
|
||||
$kw = addcslashes($keyword, '%_\\');
|
||||
$query->where(function ($q) use ($kw) {
|
||||
$q->whereLike('name', '%' . $kw . '%')
|
||||
->whereOr('work_wechat_userid', 'like', '%' . $kw . '%');
|
||||
});
|
||||
}
|
||||
|
||||
return $query->field('id,name,avatar,work_wechat_userid as userid,department')
|
||||
->limit(200)
|
||||
->order('id', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 某员工的已添加客户列表(基于 follow_users JSON 查询)
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function customerOfStaff(string $staffUserid, string $keyword = '', int $limit = 200): array
|
||||
{
|
||||
if ($staffUserid === '') {
|
||||
return [];
|
||||
}
|
||||
$query = QywxExternalContact::whereLike('follow_users', '%"userid":"' . $staffUserid . '"%');
|
||||
if ($keyword !== '') {
|
||||
$kw = addcslashes($keyword, '%_\\');
|
||||
$query->whereLike('name', '%' . $kw . '%');
|
||||
}
|
||||
|
||||
return $query->field('external_userid,name,avatar,type,gender,corp_name,unionid')
|
||||
->limit($limit)
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function markSessionRead(int $sessionId): bool
|
||||
{
|
||||
$affected = QywxMsgSession::where('id', $sessionId)->update([
|
||||
'unread_staff' => 0,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
return $affected >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 会话存档模块状态
|
||||
*/
|
||||
public static function archiveStatus(): array
|
||||
{
|
||||
$client = new WeComFinanceSdkClient();
|
||||
|
||||
return [
|
||||
'enabled' => (bool) config('pay.wechat_work.msgaudit_enabled', false),
|
||||
'available' => $client->isAvailable(),
|
||||
'error' => $client->getLastError(),
|
||||
'lib_path' => (string) config('pay.wechat_work.msgaudit_sdk_lib_path', ''),
|
||||
'public_key_ver' => (int) config('pay.wechat_work.msgaudit_public_key_ver', 0),
|
||||
'has_private_key' => self::hasPrivateKeyConfigured(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function hasPrivateKeyConfigured(): bool
|
||||
{
|
||||
$path = (string) config('pay.wechat_work.msgaudit_private_key_path', '');
|
||||
if ($path !== '' && is_file($path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ((string) config('pay.wechat_work.msgaudit_private_key', '')) !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 add_msg_template 请求体
|
||||
*
|
||||
* msg_payload 标准形:
|
||||
* {
|
||||
* "text": { "content": "你好" },
|
||||
* "attachments": [
|
||||
* { "msgtype":"image", "image":{"media_id":"xxx"} },
|
||||
* { "msgtype":"video", "video":{"media_id":"xxx"} },
|
||||
* { "msgtype":"file", "file":{"media_id":"xxx"} },
|
||||
* { "msgtype":"link", "link":{"title":"...","picurl":"...","desc":"...","url":"https://..."} },
|
||||
* { "msgtype":"miniprogram", "miniprogram":{"title":"...","pic_media_id":"...","appid":"wx...","page":"/pages/x/x"} }
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private static function buildAddMsgTemplateBody(
|
||||
string $chatType,
|
||||
string $sender,
|
||||
array $externalIds,
|
||||
array $payload
|
||||
): ?array {
|
||||
$text = $payload['text'] ?? null;
|
||||
$attachments = $payload['attachments'] ?? null;
|
||||
if (($text === null || !isset($text['content']) || trim((string) $text['content']) === '')
|
||||
&& empty($attachments)) {
|
||||
self::setError('消息内容不能为空:至少填写文本或添加 1 个附件');
|
||||
|
||||
return null;
|
||||
}
|
||||
if (is_array($attachments) && count($attachments) > 9) {
|
||||
self::setError('最多只能添加 9 个附件');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$body = [
|
||||
'chat_type' => $chatType === 'group' ? 'group' : 'single',
|
||||
'external_userid' => array_values($externalIds),
|
||||
'sender' => $sender,
|
||||
];
|
||||
if (is_array($text) && trim((string) ($text['content'] ?? '')) !== '') {
|
||||
$body['text'] = ['content' => (string) $text['content']];
|
||||
}
|
||||
if (is_array($attachments) && $attachments !== []) {
|
||||
$body['attachments'] = array_values(array_filter($attachments, 'is_array'));
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
}
|
||||
@@ -680,6 +680,17 @@ class PrescriptionOrderLogic
|
||||
|
||||
return false;
|
||||
}
|
||||
// 已成功提交甘草 SCM(生成了甘草处方单号 或 submit_time>0),再改本地信息会与甘草侧不一致,禁止编辑
|
||||
$gcOrderNo = trim((string) $order->gancao_reciperl_order_no);
|
||||
$gcSubmitTime = (int) $order->gancao_submit_time;
|
||||
if ($gcOrderNo !== '' || $gcSubmitTime > 0) {
|
||||
self::$error = sprintf(
|
||||
'订单已提交甘草(处方单号:%s),不可再编辑;如需修改请先走取消流程',
|
||||
$gcOrderNo !== '' ? $gcOrderNo : '—'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$medDays = $params['medication_days'] ?? null;
|
||||
$medDays = $medDays === '' || $medDays === null ? null : (int) $medDays;
|
||||
@@ -727,7 +738,7 @@ class PrescriptionOrderLogic
|
||||
$payOrderIds = array_values(array_intersect($payOrderIds, $existingIds));
|
||||
}
|
||||
|
||||
$linkErr = OrderLogic::assertPayOrdersLinkable($payOrderIds, $diagId, $adminId, $adminInfo);
|
||||
$linkErr = OrderLogic::assertPayOrdersLinkable($payOrderIds, $diagId, $adminId, $adminInfo, (int) $order->id);
|
||||
if ($linkErr !== null) {
|
||||
self::$error = $linkErr;
|
||||
|
||||
@@ -748,7 +759,7 @@ class PrescriptionOrderLogic
|
||||
$order->linked_pay_order_id = null;
|
||||
} else {
|
||||
$single = [(int) $lp];
|
||||
$linkErr = OrderLogic::assertPayOrdersLinkable($single, $diagId, $adminId, $adminInfo);
|
||||
$linkErr = OrderLogic::assertPayOrdersLinkable($single, $diagId, $adminId, $adminInfo, (int) $order->id);
|
||||
if ($linkErr !== null) {
|
||||
self::$error = $linkErr;
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\validate\qywx;
|
||||
|
||||
use app\common\validate\BaseValidate;
|
||||
|
||||
class MessageValidate extends BaseValidate
|
||||
{
|
||||
protected $rule = [
|
||||
'sender_userid' => 'require',
|
||||
'external_userids' => 'require|array|min:1',
|
||||
'msg_payload' => 'require|array',
|
||||
'chat_type' => 'in:single,group',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'sender_userid.require' => '请选择代发员工',
|
||||
'external_userids.require' => '请选择至少一位客户',
|
||||
'external_userids.array' => '客户列表格式错误',
|
||||
'external_userids.min' => '至少选择 1 位客户',
|
||||
'msg_payload.require' => '请填写消息内容',
|
||||
'msg_payload.array' => '消息内容格式错误',
|
||||
'chat_type.in' => '会话类型不合法',
|
||||
];
|
||||
|
||||
public function sceneSend()
|
||||
{
|
||||
return $this->only(['sender_userid', 'external_userids', 'msg_payload', 'chat_type']);
|
||||
}
|
||||
|
||||
public function sceneMarkRead()
|
||||
{
|
||||
return $this->only(['session_id'])->append('session_id', 'require|integer|>:0');
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,15 @@ use think\facade\Log;
|
||||
* 企业微信「客户联系」事件回调(接收事件服务器)
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/92130
|
||||
*
|
||||
* ⚠️ 关于"员工↔客户消息内容"接收:
|
||||
* 企业微信 **不会** 通过本回调推送客户与员工之间真实的聊天消息内容,
|
||||
* 这里只处理"添加 / 编辑 / 删除客户"等业务事件(change_external_contact 变体)。
|
||||
* 实时消息接收走「会话内容存档」独立通道:
|
||||
* - 命令: php think qywx:sync-msg-archive
|
||||
* - 服务: app\common\service\wechat\QywxMsgArchiveService
|
||||
* - SDK: app\common\service\wechat\WeComFinanceSdkClient (FFI 调 libWeWorkFinanceSdk_C.so)
|
||||
* 配置项:pay.wechat_work.msgaudit_*。
|
||||
*/
|
||||
class QywxExternalContactCallbackController extends BaseApiController
|
||||
{
|
||||
@@ -23,12 +32,16 @@ class QywxExternalContactCallbackController extends BaseApiController
|
||||
public function notify()
|
||||
{
|
||||
$corpId = (string) config('pay.wechat_work.corp_id', '');
|
||||
$secret = (string) config('pay.wechat_work.external_pay_secret', '');
|
||||
$customerSecret = (string) config('pay.wechat_work.customer_contact_secret', '');
|
||||
$payContactSecret = (string) config('pay.wechat_work.external_pay_secret', '');
|
||||
// 客户联系回调验签需用「接收事件服务器」所属应用的 Secret,优先使用 customer_contact_secret,
|
||||
// 缺省回退到 external_pay_secret 保持向后兼容(同一应用同时具备两类权限的旧部署可继续工作)。
|
||||
$secret = $customerSecret !== '' ? $customerSecret : $payContactSecret;
|
||||
$token = (string) config('pay.wechat_work.contact_callback_token', '');
|
||||
$aesKey = (string) config('pay.wechat_work.contact_callback_aes_key', '');
|
||||
|
||||
if ($corpId === '' || $secret === '' || $token === '' || $aesKey === '') {
|
||||
Log::error('qywx external contact callback: 缺少配置 corp_id / external_pay_secret / contact_callback_token / contact_callback_aes_key');
|
||||
Log::error('qywx external contact callback: 缺少配置 corp_id / customer_contact_secret(或 external_pay_secret) / contact_callback_token / contact_callback_aes_key');
|
||||
|
||||
return response('config error', 503, ['Content-Type' => 'text/plain; charset=utf-8']);
|
||||
}
|
||||
@@ -84,14 +97,27 @@ class QywxExternalContactCallbackController extends BaseApiController
|
||||
{
|
||||
$changeType = (string) ($message['ChangeType'] ?? '');
|
||||
$extId = trim((string) ($message['ExternalUserID'] ?? $message['ExternalUserId'] ?? ''));
|
||||
$userId = trim((string) ($message['UserID'] ?? $message['UserId'] ?? ''));
|
||||
$state = (string) ($message['State'] ?? '');
|
||||
$welcomeCode = (string) ($message['WelcomeCode'] ?? '');
|
||||
$failReason = (string) ($message['FailReason'] ?? '');
|
||||
|
||||
if ($extId === '') {
|
||||
Log::info('qywx external contact callback: 无 ExternalUserID', ['ChangeType' => $changeType]);
|
||||
Log::info(sprintf('qywx external contact callback: 无 ExternalUserID type=%s user=%s', $changeType, $userId));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info('qywx external contact callback', ['ChangeType' => $changeType, 'ExternalUserID' => $extId]);
|
||||
// 关键字段直接拼到消息里,便于在 ThinkPHP file 日志格式下一眼定位 ChangeType 分布
|
||||
Log::info(sprintf(
|
||||
'qywx external contact callback type=%s user=%s ext=%s state=%s welcome=%s fail=%s',
|
||||
$changeType !== '' ? $changeType : '-',
|
||||
$userId !== '' ? $userId : '-',
|
||||
$extId,
|
||||
$state !== '' ? $state : '-',
|
||||
$welcomeCode !== '' ? '***' : '-',
|
||||
$failReason !== '' ? $failReason : '-'
|
||||
));
|
||||
|
||||
if ($changeType === 'del_external_contact') {
|
||||
CustomerLogic::softDeleteExternalContactRow($extId);
|
||||
@@ -99,7 +125,15 @@ class QywxExternalContactCallbackController extends BaseApiController
|
||||
return;
|
||||
}
|
||||
|
||||
// 其余变更(添加/编辑/删跟进人等):以 get 详情为准 UPSERT,避免遗漏未枚举的 ChangeType
|
||||
if ($changeType === 'add_half_external_contact') {
|
||||
// 半客户:客户尚未通过验证,/externalcontact/get 通常返回 84061「客户尚未通过」之类,
|
||||
// 这里只 log 不写库,避免产生 noise;客户通过后会再触发 add_external_contact 事件再走 UPSERT。
|
||||
Log::info(sprintf('qywx external contact callback: half add,跳过落库 ext=%s user=%s', $extId, $userId));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 其余变更(添加/编辑/删跟进人/转接成功/标签变化等):以 get 详情为准 UPSERT,避免遗漏未枚举的 ChangeType
|
||||
CustomerLogic::upsertSingleExternalContactFromApi($extId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use app\common\service\wechat\QywxMsgArchiveService;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 企业微信会话内容存档同步
|
||||
*
|
||||
* 使用方法:
|
||||
* php think qywx:sync-msg-archive # 只拉消息
|
||||
* php think qywx:sync-msg-archive --download # 拉完后同时下载 pending 媒体
|
||||
* php think qywx:sync-msg-archive --only-media # 仅下载已登记的 pending 媒体
|
||||
*
|
||||
* crontab 建议:每 30 秒拉一次(用 sleep 模拟半分钟级)
|
||||
* * * * * * cd /path/to/project && php think qywx:sync-msg-archive --download >> /dev/null 2>&1
|
||||
* * * * * * cd /path/to/project && sleep 30 && php think qywx:sync-msg-archive --download >> /dev/null 2>&1
|
||||
*
|
||||
* 并发控制:通过文件锁,同一时刻只会跑一个,多开直接退出。
|
||||
*/
|
||||
class QywxSyncMsgArchive extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('qywx:sync-msg-archive')
|
||||
->addOption('download', 'd', Option::VALUE_NONE, '拉完消息后顺便下载 pending 媒体')
|
||||
->addOption('only-media', null, Option::VALUE_NONE, '仅下载已登记的 pending 媒体')
|
||||
->addOption('max-batches', 'b', Option::VALUE_REQUIRED, '单次运行最多拉多少批 (默认 20)', 20)
|
||||
->addOption('max-media', 'm', Option::VALUE_REQUIRED, '单次最多下载多少条媒体 (默认 200)', 200)
|
||||
->setDescription('拉取企业微信会话内容存档');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$lockFile = runtime_path() . 'lock' . DIRECTORY_SEPARATOR . 'qywx_msg_archive.lock';
|
||||
$lockDir = dirname($lockFile);
|
||||
if (!is_dir($lockDir)) {
|
||||
@mkdir($lockDir, 0755, true);
|
||||
}
|
||||
$fp = @fopen($lockFile, 'c');
|
||||
if ($fp === false) {
|
||||
$output->writeln('<error>无法创建锁文件: ' . $lockFile . '</error>');
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (!flock($fp, LOCK_EX | LOCK_NB)) {
|
||||
fclose($fp);
|
||||
$output->writeln('另一个会话存档同步进程正在运行,跳过本次。');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
$onlyMedia = (bool) $input->getOption('only-media');
|
||||
$download = (bool) $input->getOption('download');
|
||||
$maxBatches = max(1, (int) $input->getOption('max-batches'));
|
||||
$maxMedia = max(1, (int) $input->getOption('max-media'));
|
||||
|
||||
if (!$onlyMedia) {
|
||||
$pull = QywxMsgArchiveService::pullLoop($maxBatches);
|
||||
if (!$pull['enabled']) {
|
||||
$output->writeln('<comment>会话存档未启用或 SDK 不可用:' . implode('; ', $pull['errors']) . '</comment>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
$output->writeln(sprintf(
|
||||
'消息拉取:batches=%d pulled=%d inserted=%d updated=%d media_pending=%d last_seq=%d',
|
||||
$pull['batches'],
|
||||
$pull['pulled'],
|
||||
$pull['inserted'],
|
||||
$pull['updated'],
|
||||
$pull['media_pending'],
|
||||
$pull['last_seq']
|
||||
));
|
||||
if (!empty($pull['errors'])) {
|
||||
foreach ($pull['errors'] as $err) {
|
||||
Log::warning('qywx:sync-msg-archive pull error: ' . $err);
|
||||
$output->writeln('<comment>error: ' . $err . '</comment>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($onlyMedia || $download) {
|
||||
$media = QywxMsgArchiveService::downloadPendingMedia($maxMedia);
|
||||
if (!$media['enabled']) {
|
||||
$output->writeln('<comment>媒体下载-SDK 未启用</comment>');
|
||||
} else {
|
||||
$output->writeln(sprintf(
|
||||
'媒体下载:ok=%d failed=%d skipped=%d',
|
||||
$media['ok'],
|
||||
$media['failed'],
|
||||
$media['skipped']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
} catch (\Throwable $e) {
|
||||
$output->writeln('<error>同步异常: ' . $e->getMessage() . '</error>');
|
||||
Log::error('qywx:sync-msg-archive 异常: ' . $e->getMessage());
|
||||
|
||||
return 1;
|
||||
} finally {
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
/**
|
||||
* 企业微信会话存档消息
|
||||
*
|
||||
* 数据来源为「会话内容存档」SDK 拉取后解密落库,msgid 官方唯一。
|
||||
* 消息体字段根据 msgtype 有不同含义,统一用 content(摘要/文本)+ raw(原始 JSON)组合存储,
|
||||
* 具体渲染放到业务层(前端或 Logic)再按需展开。
|
||||
*/
|
||||
class QywxMsgArchive extends BaseModel
|
||||
{
|
||||
protected $name = 'qywx_msg_archive';
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
|
||||
protected $type = [
|
||||
'send_time' => 'integer',
|
||||
'seq' => 'integer',
|
||||
'file_size' => 'integer',
|
||||
'play_length' => 'integer',
|
||||
];
|
||||
|
||||
/** JSON 反序列化 to_list 访问器,便于业务层直接拿数组 */
|
||||
public function getToListAttr($value): array
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return [];
|
||||
}
|
||||
if (is_array($value)) {
|
||||
return $value;
|
||||
}
|
||||
$decoded = json_decode((string) $value, true);
|
||||
return is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
public function setToListAttr($value): string
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
class QywxMsgArchiveCursor extends BaseModel
|
||||
{
|
||||
protected $name = 'qywx_msg_archive_cursor';
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
|
||||
public const DEFAULT_KEY = 'global';
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
class QywxMsgArchiveMedia extends BaseModel
|
||||
{
|
||||
protected $name = 'qywx_msg_archive_media';
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
|
||||
public const STATUS_PENDING = 0;
|
||||
public const STATUS_SUCCESS = 1;
|
||||
public const STATUS_FAILED = 2;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
/**
|
||||
* 员工代发消息(企业群发)任务
|
||||
*
|
||||
* 企业群发 add_msg_template 的特性:
|
||||
* - 必须以「员工身份」为 sender 代发,客户端显示为员工本人
|
||||
* - 员工手机端会弹一次"发送确认",员工点确认后才真正送达客户;admin 后台无法强制送达
|
||||
* - 返回的 msgid 可通过 get_group_msg_send_result 查询确认 / 送达结果
|
||||
*
|
||||
* 状态:
|
||||
* 0=待提交、1=已提交等待员工确认、2=员工已确认发送、3=失败
|
||||
*/
|
||||
class QywxMsgSendTask extends BaseModel
|
||||
{
|
||||
protected $name = 'qywx_msg_send_task';
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
|
||||
public const STATUS_PENDING = 0;
|
||||
public const STATUS_SUBMITTED = 1;
|
||||
public const STATUS_SENT = 2;
|
||||
public const STATUS_FAILED = 3;
|
||||
|
||||
public function getExternalUseridsAttr($value): array
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return [];
|
||||
}
|
||||
$decoded = json_decode((string) $value, true);
|
||||
return is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
public function setExternalUseridsAttr($value): string
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
public function getMsgPayloadAttr($value)
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return [];
|
||||
}
|
||||
$decoded = json_decode((string) $value, true);
|
||||
return is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
public function setMsgPayloadAttr($value): string
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
public function getFailListAttr($value)
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return [];
|
||||
}
|
||||
$decoded = json_decode((string) $value, true);
|
||||
return is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
public function setFailListAttr($value): string
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
/**
|
||||
* 企业微信 员工×客户 会话索引(用于 admin 聊天页左侧会话列表)
|
||||
*/
|
||||
class QywxMsgSession extends BaseModel
|
||||
{
|
||||
protected $name = 'qywx_msg_session';
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
}
|
||||
@@ -62,14 +62,18 @@ final class GancaoOpenApiTransport
|
||||
'Expect:',
|
||||
];
|
||||
|
||||
// cURL 常量在部分精简构建里可能未注册,统一用 defined() 做优雅降级,值取自官方枚举
|
||||
$httpVer11 = defined('CURL_HTTP_VERSION_1_1') ? CURL_HTTP_VERSION_1_1 : 2;
|
||||
$ipv4Only = defined('CURL_IPRESOLVE_V4') ? CURL_IPRESOLVE_V4 : 1;
|
||||
|
||||
$ch = curl_init($this->url);
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); // 改用 HTTP/1.1
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, $httpVer11); // 改用 HTTP/1.1
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
|
||||
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
curl_setopt($ch, CURLOPT_IPRESOLVE, $ipv4Only);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 增加连接超时
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $cipher);
|
||||
@@ -77,14 +81,25 @@ final class GancaoOpenApiTransport
|
||||
if (str_starts_with($this->url, 'https:')) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 改为 0,完全禁用主机验证
|
||||
// 添加 SSL 相关选项
|
||||
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // 强制使用 TLS 1.2
|
||||
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'DEFAULT@SECLEVEL=1'); // 降低安全级别
|
||||
// 强制 TLS 1.2;常量值为 6,但部分 PHP/cURL 构建未注册该常量,运行时未定义时退化为默认 TLS
|
||||
$tls12 = defined('CURL_SSLVERSION_TLSv1_2') ? CURL_SSLVERSION_TLSv1_2 : 6;
|
||||
curl_setopt($ch, CURLOPT_SSLVERSION, $tls12);
|
||||
// 可选 cipher list。默认不设(交给 cURL 自带默认,兼容性最好)。
|
||||
// 需要兼容弱加密服务器时,在 config/gancao_scm.php 或 .env 里设:
|
||||
// GANCAO_SCM_TLS_CIPHERS="DEFAULT@SECLEVEL=1" // 仅 OpenSSL 构建的 cURL 支持此语法
|
||||
// GANCAO_SCM_TLS_CIPHERS="DEFAULT:!aNULL:!eNULL" // 通用写法
|
||||
// cURL 是 LibreSSL/NSS/GnuTLS/BoringSSL 时,@SECLEVEL= 会直接报 CURLE_SSL_CIPHER(59)。
|
||||
$cipherList = trim((string) \think\facade\Config::get('gancao_scm.tls_ciphers', ''));
|
||||
if ($cipherList !== '') {
|
||||
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, $cipherList);
|
||||
}
|
||||
}
|
||||
// 添加 TCP keepalive(部分旧 libcurl 可能没注册 CURLOPT_TCP_KEEPALIVE,守一下)
|
||||
if (defined('CURLOPT_TCP_KEEPALIVE')) {
|
||||
curl_setopt($ch, CURLOPT_TCP_KEEPALIVE, 1);
|
||||
curl_setopt($ch, CURLOPT_TCP_KEEPIDLE, 120);
|
||||
curl_setopt($ch, CURLOPT_TCP_KEEPINTVL, 60);
|
||||
}
|
||||
// 添加 TCP keepalive
|
||||
curl_setopt($ch, CURLOPT_TCP_KEEPALIVE, 1);
|
||||
curl_setopt($ch, CURLOPT_TCP_KEEPIDLE, 120);
|
||||
curl_setopt($ch, CURLOPT_TCP_KEEPINTVL, 60);
|
||||
|
||||
$raw = curl_exec($ch);
|
||||
$info = curl_getinfo($ch);
|
||||
|
||||
@@ -0,0 +1,516 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service\wechat;
|
||||
|
||||
use app\common\model\QywxMsgArchive;
|
||||
use app\common\model\QywxMsgArchiveCursor;
|
||||
use app\common\model\QywxMsgArchiveMedia;
|
||||
use app\common\model\QywxMsgSession;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 会话存档拉取与落库
|
||||
*
|
||||
* 工作流程:
|
||||
* 1) 读取游标 seq
|
||||
* 2) 调用 WeComFinanceSdkClient->pullChatData(seq)
|
||||
* 3) 遍历解密后的消息,按 msgtype 归一化字段后 UPSERT qywx_msg_archive
|
||||
* 4) 同步刷新 qywx_msg_session 列表摘要
|
||||
* 5) 媒体消息登记 qywx_msg_archive_media(待下载)
|
||||
* 6) 更新 cursor
|
||||
*
|
||||
* 媒体下载由 downloadPendingMedia() 独立跑,避免拉取慢。
|
||||
*/
|
||||
class QywxMsgArchiveService
|
||||
{
|
||||
private const MEDIA_TYPES = ['image', 'voice', 'video', 'file', 'emotion'];
|
||||
|
||||
/**
|
||||
* 拉一次,直到本批为空或达到 maxBatches
|
||||
*
|
||||
* @return array{
|
||||
* enabled: bool,
|
||||
* batches: int,
|
||||
* pulled: int,
|
||||
* inserted: int,
|
||||
* updated: int,
|
||||
* media_pending: int,
|
||||
* last_seq: int,
|
||||
* errors: string[]
|
||||
* }
|
||||
*/
|
||||
public static function pullLoop(int $maxBatches = 20, string $cursorKey = QywxMsgArchiveCursor::DEFAULT_KEY): array
|
||||
{
|
||||
$result = [
|
||||
'enabled' => true,
|
||||
'batches' => 0,
|
||||
'pulled' => 0,
|
||||
'inserted' => 0,
|
||||
'updated' => 0,
|
||||
'media_pending' => 0,
|
||||
'last_seq' => 0,
|
||||
'errors' => [],
|
||||
];
|
||||
|
||||
$sdk = new WeComFinanceSdkClient();
|
||||
if (!$sdk->isAvailable()) {
|
||||
$result['enabled'] = false;
|
||||
$result['errors'][] = $sdk->getLastError();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$seq = self::getCursorSeq($cursorKey);
|
||||
$result['last_seq'] = $seq;
|
||||
|
||||
for ($i = 0; $i < $maxBatches; $i++) {
|
||||
$batch = $sdk->pullChatData($seq);
|
||||
$result['batches']++;
|
||||
|
||||
if (!$batch['ok']) {
|
||||
$result['errors'][] = $batch['error'];
|
||||
self::touchCursor($cursorKey, $seq, 0, $batch['error']);
|
||||
break;
|
||||
}
|
||||
|
||||
$messages = $batch['messages'];
|
||||
$count = count($messages);
|
||||
if ($count === 0) {
|
||||
self::touchCursor($cursorKey, $seq, 0, '');
|
||||
break;
|
||||
}
|
||||
|
||||
[$inserted, $updated, $mediaPending] = self::persistBatch($messages);
|
||||
$result['pulled'] += $count;
|
||||
$result['inserted'] += $inserted;
|
||||
$result['updated'] += $updated;
|
||||
$result['media_pending'] += $mediaPending;
|
||||
|
||||
$seq = (int) $batch['next_seq'];
|
||||
$result['last_seq'] = $seq;
|
||||
self::touchCursor($cursorKey, $seq, $count, '');
|
||||
|
||||
if ($count < $sdk->getLimit()) {
|
||||
// 本批不足 limit,说明暂无更多,结束本轮
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载 pending 的媒体文件
|
||||
*
|
||||
* @return array{enabled: bool, ok: int, failed: int, skipped: int, errors: string[]}
|
||||
*/
|
||||
public static function downloadPendingMedia(int $max = 200): array
|
||||
{
|
||||
$result = ['enabled' => true, 'ok' => 0, 'failed' => 0, 'skipped' => 0, 'errors' => []];
|
||||
|
||||
$sdk = new WeComFinanceSdkClient();
|
||||
if (!$sdk->isAvailable()) {
|
||||
$result['enabled'] = false;
|
||||
$result['errors'][] = $sdk->getLastError();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$rows = QywxMsgArchiveMedia::where('status', QywxMsgArchiveMedia::STATUS_PENDING)
|
||||
->where('retry_count', '<', 5)
|
||||
->order('id', 'asc')
|
||||
->limit($max)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$sdkFileid = (string) $row['sdkfileid'];
|
||||
if ($sdkFileid === '') {
|
||||
$result['skipped']++;
|
||||
continue;
|
||||
}
|
||||
$relPath = self::buildMediaRelPath((string) $row['msgid'], $sdkFileid);
|
||||
$absPath = self::absoluteMediaPath($relPath);
|
||||
|
||||
$ret = $sdk->downloadMedia($sdkFileid, $absPath);
|
||||
$now = time();
|
||||
if ($ret['ok']) {
|
||||
QywxMsgArchiveMedia::where('id', $row['id'])->update([
|
||||
'status' => QywxMsgArchiveMedia::STATUS_SUCCESS,
|
||||
'file_path' => $relPath,
|
||||
'file_size' => $ret['size'],
|
||||
'error' => '',
|
||||
'update_time' => $now,
|
||||
]);
|
||||
$result['ok']++;
|
||||
} else {
|
||||
QywxMsgArchiveMedia::where('id', $row['id'])->update([
|
||||
'retry_count' => (int) $row['retry_count'] + 1,
|
||||
'status' => ((int) $row['retry_count'] + 1) >= 5 ? QywxMsgArchiveMedia::STATUS_FAILED : QywxMsgArchiveMedia::STATUS_PENDING,
|
||||
'error' => mb_substr($ret['error'], 0, 500),
|
||||
'update_time' => $now,
|
||||
]);
|
||||
$result['failed']++;
|
||||
$result['errors'][] = sprintf('msgid=%s err=%s', (string) $row['msgid'], $ret['error']);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $messages
|
||||
*
|
||||
* @return array{0:int,1:int,2:int} [inserted, updated, mediaPending]
|
||||
*/
|
||||
private static function persistBatch(array $messages): array
|
||||
{
|
||||
$inserted = 0;
|
||||
$updated = 0;
|
||||
$mediaPending = 0;
|
||||
$now = time();
|
||||
|
||||
foreach ($messages as $msg) {
|
||||
$norm = self::normalize($msg);
|
||||
if ($norm === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$isUpdate = false;
|
||||
Db::transaction(function () use ($norm, $now, &$inserted, &$updated, &$mediaPending, &$isUpdate) {
|
||||
$exists = QywxMsgArchive::where('msgid', $norm['msgid'])->findOrEmpty();
|
||||
if ($exists->isEmpty()) {
|
||||
QywxMsgArchive::create(array_merge($norm, [
|
||||
'create_time' => $now,
|
||||
'update_time' => $now,
|
||||
]));
|
||||
$inserted++;
|
||||
} else {
|
||||
// recall/switch 会重发相同 msgid,更新 action / content
|
||||
QywxMsgArchive::where('msgid', $norm['msgid'])->update(array_merge($norm, [
|
||||
'update_time' => $now,
|
||||
]));
|
||||
$updated++;
|
||||
$isUpdate = true;
|
||||
}
|
||||
|
||||
if ($norm['media_id'] !== '' && in_array($norm['msgtype'], self::MEDIA_TYPES, true)) {
|
||||
$existsMedia = QywxMsgArchiveMedia::where('msgid', $norm['msgid'])
|
||||
->where('sdkfileid', $norm['media_id'])
|
||||
->findOrEmpty();
|
||||
if ($existsMedia->isEmpty()) {
|
||||
QywxMsgArchiveMedia::create([
|
||||
'msgid' => $norm['msgid'],
|
||||
'sdkfileid' => $norm['media_id'],
|
||||
'status' => QywxMsgArchiveMedia::STATUS_PENDING,
|
||||
'md5sum' => $norm['md5sum'],
|
||||
'create_time' => $now,
|
||||
'update_time' => $now,
|
||||
]);
|
||||
$mediaPending++;
|
||||
}
|
||||
}
|
||||
|
||||
self::upsertSession($norm, $now);
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
Log::error(sprintf(
|
||||
'会话存档-消息落库异常 msgid=%s err=%s',
|
||||
(string) ($norm['msgid'] ?? '-'),
|
||||
$e->getMessage()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return [$inserted, $updated, $mediaPending];
|
||||
}
|
||||
|
||||
/**
|
||||
* 把解密后的原始消息归一化为数据库字段
|
||||
*
|
||||
* @param array<string, mixed> $msg
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
public static function normalize(array $msg): ?array
|
||||
{
|
||||
$msgid = (string) ($msg['msgid'] ?? $msg['__msgid_sdk'] ?? '');
|
||||
if ($msgid === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$action = (string) ($msg['action'] ?? 'send'); // send / recall / switch
|
||||
$msgtype = (string) ($msg['msgtype'] ?? '');
|
||||
$from = (string) ($msg['from'] ?? '');
|
||||
$roomid = (string) ($msg['roomid'] ?? '');
|
||||
$tolist = isset($msg['tolist']) && is_array($msg['tolist']) ? $msg['tolist'] : [];
|
||||
$sendTime = isset($msg['msgtime']) ? (int) (((int) $msg['msgtime']) / 1000) : 0;
|
||||
if ($sendTime === 0 && isset($msg['msgtime'])) {
|
||||
// 兼容已经是秒的情况
|
||||
$sendTime = (int) $msg['msgtime'];
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$mediaId = '';
|
||||
$md5sum = '';
|
||||
$fileName = '';
|
||||
$fileSize = 0;
|
||||
$fileExt = '';
|
||||
$playLength = 0;
|
||||
|
||||
switch ($msgtype) {
|
||||
case 'text':
|
||||
$content = (string) ($msg['text']['content'] ?? '');
|
||||
break;
|
||||
case 'markdown':
|
||||
$content = (string) ($msg['markdown']['content'] ?? '');
|
||||
break;
|
||||
case 'image':
|
||||
$mediaId = (string) ($msg['image']['sdkfileid'] ?? '');
|
||||
$md5sum = (string) ($msg['image']['md5sum'] ?? '');
|
||||
$fileSize = (int) ($msg['image']['filesize'] ?? 0);
|
||||
$content = '[图片]';
|
||||
break;
|
||||
case 'voice':
|
||||
$mediaId = (string) ($msg['voice']['sdkfileid'] ?? '');
|
||||
$md5sum = (string) ($msg['voice']['md5sum'] ?? '');
|
||||
$fileSize = (int) ($msg['voice']['voice_size'] ?? 0);
|
||||
$playLength = (int) ($msg['voice']['play_length'] ?? 0);
|
||||
$content = sprintf('[语音 %ds]', $playLength);
|
||||
break;
|
||||
case 'video':
|
||||
$mediaId = (string) ($msg['video']['sdkfileid'] ?? '');
|
||||
$md5sum = (string) ($msg['video']['md5sum'] ?? '');
|
||||
$fileSize = (int) ($msg['video']['filesize'] ?? 0);
|
||||
$playLength = (int) ($msg['video']['play_length'] ?? 0);
|
||||
$content = '[视频]';
|
||||
break;
|
||||
case 'emotion':
|
||||
$mediaId = (string) ($msg['emotion']['sdkfileid'] ?? '');
|
||||
$md5sum = (string) ($msg['emotion']['md5sum'] ?? '');
|
||||
$fileSize = (int) ($msg['emotion']['imagesize'] ?? 0);
|
||||
$content = '[表情]';
|
||||
break;
|
||||
case 'file':
|
||||
$mediaId = (string) ($msg['file']['sdkfileid'] ?? '');
|
||||
$md5sum = (string) ($msg['file']['md5sum'] ?? '');
|
||||
$fileName = (string) ($msg['file']['filename'] ?? '');
|
||||
$fileExt = (string) ($msg['file']['fileext'] ?? '');
|
||||
$fileSize = (int) ($msg['file']['filesize'] ?? 0);
|
||||
$content = '[文件] ' . $fileName;
|
||||
break;
|
||||
case 'link':
|
||||
$content = (string) ($msg['link']['title'] ?? '[链接]');
|
||||
break;
|
||||
case 'weapp':
|
||||
$content = '[小程序] ' . (string) ($msg['weapp']['title'] ?? '');
|
||||
break;
|
||||
case 'chatrecord':
|
||||
$content = '[聊天记录]';
|
||||
break;
|
||||
case 'location':
|
||||
$content = '[位置] ' . (string) ($msg['location']['address'] ?? '');
|
||||
break;
|
||||
case 'card':
|
||||
$content = '[名片]';
|
||||
break;
|
||||
case 'revoke':
|
||||
$action = 'recall';
|
||||
$content = '[撤回] ' . (string) ($msg['revoke']['pre_msgid'] ?? '');
|
||||
break;
|
||||
case 'mixed':
|
||||
$content = self::summarizeMixed($msg['mixed'] ?? null);
|
||||
break;
|
||||
case 'meeting':
|
||||
$content = '[会议] ' . (string) ($msg['meeting']['topic'] ?? '');
|
||||
break;
|
||||
case 'docmsg':
|
||||
$content = '[文档] ' . (string) ($msg['docmsg']['title'] ?? '');
|
||||
break;
|
||||
default:
|
||||
$content = '[' . $msgtype . ']';
|
||||
}
|
||||
|
||||
return [
|
||||
'msgid' => $msgid,
|
||||
'seq' => (int) ($msg['__seq'] ?? 0),
|
||||
'action' => $action,
|
||||
'from_user' => $from,
|
||||
'from_type' => 0, // 外层 session upsert 时再判定
|
||||
'to_list' => $tolist,
|
||||
'roomid' => $roomid,
|
||||
'msgtype' => $msgtype,
|
||||
'content' => mb_substr($content, 0, 16000),
|
||||
'media_id' => $mediaId,
|
||||
'md5sum' => $md5sum,
|
||||
'file_name' => mb_substr($fileName, 0, 500),
|
||||
'file_size' => $fileSize,
|
||||
'file_ext' => $fileExt,
|
||||
'play_length' => $playLength,
|
||||
'raw' => json_encode($msg, JSON_UNESCAPED_UNICODE),
|
||||
'send_time' => $sendTime,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mixed
|
||||
*/
|
||||
private static function summarizeMixed($mixed): string
|
||||
{
|
||||
if (!is_array($mixed) || !isset($mixed['item']) || !is_array($mixed['item'])) {
|
||||
return '[混合消息]';
|
||||
}
|
||||
$parts = [];
|
||||
foreach ($mixed['item'] as $el) {
|
||||
if (!is_array($el)) {
|
||||
continue;
|
||||
}
|
||||
$t = (string) ($el['type'] ?? '');
|
||||
if ($t === 'text') {
|
||||
$parts[] = (string) ($el['content'] ?? '');
|
||||
} else {
|
||||
$parts[] = '[' . $t . ']';
|
||||
}
|
||||
if (count($parts) >= 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return implode(' ', $parts);
|
||||
}
|
||||
|
||||
private static function upsertSession(array $norm, int $now): void
|
||||
{
|
||||
// 外部联系人 id 的企微前缀通常是 "wm" 或 "wo";员工 userid 无此前缀。
|
||||
// 单聊时 tolist 有 1 个对端;群聊走 roomid。
|
||||
$tolist = $norm['to_list'] ?? [];
|
||||
if ($norm['roomid'] !== '') {
|
||||
$sessionType = 2;
|
||||
$staff = self::isStaffUserid($norm['from_user']) ? $norm['from_user'] : '';
|
||||
if ($staff === '') {
|
||||
foreach ($tolist as $to) {
|
||||
if (self::isStaffUserid($to)) {
|
||||
$staff = (string) $to;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$external = '';
|
||||
} else {
|
||||
$sessionType = 1;
|
||||
if (self::isStaffUserid($norm['from_user'])) {
|
||||
$staff = $norm['from_user'];
|
||||
$external = (string) ($tolist[0] ?? '');
|
||||
} else {
|
||||
$external = $norm['from_user'];
|
||||
$staff = (string) ($tolist[0] ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
if ($staff === '' && $norm['roomid'] === '') {
|
||||
// 兜底:两端都辨不出,跳过 session 更新
|
||||
return;
|
||||
}
|
||||
|
||||
$where = [
|
||||
'staff_userid' => $staff,
|
||||
'external_userid' => $external,
|
||||
'roomid' => $norm['roomid'],
|
||||
];
|
||||
|
||||
$summary = mb_substr((string) $norm['content'], 0, 500);
|
||||
$data = [
|
||||
'session_type' => $sessionType,
|
||||
'last_msg_id' => $norm['msgid'],
|
||||
'last_msg_seq' => $norm['seq'],
|
||||
'last_msg_time' => $norm['send_time'],
|
||||
'last_msg_type' => $norm['msgtype'],
|
||||
'last_msg_summary' => $summary,
|
||||
'update_time' => $now,
|
||||
];
|
||||
|
||||
$existing = QywxMsgSession::where($where)->findOrEmpty();
|
||||
if ($existing->isEmpty()) {
|
||||
QywxMsgSession::create(array_merge($where, $data, [
|
||||
'unread_staff' => self::isStaffUserid($norm['from_user']) ? 0 : 1,
|
||||
'create_time' => $now,
|
||||
]));
|
||||
} else {
|
||||
// 仅当本条更新,才覆盖最近消息字段
|
||||
if ((int) $existing['last_msg_time'] <= (int) $norm['send_time']) {
|
||||
if (!self::isStaffUserid($norm['from_user'])) {
|
||||
$data['unread_staff'] = (int) $existing['unread_staff'] + 1;
|
||||
}
|
||||
QywxMsgSession::where('id', $existing['id'])->update($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 粗判 userid 是员工还是外部联系人:企微外部联系人 id 以 "wm"/"wo" 开头且长度较长;
|
||||
* 员工 userid 是管理员配置的,通常是字母/数字无这两个前缀。
|
||||
*/
|
||||
private static function isStaffUserid(string $id): bool
|
||||
{
|
||||
if ($id === '') {
|
||||
return false;
|
||||
}
|
||||
$lower = strtolower($id);
|
||||
if (strpos($lower, 'wm') === 0 || strpos($lower, 'wo') === 0) {
|
||||
// 仍需长度判断:员工 userid 以 wm 开头的极少见;外部联系人通常 20+ 字符
|
||||
return strlen($id) < 20;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function buildMediaRelPath(string $msgid, string $sdkFileid): string
|
||||
{
|
||||
$hash = substr(md5($msgid . ':' . $sdkFileid), 0, 16);
|
||||
|
||||
return 'qywx_archive/' . date('Ymd') . '/' . $hash;
|
||||
}
|
||||
|
||||
private static function absoluteMediaPath(string $relPath): string
|
||||
{
|
||||
$base = rtrim((string) config('filesystem.disks.public.root', public_path() . 'storage'), DIRECTORY_SEPARATOR);
|
||||
|
||||
return $base . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $relPath);
|
||||
}
|
||||
|
||||
private static function getCursorSeq(string $cursorKey): int
|
||||
{
|
||||
$row = QywxMsgArchiveCursor::where('cursor_key', $cursorKey)->findOrEmpty();
|
||||
|
||||
return $row->isEmpty() ? 0 : (int) $row['seq'];
|
||||
}
|
||||
|
||||
private static function touchCursor(string $cursorKey, int $seq, int $pullCount, string $error): void
|
||||
{
|
||||
$now = time();
|
||||
$row = QywxMsgArchiveCursor::where('cursor_key', $cursorKey)->findOrEmpty();
|
||||
if ($row->isEmpty()) {
|
||||
QywxMsgArchiveCursor::create([
|
||||
'cursor_key' => $cursorKey,
|
||||
'seq' => $seq,
|
||||
'last_pull_time' => $now,
|
||||
'last_pull_count' => $pullCount,
|
||||
'last_error' => mb_substr($error, 0, 500),
|
||||
'create_time' => $now,
|
||||
'update_time' => $now,
|
||||
]);
|
||||
} else {
|
||||
QywxMsgArchiveCursor::where('id', $row['id'])->update([
|
||||
'seq' => $seq,
|
||||
'last_pull_time' => $now,
|
||||
'last_pull_count' => $pullCount,
|
||||
'last_error' => mb_substr($error, 0, 500),
|
||||
'update_time' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service\wechat;
|
||||
|
||||
use FFI;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 仅为 IDE/静态分析"看见" FFI::cdef 绑定的 C 函数,不会在运行时使用;
|
||||
* 运行时 $this->ffi 是真正的 FFI 实例,方法是 FFI::cdef 动态注入。
|
||||
*
|
||||
* @method \FFI\CData NewSdk()
|
||||
* @method int Init(\FFI\CData $sdk, string $corpid, string $secret)
|
||||
* @method void DestroySdk(\FFI\CData $sdk)
|
||||
* @method int GetChatData(\FFI\CData $sdk, int $seq, int $limit, string $proxy, string $passwd, int $timeout, \FFI\CData $out)
|
||||
* @method int DecryptData(string $encryptKey, string $encryptMsg, \FFI\CData $out)
|
||||
* @method int GetMediaData(\FFI\CData $sdk, string $indexbuf, string $sdkFileid, string $proxy, string $passwd, int $timeout, \FFI\CData $out)
|
||||
* @method \FFI\CData NewSlice()
|
||||
* @method void FreeSlice(\FFI\CData $slice)
|
||||
* @method \FFI\CData GetContentFromSlice(\FFI\CData $slice)
|
||||
* @method int GetSliceLen(\FFI\CData $slice)
|
||||
* @method \FFI\CData NewMediaData()
|
||||
* @method void FreeMediaData(\FFI\CData $md)
|
||||
* @method \FFI\CData GetOutIndexBuf(\FFI\CData $md)
|
||||
* @method \FFI\CData GetData(\FFI\CData $md)
|
||||
* @method int GetIndexLen(\FFI\CData $md)
|
||||
* @method int GetDataLen(\FFI\CData $md)
|
||||
* @method int IsMediaDataFinish(\FFI\CData $md)
|
||||
*/
|
||||
interface WeComFinanceSdkBinding
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业微信「会话内容存档」官方 C SDK 的 PHP FFI 封装
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/91774 会话存档开发接入指南
|
||||
*
|
||||
* 官方动态库(需自行下载后放到服务器):
|
||||
* Linux: libWeWorkFinanceSdk_C.so
|
||||
* Windows: WeWorkFinanceSdk.dll
|
||||
*
|
||||
* 下载地址:https://developer.work.weixin.qq.com/document/path/91883
|
||||
*
|
||||
* 关键点:
|
||||
* 1. 调用 GetChatData 获取一批 encrypt_random_key + encrypt_chat_msg
|
||||
* 2. encrypt_random_key 是 RSA 公钥加密的,需用企业后台上传公钥对应的私钥解出 AES 密钥
|
||||
* 3. AES 密钥 + encrypt_chat_msg 调 DecryptData 得到最终明文 JSON
|
||||
* 4. 消息 msgtype 为 image/voice/video/file/emotion/chatrecord(含 voip_doc_share) 时需额外调 GetMediaData
|
||||
* 可能分片返回(is_finish=0 时带 out_index_buf 继续下一片)
|
||||
*
|
||||
* 本类对「SDK 未安装 / 未启用」场景做了 noop 兼容:构造时若 `msgaudit_enabled=false`
|
||||
* 或动态库路径为空,则 isAvailable() 返回 false,所有操作返回安全空结构,不抛异常。
|
||||
* 上层(Archive 拉取命令)按 isAvailable() 分支。
|
||||
*/
|
||||
class WeComFinanceSdkClient
|
||||
{
|
||||
/** @var FFI&WeComFinanceSdkBinding|null */
|
||||
private $ffi = null;
|
||||
|
||||
/** @var \FFI\CData|null NewSdk() 的返回值 */
|
||||
private $sdk = null;
|
||||
|
||||
private bool $inited = false;
|
||||
private bool $available = false;
|
||||
|
||||
private string $corpId = '';
|
||||
private string $secret = '';
|
||||
private string $libPath = '';
|
||||
private string $proxy = '';
|
||||
private string $proxyPasswd = '';
|
||||
private int $timeout = 60;
|
||||
private int $limit = 500;
|
||||
|
||||
/** @var array<int, string> 私钥 PEM,按 public_key_ver 索引(允许配置多版本轮换) */
|
||||
private array $privateKeys = [];
|
||||
|
||||
private string $lastError = '';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$enabled = (bool) config('pay.wechat_work.msgaudit_enabled', false);
|
||||
$this->corpId = (string) config('pay.wechat_work.corp_id', '');
|
||||
$this->secret = (string) config('pay.wechat_work.msgaudit_secret', '');
|
||||
$this->libPath = (string) config('pay.wechat_work.msgaudit_sdk_lib_path', '');
|
||||
$this->proxy = (string) config('pay.wechat_work.msgaudit_proxy', '');
|
||||
$this->proxyPasswd = (string) config('pay.wechat_work.msgaudit_proxy_passwd', '');
|
||||
$this->timeout = (int) config('pay.wechat_work.msgaudit_timeout', 60);
|
||||
$this->limit = (int) config('pay.wechat_work.msgaudit_limit', 500);
|
||||
|
||||
$this->privateKeys = $this->loadPrivateKeys();
|
||||
|
||||
if (!$enabled) {
|
||||
$this->lastError = 'msgaudit not enabled';
|
||||
|
||||
return;
|
||||
}
|
||||
if ($this->corpId === '' || $this->secret === '' || $this->libPath === '') {
|
||||
$this->lastError = 'msgaudit config incomplete (corp_id / msgaudit_secret / msgaudit_sdk_lib_path)';
|
||||
|
||||
return;
|
||||
}
|
||||
if (!extension_loaded('ffi')) {
|
||||
$this->lastError = 'php ffi extension not loaded';
|
||||
|
||||
return;
|
||||
}
|
||||
if (!is_file($this->libPath)) {
|
||||
$this->lastError = 'msgaudit sdk lib not found: ' . $this->libPath;
|
||||
|
||||
return;
|
||||
}
|
||||
if (empty($this->privateKeys)) {
|
||||
$this->lastError = 'msgaudit private key not configured';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->ffi = FFI::cdef($this->cdef(), $this->libPath);
|
||||
$this->sdk = $this->ffi->NewSdk();
|
||||
$ret = $this->ffi->Init($this->sdk, $this->corpId, $this->secret);
|
||||
if ($ret !== 0) {
|
||||
$this->lastError = 'SDK Init failed, ret=' . $ret;
|
||||
$this->ffi->DestroySdk($this->sdk);
|
||||
$this->sdk = null;
|
||||
|
||||
return;
|
||||
}
|
||||
$this->inited = true;
|
||||
$this->available = true;
|
||||
} catch (\Throwable $e) {
|
||||
$this->lastError = 'FFI error: ' . $e->getMessage();
|
||||
$this->sdk = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
try {
|
||||
if ($this->sdk !== null && $this->ffi !== null) {
|
||||
$this->ffi->DestroySdk($this->sdk);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// 忽略析构异常
|
||||
}
|
||||
}
|
||||
|
||||
public function isAvailable(): bool
|
||||
{
|
||||
return $this->available;
|
||||
}
|
||||
|
||||
public function getLastError(): string
|
||||
{
|
||||
return $this->lastError;
|
||||
}
|
||||
|
||||
public function getTimeout(): int
|
||||
{
|
||||
return $this->timeout;
|
||||
}
|
||||
|
||||
public function getLimit(): int
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取一批消息;返回解密后的明文数组(每条含 msgid、action、msgtype、content-like 字段等)
|
||||
*
|
||||
* @param int $seq 上次拉取到的最大 seq,首次传 0
|
||||
* @param int $limit 单次条数,官方上限 1000
|
||||
*
|
||||
* @return array{
|
||||
* ok: bool,
|
||||
* error: string,
|
||||
* messages: array<int, array<string, mixed>>,
|
||||
* next_seq: int,
|
||||
* }
|
||||
*/
|
||||
public function pullChatData(int $seq = 0, ?int $limit = null): array
|
||||
{
|
||||
if (!$this->available) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'error' => $this->lastError !== '' ? $this->lastError : 'sdk unavailable',
|
||||
'messages' => [],
|
||||
'next_seq' => $seq,
|
||||
];
|
||||
}
|
||||
|
||||
$limit = $limit === null ? $this->limit : $limit;
|
||||
$limit = (int) min(1000, max(1, $limit));
|
||||
|
||||
$slice = null;
|
||||
try {
|
||||
$slice = $this->ffi->NewSlice();
|
||||
$ret = $this->ffi->GetChatData(
|
||||
$this->sdk,
|
||||
$seq,
|
||||
$limit,
|
||||
$this->proxy,
|
||||
$this->proxyPasswd,
|
||||
$this->timeout,
|
||||
$slice
|
||||
);
|
||||
if ($ret !== 0) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'error' => 'GetChatData failed, ret=' . $ret,
|
||||
'messages' => [],
|
||||
'next_seq' => $seq,
|
||||
];
|
||||
}
|
||||
|
||||
$json = $this->sliceToString($slice);
|
||||
$decoded = json_decode($json, true);
|
||||
if (!is_array($decoded) || !isset($decoded['chatdata']) || !is_array($decoded['chatdata'])) {
|
||||
return [
|
||||
'ok' => true,
|
||||
'error' => '',
|
||||
'messages' => [],
|
||||
'next_seq' => $seq,
|
||||
];
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
$nextSeq = $seq;
|
||||
foreach ($decoded['chatdata'] as $entry) {
|
||||
if (!is_array($entry)) {
|
||||
continue;
|
||||
}
|
||||
$curSeq = isset($entry['seq']) ? (int) $entry['seq'] : 0;
|
||||
if ($curSeq > $nextSeq) {
|
||||
$nextSeq = $curSeq;
|
||||
}
|
||||
|
||||
$plain = $this->decryptChatItem($entry);
|
||||
if ($plain === null) {
|
||||
continue;
|
||||
}
|
||||
$plain['__seq'] = $curSeq;
|
||||
$plain['__msgid_sdk'] = (string) ($entry['msgid'] ?? ($plain['msgid'] ?? ''));
|
||||
$plain['__publickey_ver'] = (int) ($entry['publickey_ver'] ?? 0);
|
||||
$messages[] = $plain;
|
||||
}
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'error' => '',
|
||||
'messages' => $messages,
|
||||
'next_seq' => $nextSeq,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'error' => 'exception: ' . $e->getMessage(),
|
||||
'messages' => [],
|
||||
'next_seq' => $seq,
|
||||
];
|
||||
} finally {
|
||||
if ($slice !== null) {
|
||||
try {
|
||||
$this->ffi->FreeSlice($slice);
|
||||
} catch (\Throwable $e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体(image/voice/video/file/emotion)到本地文件
|
||||
*
|
||||
* @param string $sdkFileid 消息明文里的 sdkfileid
|
||||
* @param string $destPath 目标绝对路径
|
||||
*
|
||||
* @return array{ok: bool, error: string, size: int}
|
||||
*/
|
||||
public function downloadMedia(string $sdkFileid, string $destPath): array
|
||||
{
|
||||
if (!$this->available) {
|
||||
return ['ok' => false, 'error' => $this->lastError !== '' ? $this->lastError : 'sdk unavailable', 'size' => 0];
|
||||
}
|
||||
if ($sdkFileid === '') {
|
||||
return ['ok' => false, 'error' => 'empty sdkfileid', 'size' => 0];
|
||||
}
|
||||
|
||||
$dir = dirname($destPath);
|
||||
if (!is_dir($dir) && !mkdir($dir, 0755, true) && !is_dir($dir)) {
|
||||
return ['ok' => false, 'error' => 'mkdir failed: ' . $dir, 'size' => 0];
|
||||
}
|
||||
|
||||
$fp = @fopen($destPath, 'wb');
|
||||
if ($fp === false) {
|
||||
return ['ok' => false, 'error' => 'fopen failed: ' . $destPath, 'size' => 0];
|
||||
}
|
||||
|
||||
$indexBuf = '';
|
||||
$totalSize = 0;
|
||||
$chunkCount = 0;
|
||||
$maxChunks = 10000; // 安全上限,防止 SDK 异常时死循环
|
||||
|
||||
try {
|
||||
while ($chunkCount++ < $maxChunks) {
|
||||
$mediaData = $this->ffi->NewMediaData();
|
||||
try {
|
||||
$ret = $this->ffi->GetMediaData(
|
||||
$this->sdk,
|
||||
$indexBuf,
|
||||
$sdkFileid,
|
||||
$this->proxy,
|
||||
$this->proxyPasswd,
|
||||
$this->timeout,
|
||||
$mediaData
|
||||
);
|
||||
if ($ret !== 0) {
|
||||
fclose($fp);
|
||||
@unlink($destPath);
|
||||
|
||||
return ['ok' => false, 'error' => 'GetMediaData failed, ret=' . $ret . ' chunk=' . $chunkCount, 'size' => 0];
|
||||
}
|
||||
|
||||
$dataLen = (int) $this->ffi->GetDataLen($mediaData);
|
||||
if ($dataLen > 0) {
|
||||
$dataPtr = $this->ffi->GetData($mediaData);
|
||||
$chunk = FFI::string($dataPtr, $dataLen);
|
||||
fwrite($fp, $chunk);
|
||||
$totalSize += strlen($chunk);
|
||||
}
|
||||
|
||||
$isFinish = (int) $this->ffi->IsMediaDataFinish($mediaData);
|
||||
if ($isFinish === 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
$indexLen = (int) $this->ffi->GetIndexLen($mediaData);
|
||||
if ($indexLen > 0) {
|
||||
$indexPtr = $this->ffi->GetOutIndexBuf($mediaData);
|
||||
$indexBuf = FFI::string($indexPtr, $indexLen);
|
||||
} else {
|
||||
// 无 index 又 not finish,保护性退出
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
$this->ffi->FreeMediaData($mediaData);
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
return ['ok' => true, 'error' => '', 'size' => $totalSize];
|
||||
} catch (\Throwable $e) {
|
||||
if (is_resource($fp)) {
|
||||
fclose($fp);
|
||||
}
|
||||
@unlink($destPath);
|
||||
|
||||
return ['ok' => false, 'error' => 'exception: ' . $e->getMessage(), 'size' => 0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单条消息解密:encrypt_random_key(RSA)-> AES key -> DecryptData 明文
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function decryptChatItem(array $entry): ?array
|
||||
{
|
||||
$encryptRandomKeyB64 = (string) ($entry['encrypt_random_key'] ?? '');
|
||||
$encryptChatMsg = (string) ($entry['encrypt_chat_msg'] ?? '');
|
||||
$publicKeyVer = (int) ($entry['publickey_ver'] ?? 0);
|
||||
|
||||
if ($encryptRandomKeyB64 === '' || $encryptChatMsg === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$privateKey = $this->privateKeys[$publicKeyVer] ?? null;
|
||||
if ($privateKey === null) {
|
||||
// 尝试唯一配置的私钥兜底
|
||||
$privateKey = reset($this->privateKeys) ?: null;
|
||||
}
|
||||
if ($privateKey === null) {
|
||||
Log::warning(sprintf('会话存档-无匹配私钥 publickey_ver=%d', $publicKeyVer));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$encryptRandomKey = base64_decode($encryptRandomKeyB64, true);
|
||||
if ($encryptRandomKey === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$aesKey = null;
|
||||
// 企微会话存档默认 RSA-PKCS1 填充;部分版本可能使用 OAEP,兼容尝试
|
||||
if (openssl_private_decrypt($encryptRandomKey, $decrypted, $privateKey, OPENSSL_PKCS1_PADDING)) {
|
||||
$aesKey = $decrypted;
|
||||
} elseif (openssl_private_decrypt($encryptRandomKey, $decrypted, $privateKey, OPENSSL_PKCS1_OAEP_PADDING)) {
|
||||
$aesKey = $decrypted;
|
||||
} else {
|
||||
Log::warning(sprintf(
|
||||
'会话存档-RSA 解密失败 publickey_ver=%d err=%s',
|
||||
$publicKeyVer,
|
||||
(string) openssl_error_string()
|
||||
));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$slice = null;
|
||||
try {
|
||||
$slice = $this->ffi->NewSlice();
|
||||
$ret = $this->ffi->DecryptData($aesKey, $encryptChatMsg, $slice);
|
||||
if ($ret !== 0) {
|
||||
Log::warning('会话存档-DecryptData 失败 ret=' . $ret);
|
||||
|
||||
return null;
|
||||
}
|
||||
$plain = $this->sliceToString($slice);
|
||||
$json = json_decode($plain, true);
|
||||
if (!is_array($json)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $json;
|
||||
} finally {
|
||||
if ($slice !== null) {
|
||||
try {
|
||||
$this->ffi->FreeSlice($slice);
|
||||
} catch (\Throwable $e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function sliceToString(\FFI\CData $slice): string
|
||||
{
|
||||
$len = (int) $this->ffi->GetSliceLen($slice);
|
||||
if ($len <= 0) {
|
||||
return '';
|
||||
}
|
||||
$buf = $this->ffi->GetContentFromSlice($slice);
|
||||
|
||||
return FFI::string($buf, $len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string> publickey_ver => pem
|
||||
*/
|
||||
private function loadPrivateKeys(): array
|
||||
{
|
||||
$ver = (int) config('pay.wechat_work.msgaudit_public_key_ver', 0);
|
||||
$pemFromPath = '';
|
||||
$path = (string) config('pay.wechat_work.msgaudit_private_key_path', '');
|
||||
if ($path !== '' && is_file($path) && is_readable($path)) {
|
||||
$pemFromPath = (string) file_get_contents($path);
|
||||
}
|
||||
$pemInline = (string) config('pay.wechat_work.msgaudit_private_key', '');
|
||||
$pem = $pemFromPath !== '' ? $pemFromPath : $pemInline;
|
||||
if ($pem === '') {
|
||||
return [];
|
||||
}
|
||||
// 允许配置里是 \n 转义;标准化换行
|
||||
$pem = str_replace(["\r\n", "\\n"], ["\n", "\n"], $pem);
|
||||
if (strpos($pem, '-----BEGIN') === false) {
|
||||
// 容忍纯 base64:按 64 列切并补头尾
|
||||
$pem = "-----BEGIN RSA PRIVATE KEY-----\n" . chunk_split(trim($pem), 64, "\n") . "-----END RSA PRIVATE KEY-----\n";
|
||||
}
|
||||
|
||||
// 支持未来扩展多版本;目前只有一把,默认索引为配置的 ver(>=1),若为 0 则归到 key=0
|
||||
return [$ver => $pem];
|
||||
}
|
||||
|
||||
/**
|
||||
* 官方 C SDK 头文件的 FFI cdef;与 libWeWorkFinanceSdk_C 头文件完全对应。
|
||||
*
|
||||
* 官方定义(简化):
|
||||
* struct Slice_t { char* buf; int len; };
|
||||
* struct MediaData_t { char* outindexbuf; char* data; int data_len; int is_finish; };
|
||||
*/
|
||||
private function cdef(): string
|
||||
{
|
||||
return <<<'CDEF'
|
||||
typedef struct Slice {
|
||||
char *buf;
|
||||
int len;
|
||||
} Slice_t;
|
||||
|
||||
typedef struct MediaData {
|
||||
char *outindexbuf;
|
||||
int outindexbuf_len;
|
||||
char *data;
|
||||
int data_len;
|
||||
int is_finish;
|
||||
} MediaData_t;
|
||||
|
||||
typedef void WeWorkFinanceSdk_t;
|
||||
|
||||
WeWorkFinanceSdk_t* NewSdk();
|
||||
int Init(WeWorkFinanceSdk_t* sdk, const char* corpid, const char* secret);
|
||||
void DestroySdk(WeWorkFinanceSdk_t* sdk);
|
||||
|
||||
int GetChatData(WeWorkFinanceSdk_t* sdk, unsigned long long seq, unsigned int limit,
|
||||
const char* proxy, const char* passwd, int timeout, Slice_t* chatData);
|
||||
|
||||
int DecryptData(const char* encrypt_key, const char* encrypt_msg, Slice_t* msg);
|
||||
|
||||
int GetMediaData(WeWorkFinanceSdk_t* sdk, const char* indexbuf, const char* sdkFileid,
|
||||
const char* proxy, const char* passwd, int timeout, MediaData_t* mediaData);
|
||||
|
||||
Slice_t* NewSlice();
|
||||
void FreeSlice(Slice_t* slice);
|
||||
char* GetContentFromSlice(Slice_t* slice);
|
||||
int GetSliceLen(Slice_t* slice);
|
||||
|
||||
MediaData_t* NewMediaData();
|
||||
void FreeMediaData(MediaData_t* mediaData);
|
||||
char* GetOutIndexBuf(MediaData_t* mediaData);
|
||||
char* GetData(MediaData_t* mediaData);
|
||||
int GetIndexLen(MediaData_t* mediaData);
|
||||
int GetDataLen(MediaData_t* mediaData);
|
||||
int IsMediaDataFinish(MediaData_t* mediaData);
|
||||
CDEF;
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,64 @@ class WechatWorkService
|
||||
{
|
||||
private $corpId;
|
||||
private $secret;
|
||||
/** 实际选用的 secret 语义标签:customer_contact / external_pay / unknown,便于排错 */
|
||||
private string $secretLabel = 'unknown';
|
||||
private $accessToken;
|
||||
|
||||
public function __construct()
|
||||
/**
|
||||
* @param string|null $secretType 'customer_contact'(客户联系 API)或 'external_pay'(对外收款 API);
|
||||
* 缺省按调用方法的语义自动选择,未指定时优先使用客户联系 Secret,回退到对外收款。
|
||||
*/
|
||||
public function __construct(?string $secretType = null)
|
||||
{
|
||||
$this->corpId = config('pay.wechat_work.corp_id');
|
||||
$this->secret = config('pay.wechat_work.external_pay_secret');
|
||||
|
||||
$customerSecret = (string) config('pay.wechat_work.customer_contact_secret', '');
|
||||
$payContactSecret = (string) config('pay.wechat_work.external_pay_secret', '');
|
||||
|
||||
if ($secretType === 'external_pay') {
|
||||
$this->secret = $payContactSecret;
|
||||
$this->secretLabel = 'external_pay';
|
||||
} elseif ($secretType === 'customer_contact') {
|
||||
if ($customerSecret !== '') {
|
||||
$this->secret = $customerSecret;
|
||||
$this->secretLabel = 'customer_contact';
|
||||
} else {
|
||||
$this->secret = $payContactSecret;
|
||||
$this->secretLabel = 'external_pay(fallback)';
|
||||
}
|
||||
} else {
|
||||
// 历史调用:本类绝大多数方法走的是「客户联系」API,因此默认优先取客户联系 Secret,
|
||||
// 未配置时回退到对外收款 Secret,保持向后兼容(同一应用同时具备两类权限的旧部署可继续工作)。
|
||||
if ($customerSecret !== '') {
|
||||
$this->secret = $customerSecret;
|
||||
$this->secretLabel = 'customer_contact';
|
||||
} else {
|
||||
$this->secret = $payContactSecret;
|
||||
$this->secretLabel = 'external_pay(fallback)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 当前选用的 secret 语义标签 */
|
||||
public function getSecretLabel(): string
|
||||
{
|
||||
return $this->secretLabel;
|
||||
}
|
||||
|
||||
/** 对 secret 做脱敏展示,用于错误日志定位 */
|
||||
private function maskSecret(): string
|
||||
{
|
||||
$s = (string) $this->secret;
|
||||
if ($s === '') {
|
||||
return '(empty)';
|
||||
}
|
||||
$len = strlen($s);
|
||||
if ($len <= 8) {
|
||||
return str_repeat('*', $len);
|
||||
}
|
||||
|
||||
return substr($s, 0, 4) . str_repeat('*', $len - 8) . substr($s, -4) . '(len=' . $len . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,8 +85,9 @@ class WechatWorkService
|
||||
return $this->accessToken;
|
||||
}
|
||||
|
||||
// 从缓存获取
|
||||
$cacheKey = 'qywx_access_token';
|
||||
// 缓存 key 必须按 corp+secret 分桶,否则多应用(customer_contact / external_pay)之间会相互覆盖,
|
||||
// 读到别家应用的 token 去调本家接口 → 偶发 40001 / 40014 / 60011。
|
||||
$cacheKey = 'qywx_access_token:' . md5($this->corpId . '|' . $this->secret);
|
||||
$token = Cache::get($cacheKey);
|
||||
if ($token) {
|
||||
$this->accessToken = $token;
|
||||
@@ -52,15 +105,32 @@ class WechatWorkService
|
||||
if (isset($response['access_token'])) {
|
||||
$token = $response['access_token'];
|
||||
$expiresIn = $response['expires_in'] ?? 7200;
|
||||
|
||||
|
||||
// 缓存token,提前5分钟过期
|
||||
Cache::set($cacheKey, $token, $expiresIn - 300);
|
||||
|
||||
|
||||
$this->accessToken = $token;
|
||||
return $token;
|
||||
}
|
||||
|
||||
throw new \Exception('获取access_token失败: ' . ($response['errmsg'] ?? '未知错误'));
|
||||
$errcode = $response['errcode'] ?? '?';
|
||||
$errmsg = $response['errmsg'] ?? '未知错误';
|
||||
Log::error('企业微信 gettoken 失败', [
|
||||
'errcode' => $errcode,
|
||||
'errmsg' => $errmsg,
|
||||
'secret_label' => $this->secretLabel,
|
||||
'secret_masked' => $this->maskSecret(),
|
||||
'corp_id' => $this->corpId,
|
||||
]);
|
||||
|
||||
throw new \Exception(sprintf(
|
||||
'获取access_token失败[%s]: %s (secret_label=%s, secret=%s, corp_id=%s)',
|
||||
(string) $errcode,
|
||||
(string) $errmsg,
|
||||
$this->secretLabel,
|
||||
$this->maskSecret(),
|
||||
(string) $this->corpId
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,9 +219,15 @@ class WechatWorkService
|
||||
/**
|
||||
* @notes 获取客户详情
|
||||
* @see https://developer.work.weixin.qq.com/document/path/92114
|
||||
*
|
||||
* @param string $externalUserId
|
||||
* @param array<string, mixed>|null $errorOut 引用出参:当返回空数组时携带 errcode/errmsg/raw,便于上游分流处理
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getExternalContactDetail(string $externalUserId): array
|
||||
public function getExternalContactDetail(string $externalUserId, ?array &$errorOut = null): array
|
||||
{
|
||||
$errorOut = null;
|
||||
|
||||
$accessToken = $this->getAccessToken();
|
||||
$url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get';
|
||||
$params = [
|
||||
@@ -160,15 +236,214 @@ class WechatWorkService
|
||||
];
|
||||
|
||||
$response = $this->httpGet($url, $params);
|
||||
|
||||
|
||||
if (isset($response['external_contact'])) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
Log::error('获取客户详情失败: ' . json_encode($response));
|
||||
$errcode = isset($response['errcode']) ? (int) $response['errcode'] : null;
|
||||
$errmsg = (string) ($response['errmsg'] ?? '');
|
||||
$errorOut = [
|
||||
'errcode' => $errcode,
|
||||
'errmsg' => $errmsg,
|
||||
'raw' => $response,
|
||||
];
|
||||
|
||||
// 84061: 客户尚未通过验证 / 41068: 不合法的成员/外部联系人 / 60011/60111: 没有权限访问
|
||||
// 这几类是「业务上预期会发生」的,降级为 warning,避免污染 error 日志。
|
||||
// 关键字段直接拼到消息文本里,便于在 ThinkPHP 默认 file 日志格式下 grep 统计 errcode 分布。
|
||||
$line = sprintf(
|
||||
'企业微信-获取客户详情失败 errcode=%s errmsg=%s ext=%s',
|
||||
$errcode === null ? '?' : (string) $errcode,
|
||||
$errmsg !== '' ? $errmsg : '-',
|
||||
$externalUserId
|
||||
);
|
||||
if (in_array($errcode, [84061, 41068, 60011, 60111], true)) {
|
||||
Log::warning($line);
|
||||
} else {
|
||||
Log::error($line);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业群发:员工代发消息给已添加客户 / 客户群
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/92135 创建企业群发
|
||||
*
|
||||
* 注意:这里只是「下发提醒」,员工手机端会在企微 App 看到"请发送"的提示,点击后才真正发给客户;
|
||||
* 不点击则消息不会触达。发送结果需通过 getGroupMsgSendResult 查询。
|
||||
*
|
||||
* @param array<string, mixed> $payload 标准字段:
|
||||
* chat_type string 'single' 或 'group',必填
|
||||
* external_userid string[] 客户 external_userid 列表(single 必填,最多 10000;group 不传)
|
||||
* chat_type_external_userid_list ... 预留
|
||||
* sender string 员工 userid(不传则使用创建者自己;推荐显式传)
|
||||
* allow_select bool 为 true 时企微会让员工在企微 App 里勾选客户;默认 false
|
||||
* text ['content' => string]
|
||||
* attachments array[] 单条内可含 image / video / link / miniprogram / file(最多 9 个)
|
||||
*
|
||||
* @return array<string, mixed> 原样返回 errcode / errmsg / msgid / fail_list
|
||||
*/
|
||||
public function addMsgTemplate(array $payload): array
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
$url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=' . urlencode($accessToken);
|
||||
|
||||
$response = $this->httpPostJson($url, $payload);
|
||||
$errcode = isset($response['errcode']) ? (int) $response['errcode'] : null;
|
||||
if ($errcode !== 0) {
|
||||
$errmsg = (string) ($response['errmsg'] ?? '');
|
||||
Log::warning(sprintf(
|
||||
'企业微信-企业群发失败 errcode=%s errmsg=%s sender=%s chat_type=%s',
|
||||
$errcode === null ? '?' : (string) $errcode,
|
||||
$errmsg !== '' ? $errmsg : '-',
|
||||
(string) ($payload['sender'] ?? '-'),
|
||||
(string) ($payload['chat_type'] ?? '-')
|
||||
));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询企业群发结果
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/93338
|
||||
* 群发任务创建后,消息会进入发送池,员工手机端需点击确认;此接口返回员工确认/送达/读状态。
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getGroupMsgSendResult(string $msgid, string $userid = '', string $cursor = '', int $limit = 500): array
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
$url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_group_msg_send_result?access_token=' . urlencode($accessToken);
|
||||
|
||||
$body = [
|
||||
'msgid' => $msgid,
|
||||
'limit' => min(1000, max(1, $limit)),
|
||||
'cursor' => $cursor,
|
||||
];
|
||||
if ($userid !== '') {
|
||||
$body['userid'] = $userid;
|
||||
}
|
||||
|
||||
return $this->httpPostJson($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传临时素材(企微 media_id,3 天有效)。用于企业群发的 image/video/file 类型 attachment。
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/90253
|
||||
*
|
||||
* @param string $type image|voice|video|file
|
||||
* @param string $path 本地可读文件绝对路径
|
||||
* @param string $filename 上传字段里的 filename,默认取 basename
|
||||
* @return array<string, mixed> 标准响应(包含 media_id)
|
||||
*/
|
||||
public function uploadMedia(string $type, string $path, string $filename = ''): array
|
||||
{
|
||||
if (!is_file($path) || !is_readable($path)) {
|
||||
Log::error(sprintf('企业微信-上传临时素材失败:文件不存在或不可读 path=%s', $path));
|
||||
|
||||
return ['errcode' => -1, 'errmsg' => 'file not found: ' . $path];
|
||||
}
|
||||
|
||||
$type = in_array($type, ['image', 'voice', 'video', 'file'], true) ? $type : 'file';
|
||||
$accessToken = $this->getAccessToken();
|
||||
$url = 'https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=' . urlencode($accessToken) . '&type=' . $type;
|
||||
|
||||
if ($filename === '') {
|
||||
$filename = basename($path);
|
||||
}
|
||||
$cfile = new \CURLFile($path, mime_content_type($path) ?: 'application/octet-stream', $filename);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, ['media' => $cfile]);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curlErr = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode !== 200) {
|
||||
Log::error(sprintf('企业微信-上传临时素材 HTTP=%d type=%s err=%s', $httpCode, $type, $curlErr));
|
||||
|
||||
return ['errcode' => -1, 'errmsg' => 'http ' . $httpCode . ' ' . $curlErr];
|
||||
}
|
||||
|
||||
$result = json_decode((string) $response, true);
|
||||
if (!is_array($result)) {
|
||||
Log::error('企业微信-上传临时素材 响应解析失败:' . (string) $response);
|
||||
|
||||
return ['errcode' => -1, 'errmsg' => 'bad json'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图文/图片的永久图片素材,获取企微 CDN 图片 URL(用于 link/image 附件的 pic_url)
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/90256
|
||||
*/
|
||||
public function uploadImageToCdn(string $path, string $filename = ''): array
|
||||
{
|
||||
if (!is_file($path) || !is_readable($path)) {
|
||||
return ['errcode' => -1, 'errmsg' => 'file not found'];
|
||||
}
|
||||
|
||||
$accessToken = $this->getAccessToken();
|
||||
$url = 'https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=' . urlencode($accessToken);
|
||||
|
||||
if ($filename === '') {
|
||||
$filename = basename($path);
|
||||
}
|
||||
$cfile = new \CURLFile($path, mime_content_type($path) ?: 'image/jpeg', $filename);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, ['media' => $cfile]);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$result = json_decode((string) $response, true);
|
||||
|
||||
return is_array($result) ? $result : ['errcode' => -1, 'errmsg' => 'bad json'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业微信部门下所有成员(含字段 userid/name/mobile/department/...),供 admin 选择发送员工
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/90201
|
||||
*/
|
||||
public function getDepartmentUserSimpleList(int $departmentId = 1, bool $fetchChild = true): array
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
$url = 'https://qyapi.weixin.qq.com/cgi-bin/user/simplelist';
|
||||
$params = [
|
||||
'access_token' => $accessToken,
|
||||
'department_id' => $departmentId,
|
||||
'fetch_child' => $fetchChild ? 1 : 0,
|
||||
];
|
||||
|
||||
$response = $this->httpGet($url, $params);
|
||||
|
||||
return isset($response['userlist']) && is_array($response['userlist']) ? $response['userlist'] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 检查应用权限(用于诊断)
|
||||
* @return array 返回应用的权限信息
|
||||
|
||||
@@ -24,6 +24,8 @@ return [
|
||||
'express:sync' => 'app\\command\\SyncTrackingNumbers',
|
||||
// 企业微信客户同步
|
||||
'qywx:sync-customer' => 'app\\command\\QywxSyncCustomer',
|
||||
// 企业微信会话内容存档同步(需开通会话存档 License 并配置 msgaudit_* 相关项 + 动态库)
|
||||
'qywx:sync-msg-archive' => 'app\\command\\QywxSyncMsgArchive',
|
||||
// 甘草订单物流路由同步(GET_TASK_ROUTE_LIST)
|
||||
'gancao:sync-logistics' => 'app\\command\\GancaoSyncLogisticsRoute',
|
||||
],
|
||||
|
||||
@@ -75,5 +75,11 @@ return [
|
||||
'default_num_per_pack' => (int) zyt_gancao_scm_env('NUM_PER_PACK', 2),
|
||||
'default_dose_ml' => (int) zyt_gancao_scm_env('DOSE_ML', 150),
|
||||
'herb_id_map' => [],
|
||||
'df_ids'=>['饮片'=>'101','浓缩水丸'=>'102']
|
||||
'df_ids' => ['饮片' => '101', '浓缩水丸' => '102'],
|
||||
// 可选:HTTPS cURL cipher list。默认留空 → 走 cURL 内置默认,兼容性最好。
|
||||
// 需要对付弱加密服务器时:
|
||||
// - OpenSSL 构建(绝大多数 Linux Docker):GANCAO_SCM_TLS_CIPHERS="DEFAULT@SECLEVEL=1"
|
||||
// - 通用:GANCAO_SCM_TLS_CIPHERS="DEFAULT:!aNULL:!eNULL"
|
||||
// 如果 cURL 报 CURLE_SSL_CIPHER(59) Unknown cipher in list,八成是底层不是 OpenSSL,清空此项即可。
|
||||
'tls_ciphers' => (string) zyt_gancao_scm_env('TLS_CIPHERS', ''),
|
||||
];
|
||||
|
||||
@@ -29,6 +29,10 @@ return [
|
||||
'corp_id' => env('WECHAT_WORK_CORP_ID', '') ?: (string)env('work_wechat.corp_id', ''),
|
||||
// 对外收款 get_bill_list 必须使用「对外收款」应用的 Secret,在 管理后台-应用管理-对外收款-API 中查看
|
||||
'external_pay_secret' => env('WECHAT_WORK_EXTERNAL_PAY_SECRET', '') ?: (string)env('work_wechat.wechat_work_external_pay_secret', '') ?: (string)env('work_wechat.secret', ''),
|
||||
// 客户联系 API 与回调用的 Secret,应在「客户联系」管理后台-API-取出。
|
||||
// 若与「对外收款」应用同 secret,可不配;缺省回退到 external_pay_secret 保持向后兼容。
|
||||
// 注意:此 Secret 决定了 customer 同步/回调能看到哪些成员添加的客户(受应用「可调用应用 / 成员可见范围」限制)。
|
||||
'customer_contact_secret' => env('WECHAT_WORK_CUSTOMER_CONTACT_SECRET', '') ?: (string)env('work_wechat.wechat_work_customer_contact_secret', ''),
|
||||
// 客户联系-API「接收事件服务器」中配置的 Token、EncodingAESKey(与对外收款回调无关,需单独填写)
|
||||
'contact_callback_token' => env('WECHAT_WORK_CONTACT_CALLBACK_TOKEN', ''),
|
||||
'contact_callback_aes_key' => env('WECHAT_WORK_CONTACT_CALLBACK_AES_KEY', ''),
|
||||
@@ -38,5 +42,31 @@ return [
|
||||
// 直接在企业微信发起收款时,回调自动创建订单的默认值
|
||||
'default_creator_id' => (int)env('WECHAT_WORK_DEFAULT_CREATOR_ID', 1),
|
||||
'default_order_type' => (int)env('WECHAT_WORK_DEFAULT_ORDER_TYPE', 6), // 6=其他费用
|
||||
|
||||
// ========== 会话内容存档(员工↔客户消息接收)==========
|
||||
// 开关:为 false 时后台仅启用「发消息」能力,拉取存档的 cron 任务空跑,方便 SDK/私钥未就绪阶段。
|
||||
'msgaudit_enabled' => (bool) env('WECHAT_WORK_MSGAUDIT_ENABLED', false),
|
||||
// 会话存档应用独立 Secret(与客户联系、对外收款互不相同;在 管理后台-应用管理-会话内容存档-API 中取)
|
||||
'msgaudit_secret' => env('WECHAT_WORK_MSGAUDIT_SECRET', ''),
|
||||
// 管理后台上传公钥时返回的 public_key_ver(整数),需与当前私钥严格对应。
|
||||
'msgaudit_public_key_ver' => (int) env('WECHAT_WORK_MSGAUDIT_PUBLIC_KEY_VER', 0),
|
||||
// RSA 私钥 PEM(建议放文件,避免 .env 里多行换行坑;此项优先)
|
||||
'msgaudit_private_key_path' => env('WECHAT_WORK_MSGAUDIT_PRIVATE_KEY_PATH', ''),
|
||||
// 或直接把 PEM 贴到这里(若同时配置了 path,以文件为准)
|
||||
'msgaudit_private_key' => env('WECHAT_WORK_MSGAUDIT_PRIVATE_KEY', ''),
|
||||
// 企业微信官方 C SDK 动态库路径(Linux: libWeWorkFinanceSdk_C.so;Windows: WeWorkFinanceSdk.dll)
|
||||
// 留空时走 noop(不会抛异常,只记一条 warning),方便代码先部署上线等 SDK 到位。
|
||||
'msgaudit_sdk_lib_path' => env('WECHAT_WORK_MSGAUDIT_SDK_LIB_PATH', ''),
|
||||
// SDK 调用超时(秒),getchatdata / getmediadata 用
|
||||
'msgaudit_timeout' => (int) env('WECHAT_WORK_MSGAUDIT_TIMEOUT', 60),
|
||||
// 单次拉取条数(官方上限 1000)
|
||||
'msgaudit_limit' => (int) env('WECHAT_WORK_MSGAUDIT_LIMIT', 500),
|
||||
// 为代理机访问企微拉取服务器配置的出口代理(可留空)
|
||||
'msgaudit_proxy' => env('WECHAT_WORK_MSGAUDIT_PROXY', ''),
|
||||
'msgaudit_proxy_passwd' => env('WECHAT_WORK_MSGAUDIT_PROXY_PASSWD', ''),
|
||||
|
||||
// ========== 员工代发消息(企业群发 add_msg_template)==========
|
||||
// 这一组能力依赖「客户联系」Secret;默认复用 customer_contact_secret。
|
||||
// 代发消息频率/范围限制详见 https://developer.work.weixin.qq.com/document/path/92135
|
||||
],
|
||||
];
|
||||
|
||||
@@ -103,19 +103,19 @@ return [
|
||||
],
|
||||
|
||||
// 医助创建订单权限:拥有以下角色ID的用户可修改任意订单,其他用户只能修改自己创建的订单
|
||||
'order_edit_all_roles' => [0, 3, 6],
|
||||
'order_edit_all_roles' => [0, 3, 4, 9, 6],
|
||||
|
||||
// 处方库:以下角色ID + 超级管理员(root) 可查看/编辑/删除全部;他人仅可管理自己创建的,公开处方对他人只读
|
||||
'prescription_library_manage_all_roles' => [0, 3, 6],
|
||||
'prescription_library_manage_all_roles' => [0, 3, 4, 9, 6],
|
||||
|
||||
// 消费者处方单:以下角色 + root 可对「待审核」处方进行通过/驳回(驳回即作废处方)
|
||||
'prescription_audit_roles' => [0, 3, 6],
|
||||
'prescription_audit_roles' => [0, 3, 4, 9, 6],
|
||||
|
||||
// 处方业务订单 internal_cost 等财务字段:以下角色 ID + root 可见
|
||||
'prescription_order_finance_roles' => [0, 3, 6],
|
||||
'prescription_order_finance_roles' => [0, 3, 4, 9, 6],
|
||||
|
||||
// 业务订单「关联支付单」审核:以下角色 ID + root 可操作(可与财务角色一致)
|
||||
'prescription_order_payment_audit_roles' => [0, 3, 6],
|
||||
'prescription_order_payment_audit_roles' => [0, 3, 4, 9, 6],
|
||||
|
||||
// 腾讯云实时音视频(TRTC)配置
|
||||
'trtc' => [
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
-- 企业微信 员工↔客户 消息收发相关表
|
||||
-- 1) 会话索引(员工 userid × 客户 external_userid × 群 roomid 三元组,用于前端会话列表)
|
||||
-- 2) 消息归档(会话存档 SDK 拉取落库;msgid 唯一,支持撤回更新)
|
||||
-- 3) 消息归档附件(大型媒体独立存储,按需下载到本地/对象存储)
|
||||
-- 4) 发消息任务(企业群发 add_msg_template 一次投递记录 + 每客户明细)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_session` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`staff_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '企微员工 userid',
|
||||
`external_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '客户 external_userid;群聊时为 roomid 对应的主联系客户,可留空',
|
||||
`roomid` varchar(64) NOT NULL DEFAULT '' COMMENT '企微群聊 roomid;单聊为空',
|
||||
`session_type` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '1=单聊 2=群聊',
|
||||
`last_msg_id` varchar(64) NOT NULL DEFAULT '' COMMENT '最近一条归档消息 msgid(来自会话存档)',
|
||||
`last_msg_seq` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '最近一条归档消息 seq',
|
||||
`last_msg_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '最近一条归档消息 Unix 秒',
|
||||
`last_msg_type` varchar(32) NOT NULL DEFAULT '' COMMENT '最近一条消息类型',
|
||||
`last_msg_summary` varchar(512) NOT NULL DEFAULT '' COMMENT '最近一条消息摘要(纯文本,用于列表)',
|
||||
`unread_staff` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '员工侧未读(后台管理员打开会话后清零)',
|
||||
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_session` (`staff_userid`,`external_userid`,`roomid`),
|
||||
KEY `idx_staff_time` (`staff_userid`,`last_msg_time`),
|
||||
KEY `idx_ext_time` (`external_userid`,`last_msg_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微消息会话索引';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_archive` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`msgid` varchar(64) NOT NULL DEFAULT '' COMMENT '企微会话存档 msgid,官方唯一键',
|
||||
`seq` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '拉取 seq(单调递增,断点续拉)',
|
||||
`action` varchar(16) NOT NULL DEFAULT 'send' COMMENT 'send/recall/switch',
|
||||
`from_user` varchar(64) NOT NULL DEFAULT '' COMMENT '发送方 userid / external_userid',
|
||||
`from_type` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0=未知 1=员工 2=客户',
|
||||
`to_list` text COMMENT '接收方列表 JSON(单聊通常仅 1 个)',
|
||||
`roomid` varchar(64) NOT NULL DEFAULT '' COMMENT '群 roomid,单聊为空',
|
||||
`msgtype` varchar(32) NOT NULL DEFAULT '' COMMENT 'text/image/voice/video/file/link/location/emotion/chatrecord/markdown/news/meeting/calendar/mixed/weapp/voip_doc_share/...',
|
||||
`content` mediumtext COMMENT '文本/卡片摘要(mixed/chatrecord 会序列化 JSON)',
|
||||
`media_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'sdkfileid:作为 GetMediaData 入参',
|
||||
`md5sum` varchar(64) NOT NULL DEFAULT '' COMMENT '企微下发的 md5sum',
|
||||
`file_name` varchar(512) NOT NULL DEFAULT '' COMMENT '原始文件名',
|
||||
`file_size` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '字节',
|
||||
`file_ext` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展名',
|
||||
`play_length` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '语音/视频时长 秒',
|
||||
`raw` mediumtext COMMENT '解密后的原始 JSON,兜底',
|
||||
`send_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '消息时间 Unix 秒',
|
||||
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_msgid` (`msgid`),
|
||||
KEY `idx_seq` (`seq`),
|
||||
KEY `idx_room_time` (`roomid`,`send_time`),
|
||||
KEY `idx_from_time` (`from_user`,`send_time`),
|
||||
KEY `idx_send_time` (`send_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微会话存档消息';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_archive_media` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`msgid` varchar(64) NOT NULL DEFAULT '' COMMENT '关联 zyt_qywx_msg_archive.msgid',
|
||||
`sdkfileid` varchar(128) NOT NULL DEFAULT '',
|
||||
`status` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0=待下载 1=成功 2=失败',
|
||||
`retry_count` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`file_path` varchar(1024) NOT NULL DEFAULT '' COMMENT '本地/对象存储相对路径',
|
||||
`file_url` varchar(1024) NOT NULL DEFAULT '' COMMENT '可公网访问的地址(如已迁 CDN)',
|
||||
`file_size` bigint(20) unsigned NOT NULL DEFAULT 0,
|
||||
`md5sum` varchar(64) NOT NULL DEFAULT '',
|
||||
`error` varchar(512) NOT NULL DEFAULT '',
|
||||
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_msg_sdk` (`msgid`,`sdkfileid`),
|
||||
KEY `idx_status` (`status`,`retry_count`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微会话存档消息媒介文件';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_send_task` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`admin_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '后台发起人 admin id',
|
||||
`sender_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '代发员工 userid(add_msg_template 的 sender)',
|
||||
`external_userids` text COMMENT '目标客户 external_userid JSON 数组',
|
||||
`chat_type` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '1=single 2=group(对应企微 chat_type)',
|
||||
`msg_payload` mediumtext COMMENT '消息体 JSON(含 text/image/video/file/link/miniprogram 任意组合)',
|
||||
`msg_template_id` varchar(64) NOT NULL DEFAULT '' COMMENT '企微返回 msgid(提醒员工确认发送的 ID)',
|
||||
`fail_list` text COMMENT '企微返回的 fail_list',
|
||||
`status` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0=待提交 1=已提交等待员工确认 2=已确认发送 3=失败',
|
||||
`error` varchar(512) NOT NULL DEFAULT '',
|
||||
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_sender_time` (`sender_userid`,`create_time`),
|
||||
KEY `idx_template` (`msg_template_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微员工代发消息任务';
|
||||
|
||||
-- 断点续拉游标(seq 持久化;一行一条,按 staff_userid 维度)
|
||||
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_archive_cursor` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`cursor_key` varchar(64) NOT NULL DEFAULT '' COMMENT '默认 global;如需按员工分片则存 staff_userid',
|
||||
`seq` bigint(20) unsigned NOT NULL DEFAULT 0,
|
||||
`last_pull_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`last_pull_count` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`last_error` varchar(512) NOT NULL DEFAULT '',
|
||||
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_cursor_key` (`cursor_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微会话存档拉取游标';
|
||||
@@ -0,0 +1,98 @@
|
||||
# 企业微信 员工↔客户 IM 功能部署说明
|
||||
|
||||
本文档对应「管理后台 IM」功能(`admin/src/views/chat`),负责在后端/后台视角下的**收/发**一对一消息。
|
||||
|
||||
- 发送:企业群发 `add_msg_template`(员工本人身份 + 手机端确认)
|
||||
- 接收:会话内容存档(官方 C SDK + RSA 解密 + 计划任务拉取)
|
||||
- 老回调接口 `QywxExternalContactCallbackController` 仍用于 **添加/编辑/删除外部联系人** 事件,不承载消息内容。
|
||||
|
||||
---
|
||||
|
||||
## 1. 数据表
|
||||
|
||||
执行一次:
|
||||
|
||||
```bash
|
||||
mysql -u<user> -p<pass> <db> < server/database/migrations/2026_04_20_create_qywx_msg_tables.sql
|
||||
```
|
||||
|
||||
新增 5 张:`qywx_msg_session`、`qywx_msg_archive`、`qywx_msg_archive_media`、`qywx_msg_send_task`、`qywx_msg_archive_cursor`。
|
||||
|
||||
## 2. 配置(server/config/pay.php → wechat_work)
|
||||
|
||||
```php
|
||||
'customer_contact_secret' => '客户联系 Secret', // 已有:发消息 / 客户列表
|
||||
|
||||
// 会话内容存档
|
||||
'msgaudit_enabled' => true, // 开关
|
||||
'msgaudit_secret' => '会话存档 Secret', // 独立应用 Secret
|
||||
'msgaudit_public_key_ver' => 1, // 管理后台上传公钥返回的版本号
|
||||
'msgaudit_private_key_path'=> '/data/qywx/priv.pem', // RSA 私钥文件路径(建议)
|
||||
'msgaudit_sdk_lib_path' => '/data/qywx/libWeWorkFinanceSdk_C.so', // SDK 动态库
|
||||
'msgaudit_timeout' => 60,
|
||||
'msgaudit_limit' => 500,
|
||||
```
|
||||
|
||||
> `msgaudit_enabled = false` 或 `msgaudit_sdk_lib_path` 留空时,后端不会崩溃——拉取命令会以 `noop` 方式返回,方便「先上线、再接 SDK」。
|
||||
|
||||
## 3. C SDK & 私钥准备
|
||||
|
||||
1. 从企微管理后台 → 安全与合规 → 会话内容存档 → SDK 下载区,下载官方 C SDK。
|
||||
2. Linux 部署 `libWeWorkFinanceSdk_C.so` 到 `/data/qywx/`,并确保 PHP-FPM 账户有可执行权限。
|
||||
3. **安装 PHP FFI**:`php.ini` 开启 `ffi.enable=true`(preload 场景用 `preload`,CLI + FPM 用 `true`)。
|
||||
4. 生成 RSA 密钥对:`openssl genrsa -out priv.pem 2048 && openssl rsa -in priv.pem -pubout -out pub.pem`
|
||||
5. 企微后台上传 `pub.pem` → 记录返回的 `public_key_ver` → 回填到配置。
|
||||
6. 私钥 `priv.pem` 放到 `msgaudit_private_key_path` 指向的位置,权限 600。
|
||||
|
||||
> 轮换公钥时,**保留历史 `public_key_ver → private_key` 映射**(SDK 会用旧消息的版本号去找旧私钥)。如需多版本,代码已预留:在 `WeComFinanceSdkClient::loadPrivateKeys()` 同一配置下,可额外传入 `msgaudit_private_keys` 数组形式支持多版本(自行扩展)。
|
||||
|
||||
## 4. 计划任务
|
||||
|
||||
推荐 30 秒一次(企微限制:每分钟不超过 600 次)。
|
||||
|
||||
Linux crontab(每 30s 跑一次的 2 行写法):
|
||||
|
||||
```
|
||||
* * * * * cd /path/to/server && /usr/bin/php think qywx:sync-msg-archive --download >/dev/null 2>&1
|
||||
* * * * * cd /path/to/server && sleep 30 && /usr/bin/php think qywx:sync-msg-archive --download >/dev/null 2>&1
|
||||
```
|
||||
|
||||
可选:把媒体下载拆开、并发运行:
|
||||
|
||||
```
|
||||
* * * * * cd /path/to/server && /usr/bin/php think qywx:sync-msg-archive >/dev/null 2>&1
|
||||
*/2 * * * * cd /path/to/server && /usr/bin/php think qywx:sync-msg-archive --only-media --max-media=500 >/dev/null 2>&1
|
||||
```
|
||||
|
||||
命令已做 `flock` 互斥(`runtime/qywx_msg_archive.lock`),并发多跑也不会重复写。
|
||||
|
||||
## 5. 权限与菜单
|
||||
|
||||
后台菜单需新增一条,路径 `/chat`(或自定义),component 指向 `views/chat/index.vue`。
|
||||
|
||||
建议开启菜单权限控制:仅运营/客服组可见。API 路由前缀为 `qywx.message/*`,请在 `adminapi` 权限中心相应配置。
|
||||
|
||||
## 6. 使用流程
|
||||
|
||||
1. 打开「IM」页面,系统自动拉取会话列表。
|
||||
2. 左侧可按员工筛选;选中会话后中间展示消息流,8 秒轮询新消息。
|
||||
3. 在底部输入框输入文本/添加附件(图片/视频/文件/链接/小程序)→ 点击「发送」。
|
||||
4. 后端创建企微 `add_msg_template` 任务,**员工手机**会收到确认弹窗,确认后客户即可收到。
|
||||
5. 已发送任务可在右侧「发送任务」Tab 查看送达详情。
|
||||
|
||||
## 7. 故障排查
|
||||
|
||||
| 症状 | 排查 |
|
||||
| --- | --- |
|
||||
| 前端顶部提示「会话存档 SDK 不可用」| 查 `config/pay.php` msgaudit_* 配置 + `libWeWorkFinanceSdk_C.so` 路径 + `ffi.enable` + 日志 `runtime/log/`。调 GET `/adminapi/qywx.message/archive_status` 看诊断。 |
|
||||
| 消息拉取无数据 | `php think qywx:sync-msg-archive -vvv`;看 `qywx_msg_archive_cursor` 表 seq 是否推进;确认企微已开通会话存档 License 并勾选目标员工。 |
|
||||
| 媒体文件一直下载中 | `qywx_msg_archive_media.status` / `retry_count` / `last_error`;路径 `runtime/qywx_msg_media/` 写权限;SDK `GetMediaData` 超时调大 `msgaudit_timeout`。 |
|
||||
| 发送「消息内容不能为空」 | 文本 + 附件都为空;或附件上传失败导致没有 media_id,面板会红色报错。 |
|
||||
| 发送成功但客户未收到 | 员工手机端漏点确认;或该员工未启用企业群发能力;查 `qywx_msg_send_task.fail_list` & 右侧「送达详情」。 |
|
||||
| 需要撤回消息 | 企微规则:群发任务已提交后无法撤回单条;会话存档里会记录 `recall` 动作并在前端打「已撤回」标记。 |
|
||||
|
||||
## 8. 未来扩展点
|
||||
|
||||
- 多版本 RSA 私钥轮换:`WeComFinanceSdkClient::loadPrivateKeys()` 改造为读取 `msgaudit_private_keys` 数组,key 为 `public_key_ver`。
|
||||
- WebSocket 推送新消息:在 `QywxMsgArchiveService::persistBatch()` 写入后发布到 Workerman / Swoole,前端改成订阅(当前是 8s 轮询)。
|
||||
- 群聊发送:企微「客户群 SOP」接口,当前 UI 仅展示群会话消息不允许发送(`canSendMessage` 为 false)。
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import r from"./error-BlU2BJ1p.js";import{f as p,ak as i,I as m,a as e,aN as s,J as o}from"./@vue/runtime-core-C0pg79pw.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CYz6RFzi.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const a="/admin/assets/no_perms-jDxcYpYC.png",n={class:"error404"},W=p({__name:"403",setup(c){return(_,t)=>(i(),m("div",n,[e(r,{code:"403",title:"您的账号权限不足,请联系管理员添加权限!","show-btn":!1},{content:s(()=>[...t[0]||(t[0]=[o("div",{class:"flex justify-center"},[o("img",{class:"w-[150px] h-[150px]",src:a,alt:""})],-1)])]),_:1})]))}});export{W as default};
|
||||
import r from"./error-Bx-pGU7q.js";import{f as p,ak as i,I as m,a as e,aN as s,J as o}from"./@vue/runtime-core-C0pg79pw.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CYz6RFzi.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const a="/admin/assets/no_perms-jDxcYpYC.png",n={class:"error404"},W=p({__name:"403",setup(c){return(_,t)=>(i(),m("div",n,[e(r,{code:"403",title:"您的账号权限不足,请联系管理员添加权限!","show-btn":!1},{content:s(()=>[...t[0]||(t[0]=[o("div",{class:"flex justify-center"},[o("img",{class:"w-[150px] h-[150px]",src:a,alt:""})],-1)])]),_:1})]))}});export{W as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import o from"./error-BlU2BJ1p.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C0pg79pw.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CYz6RFzi.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const i={class:"error404"},T=r({__name:"404",setup(e){return(a,s)=>(t(),m("div",i,[p(o,{code:"404",title:"哎呀,出错了!您访问的页面不存在…"})]))}});export{T as default};
|
||||
import o from"./error-Bx-pGU7q.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C0pg79pw.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CYz6RFzi.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const i={class:"error404"},T=r({__name:"404",setup(e){return(a,s)=>(t(),m("div",i,[p(o,{code:"404",title:"哎呀,出错了!您访问的页面不存在…"})]))}});export{T as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./AssignLogPanel.vue_vue_type_script_setup_true_lang-B51nxqq-.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./tcm-DompPo1O.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
import{_ as o}from"./AssignLogPanel.vue_vue_type_script_setup_true_lang-Dqu6qTHC.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./tcm-7RUvcI90.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{L as _,N as f,M as u}from"./element-plus-6h1hTCrQ.js";import{M as w}from"./tcm-DompPo1O.js";import{f as h,w as g,ak as n,I as v,aP as b,G as x,aN as y,a as e}from"./@vue/runtime-core-C0pg79pw.js";import{o as l}from"./@vue/reactivity-BIbyPIZJ.js";const I={class:"assign-log-panel"},E=h({__name:"AssignLogPanel",props:{diagnosisId:{}},setup(c,{expose:p}){const t=c,s=l(!1),i=l([]),r=async()=>{if(t.diagnosisId){s.value=!0;try{const o=await w({id:t.diagnosisId});i.value=Array.isArray(o)?o:[]}catch(o){console.error(o),i.value=[]}finally{s.value=!1}}};return g(()=>t.diagnosisId,()=>{r()},{immediate:!0}),p({refresh:r}),(o,L)=>{const a=f,d=u,m=_;return n(),v("div",I,[b((n(),x(d,{data:i.value,border:"",stripe:"","empty-text":"暂无指派记录"},{default:y(()=>[e(a,{label:"操作时间",width:"175",prop:"create_time_text"}),e(a,{label:"原医助","min-width":"120",prop:"from_assistant_name"}),e(a,{label:"新医助","min-width":"120",prop:"to_assistant_name"}),e(a,{label:"操作人",width:"110",prop:"operator_name"}),e(a,{label:"操作账号",width:"120",prop:"operator_account","show-overflow-tooltip":""}),e(a,{label:"IP",width:"130",prop:"ip","show-overflow-tooltip":""})]),_:1},8,["data"])),[[m,s.value]])])}}});export{E as _};
|
||||
import{L as _,N as f,M as u}from"./element-plus-osWj3D3p.js";import{M as w}from"./tcm-7RUvcI90.js";import{f as h,w as g,ak as n,I as v,aP as b,G as x,aN as y,a as e}from"./@vue/runtime-core-C0pg79pw.js";import{o as l}from"./@vue/reactivity-BIbyPIZJ.js";const I={class:"assign-log-panel"},E=h({__name:"AssignLogPanel",props:{diagnosisId:{}},setup(c,{expose:p}){const t=c,s=l(!1),i=l([]),r=async()=>{if(t.diagnosisId){s.value=!0;try{const o=await w({id:t.diagnosisId});i.value=Array.isArray(o)?o:[]}catch(o){console.error(o),i.value=[]}finally{s.value=!1}}};return g(()=>t.diagnosisId,()=>{r()},{immediate:!0}),p({refresh:r}),(o,L)=>{const a=f,d=u,m=_;return n(),v("div",I,[b((n(),x(d,{data:i.value,border:"",stripe:"","empty-text":"暂无指派记录"},{default:y(()=>[e(a,{label:"操作时间",width:"175",prop:"create_time_text"}),e(a,{label:"原医助","min-width":"120",prop:"from_assistant_name"}),e(a,{label:"新医助","min-width":"120",prop:"to_assistant_name"}),e(a,{label:"操作人",width:"110",prop:"operator_name"}),e(a,{label:"操作账号",width:"120",prop:"operator_account","show-overflow-tooltip":""}),e(a,{label:"IP",width:"130",prop:"ip","show-overflow-tooltip":""})]),_:1},8,["data"])),[[m,s.value]])])}}});export{E as _};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{K as E,L as T,N as L,M as N,_ as P}from"./element-plus-osWj3D3p.js";import{T as B}from"./tcm-7RUvcI90.js";import{f as R,w as V,ak as e,I as i,a as o,aP as D,G as u,aN as s,O as n,F,ap as A}from"./@vue/runtime-core-C0pg79pw.js";import{Q as l}from"./@vue/shared-mAAVTE9n.js";import{o as g}from"./@vue/reactivity-BIbyPIZJ.js";import{_ as G}from"./index-xZXgRhuH.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const K={class:"call-record-panel"},M={key:0,class:"text-primary"},O={key:1,class:"text-gray-400"},Q={key:0,class:"recording-list"},S=["src"],$={key:1,class:"text-gray-400"},j=R({__name:"CallRecordPanel",props:{diagnosisId:{}},setup(h,{expose:y}){const p=h,m=g(!1),c=g([]),_=async()=>{if(p.diagnosisId){m.value=!0;try{c.value=await B({diagnosis_id:p.diagnosisId})||[]}catch(a){console.error(a),c.value=[]}finally{m.value=!1}}};V(()=>p.diagnosisId,()=>{_()},{immediate:!0}),y({refresh:_});function b(a){return{1:"进行中",2:"已结束",3:"未接听",4:"已取消"}[a]??"—"}function v(a){return!a||typeof a!="string"?!1:/\.(mp4|webm|ogg)(\?|$)/i.test(a)}return(a,k)=>{const w=E,r=L,x=P,C=N,I=T;return e(),i("div",K,[o(w,{type:"info","show-icon":"",closable:!1,class:"mb-4",title:"视频通话与录制回放"}),D((e(),u(C,{data:c.value,border:"",stripe:"","empty-text":"暂无通话记录"},{default:s(()=>[o(r,{label:"开始时间",width:"170",prop:"start_time_text"}),o(r,{label:"结束时间",width:"170",prop:"end_time_text"}),o(r,{label:"通话类型",width:"100"},{default:s(({row:t})=>[n(l(t.call_type===1?"语音":"视频"),1)]),_:1}),o(r,{label:"房间号",width:"140"},{default:s(({row:t})=>[t.room_id?(e(),i("span",M,l(t.room_id),1)):(e(),i("span",O,"—"))]),_:1}),o(r,{label:"时长",width:"110",prop:"duration_text"}),o(r,{label:"状态",width:"90"},{default:s(({row:t})=>[n(l(b(t.status)),1)]),_:1}),o(r,{label:"录制",width:"100"},{default:s(({row:t})=>[n(l(t.recording_status_text||"—"),1)]),_:1}),o(r,{label:"录制回放","min-width":"280"},{default:s(({row:t})=>[(t.recording_urls_list||[]).length?(e(),i("div",Q,[(e(!0),i(F,null,A(t.recording_urls_list,(d,f)=>(e(),i("div",{key:f,class:"recording-item"},[v(d)?(e(),i("video",{key:0,src:d,controls:"",preload:"metadata",class:"recording-video"},null,8,S)):(e(),u(x,{key:1,href:d,target:"_blank",type:"primary"},{default:s(()=>[n(" 打开链接 "+l(f+1),1)]),_:2},1032,["href"]))]))),128))])):(e(),i("span",$,"暂无"))]),_:1})]),_:1},8,["data"])),[[I,m.value]])])}}}),Nt=G(j,[["__scopeId","data-v-b392e2ba"]]);export{Nt as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{K as E,L as T,N as L,M as N,a3 as P}from"./element-plus-6h1hTCrQ.js";import{T as B}from"./tcm-DompPo1O.js";import{f as R,w as V,ak as e,I as i,a as o,aP as D,G as u,aN as s,O as n,F,ap as A}from"./@vue/runtime-core-C0pg79pw.js";import{Q as l}from"./@vue/shared-mAAVTE9n.js";import{o as g}from"./@vue/reactivity-BIbyPIZJ.js";import{_ as G}from"./index-55neFmjq.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const K={class:"call-record-panel"},M={key:0,class:"text-primary"},O={key:1,class:"text-gray-400"},Q={key:0,class:"recording-list"},S=["src"],$={key:1,class:"text-gray-400"},j=R({__name:"CallRecordPanel",props:{diagnosisId:{}},setup(h,{expose:y}){const p=h,m=g(!1),c=g([]),_=async()=>{if(p.diagnosisId){m.value=!0;try{c.value=await B({diagnosis_id:p.diagnosisId})||[]}catch(a){console.error(a),c.value=[]}finally{m.value=!1}}};V(()=>p.diagnosisId,()=>{_()},{immediate:!0}),y({refresh:_});function b(a){return{1:"进行中",2:"已结束",3:"未接听",4:"已取消"}[a]??"—"}function v(a){return!a||typeof a!="string"?!1:/\.(mp4|webm|ogg)(\?|$)/i.test(a)}return(a,k)=>{const w=E,r=L,x=P,C=N,I=T;return e(),i("div",K,[o(w,{type:"info","show-icon":"",closable:!1,class:"mb-4",title:"视频通话与录制回放"}),D((e(),u(C,{data:c.value,border:"",stripe:"","empty-text":"暂无通话记录"},{default:s(()=>[o(r,{label:"开始时间",width:"170",prop:"start_time_text"}),o(r,{label:"结束时间",width:"170",prop:"end_time_text"}),o(r,{label:"通话类型",width:"100"},{default:s(({row:t})=>[n(l(t.call_type===1?"语音":"视频"),1)]),_:1}),o(r,{label:"房间号",width:"140"},{default:s(({row:t})=>[t.room_id?(e(),i("span",M,l(t.room_id),1)):(e(),i("span",O,"—"))]),_:1}),o(r,{label:"时长",width:"110",prop:"duration_text"}),o(r,{label:"状态",width:"90"},{default:s(({row:t})=>[n(l(b(t.status)),1)]),_:1}),o(r,{label:"录制",width:"100"},{default:s(({row:t})=>[n(l(t.recording_status_text||"—"),1)]),_:1}),o(r,{label:"录制回放","min-width":"280"},{default:s(({row:t})=>[(t.recording_urls_list||[]).length?(e(),i("div",Q,[(e(!0),i(F,null,A(t.recording_urls_list,(d,f)=>(e(),i("div",{key:f,class:"recording-item"},[v(d)?(e(),i("video",{key:0,src:d,controls:"",preload:"metadata",class:"recording-video"},null,8,S)):(e(),u(x,{key:1,href:d,target:"_blank",type:"primary"},{default:s(()=>[n(" 打开链接 "+l(f+1),1)]),_:2},1032,["href"]))]))),128))])):(e(),i("span",$,"暂无"))]),_:1})]),_:1},8,["data"])),[[I,m.value]])])}}}),Nt=G(j,[["__scopeId","data-v-b392e2ba"]]);export{Nt as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{i as L,L as T,N as V,U as D,M as z,T as M}from"./element-plus-6h1hTCrQ.js";import{U as P}from"./tcm-DompPo1O.js";import{f as F,b as j,w as A,ak as r,I as l,J as v,a as i,aN as s,O as m,aP as H,G as g,F as O,H as R}from"./@vue/runtime-core-C0pg79pw.js";import{y as d,o as w}from"./@vue/reactivity-BIbyPIZJ.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{_ as U}from"./index-55neFmjq.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const G={class:"case-record-list"},J={class:"mb-3 flex justify-end"},Q={key:0},Y={key:1,class:"text-gray-400"},q={class:"void-detail text-xs text-gray-500 mt-1"},K=F({__name:"CaseRecordList",props:{diagnosisId:{type:Number,default:0}},emits:["view","openPrescription"],setup(k,{expose:x,emit:C}){const _=k,y=C,n=w([]),p=w(!1),u=async()=>{if(_.diagnosisId){p.value=!0;try{const e=await P({diagnosis_id:_.diagnosisId});n.value=Array.isArray(e)?e:[]}catch(e){console.error("获取病历记录失败:",e),n.value=[]}finally{p.value=!1}}},S=e=>{if(!e)return"";const t=new Date(e*1e3);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},$=e=>{y("view",e)},E=()=>{y("openPrescription")};return j(()=>{u()}),A(()=>_.diagnosisId,()=>{u()}),x({refresh:u}),(e,t)=>{const h=L,a=V,b=D,N=z,B=M,I=T;return r(),l("div",G,[v("div",J,[i(h,{type:"primary",size:"small",onClick:E},{default:s(()=>[...t[0]||(t[0]=[m("开方",-1)])]),_:1})]),H((r(),g(N,{data:d(n),border:""},{default:s(()=>[i(a,{prop:"prescription_date",label:"就诊日期",width:"120"}),i(a,{prop:"visit_no",label:"门诊号",width:"120"}),i(a,{prop:"clinical_diagnosis",label:"临床诊断","min-width":"160","show-overflow-tooltip":""}),i(a,{label:"处方摘要","min-width":"180"},{default:s(({row:o})=>[o.herbs&&o.herbs.length?(r(),l("span",Q,c(o.herbs.slice(0,3).map(f=>`${f.name}${f.dosage}克`).join("、"))+c(o.herbs.length>3?"...":""),1)):(r(),l("span",Y,"—"))]),_:1}),i(a,{prop:"doctor_name",label:"医师",width:"90","show-overflow-tooltip":""}),i(a,{label:"状态",width:"140",align:"center"},{default:s(({row:o})=>[o.void_status===1?(r(),l(O,{key:0},[i(b,{type:"danger",size:"small"},{default:s(()=>[...t[1]||(t[1]=[m("已作废",-1)])]),_:1}),v("div",q,c(o.void_by_name||"—")+" "+c(S(o.void_time)),1)],64)):(r(),g(b,{key:1,type:"success",size:"small"},{default:s(()=>[...t[2]||(t[2]=[m("正常",-1)])]),_:1}))]),_:1}),i(a,{label:"操作",width:"120",fixed:"right"},{default:s(({row:o})=>[i(h,{link:"",type:"primary",size:"small",onClick:f=>$(o)},{default:s(()=>[...t[3]||(t[3]=[m(" 查看 ",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"])),[[I,d(p)]]),!d(p)&&d(n).length===0?(r(),g(B,{key:0,description:"暂无病历记录,开方后会自动显示",class:"mt-4"})):R("",!0)])}}}),zt=U(K,[["__scopeId","data-v-de802464"]]);export{zt as default};
|
||||
import{i as L,L as T,N as V,T as D,M as z,R as M}from"./element-plus-osWj3D3p.js";import{U as P}from"./tcm-7RUvcI90.js";import{f as F,b as R,w as j,ak as r,I as l,J as v,a as i,aN as s,O as m,aP as A,G as g,F as H,H as O}from"./@vue/runtime-core-C0pg79pw.js";import{y as d,o as w}from"./@vue/reactivity-BIbyPIZJ.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{_ as G}from"./index-xZXgRhuH.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const J={class:"case-record-list"},Q={class:"mb-3 flex justify-end"},U={key:0},Y={key:1,class:"text-gray-400"},q={class:"void-detail text-xs text-gray-500 mt-1"},K=F({__name:"CaseRecordList",props:{diagnosisId:{type:Number,default:0}},emits:["view","openPrescription"],setup(k,{expose:x,emit:C}){const _=k,y=C,n=w([]),p=w(!1),u=async()=>{if(_.diagnosisId){p.value=!0;try{const e=await P({diagnosis_id:_.diagnosisId});n.value=Array.isArray(e)?e:[]}catch(e){console.error("获取病历记录失败:",e),n.value=[]}finally{p.value=!1}}},S=e=>{if(!e)return"";const t=new Date(e*1e3);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},$=e=>{y("view",e)},E=()=>{y("openPrescription")};return R(()=>{u()}),j(()=>_.diagnosisId,()=>{u()}),x({refresh:u}),(e,t)=>{const h=L,a=V,b=D,N=z,B=M,I=T;return r(),l("div",J,[v("div",Q,[i(h,{type:"primary",size:"small",onClick:E},{default:s(()=>[...t[0]||(t[0]=[m("开方",-1)])]),_:1})]),A((r(),g(N,{data:d(n),border:""},{default:s(()=>[i(a,{prop:"prescription_date",label:"就诊日期",width:"120"}),i(a,{prop:"visit_no",label:"门诊号",width:"120"}),i(a,{prop:"clinical_diagnosis",label:"临床诊断","min-width":"160","show-overflow-tooltip":""}),i(a,{label:"处方摘要","min-width":"180"},{default:s(({row:o})=>[o.herbs&&o.herbs.length?(r(),l("span",U,c(o.herbs.slice(0,3).map(f=>`${f.name}${f.dosage}克`).join("、"))+c(o.herbs.length>3?"...":""),1)):(r(),l("span",Y,"—"))]),_:1}),i(a,{prop:"doctor_name",label:"医师",width:"90","show-overflow-tooltip":""}),i(a,{label:"状态",width:"140",align:"center"},{default:s(({row:o})=>[o.void_status===1?(r(),l(H,{key:0},[i(b,{type:"danger",size:"small"},{default:s(()=>[...t[1]||(t[1]=[m("已作废",-1)])]),_:1}),v("div",q,c(o.void_by_name||"—")+" "+c(S(o.void_time)),1)],64)):(r(),g(b,{key:1,type:"success",size:"small"},{default:s(()=>[...t[2]||(t[2]=[m("正常",-1)])]),_:1}))]),_:1}),i(a,{label:"操作",width:"120",fixed:"right"},{default:s(({row:o})=>[i(h,{link:"",type:"primary",size:"small",onClick:f=>$(o)},{default:s(()=>[...t[3]||(t[3]=[m(" 查看 ",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"])),[[I,d(p)]]),!d(p)&&d(n).length===0?(r(),g(B,{key:0,description:"暂无病历记录,开方后会自动显示",class:"mt-4"})):O("",!0)])}}}),zt=G(K,[["__scopeId","data-v-de802464"]]);export{zt as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.msg-bubble[data-v-b5ff1168]{display:flex;gap:10px;padding:10px 20px;align-items:flex-start}.msg-bubble.is-staff[data-v-b5ff1168]{flex-direction:row-reverse}.msg-bubble.is-staff .msg-body[data-v-b5ff1168]{align-items:flex-end}.msg-bubble.is-staff .msg-content.bubble-text[data-v-b5ff1168],.msg-bubble.is-staff .msg-content.bubble-file[data-v-b5ff1168]{background:#95ec69;color:#000}.msg-bubble .msg-avatar[data-v-b5ff1168]{flex-shrink:0;background:#d0d7de;color:#fff;font-size:12px}.msg-bubble .msg-body[data-v-b5ff1168]{display:flex;flex-direction:column;gap:4px;max-width:65%;min-width:0}.msg-bubble .msg-meta[data-v-b5ff1168]{display:flex;gap:8px;align-items:center;font-size:12px;color:#999}.msg-bubble .msg-sender[data-v-b5ff1168]{font-weight:500;color:#555}.msg-bubble .msg-content[data-v-b5ff1168]{padding:8px 12px;border-radius:6px;background:#fff;word-break:break-word;line-height:1.6;max-width:100%}.msg-bubble .msg-content.bubble-media[data-v-b5ff1168]{padding:0;background:transparent}.msg-bubble .content-text[data-v-b5ff1168]{white-space:pre-wrap}.msg-bubble .content-image[data-v-b5ff1168]{max-width:300px;max-height:300px;border-radius:6px;display:block}.msg-bubble .content-video[data-v-b5ff1168]{max-width:320px;max-height:320px;border-radius:6px;display:block}.msg-bubble .content-audio[data-v-b5ff1168]{max-width:260px}.msg-bubble .content-file[data-v-b5ff1168]{display:flex;gap:12px;align-items:center;min-width:220px;padding:4px 8px}.msg-bubble .content-file .file-meta[data-v-b5ff1168]{flex:1;min-width:0}.msg-bubble .content-file .file-name[data-v-b5ff1168]{font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.msg-bubble .content-file .file-info[data-v-b5ff1168]{font-size:12px;color:#888}.msg-bubble .content-pending[data-v-b5ff1168]{display:flex;gap:6px;align-items:center;color:#999;font-size:13px}.msg-bubble .content-fallback .fallback-title[data-v-b5ff1168]{font-size:13px;color:#666;margin-bottom:4px}.msg-bubble .content-fallback .fallback-desc[data-v-b5ff1168]{font-size:14px;color:#333}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.send-panel[data-v-afee3bd0]{display:flex;flex-direction:column;gap:8px;padding:12px 16px;background:#fafafa;border-top:1px solid #eee}.attachment-list[data-v-afee3bd0]{display:flex;flex-wrap:wrap;gap:8px}.attachment-list .attachment-item[data-v-afee3bd0]{position:relative;display:flex;align-items:center;gap:6px;padding:4px 8px;background:#fff;border:1px solid #ebeef5;border-radius:4px;max-width:220px}.attachment-list .attachment-item .attachment-preview[data-v-afee3bd0]{width:48px;height:48px;border-radius:4px;-o-object-fit:cover;object-fit:cover}.attachment-list .attachment-item .attachment-filename[data-v-afee3bd0]{max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.attachment-list .attachment-item .attachment-remove[data-v-afee3bd0]{position:absolute;top:-6px;right:-6px;padding:0}.send-toolbar[data-v-afee3bd0]{display:flex;justify-content:space-between;align-items:center}.send-toolbar .toolbar-left[data-v-afee3bd0]{display:flex;gap:4px}.send-toolbar .toolbar-right[data-v-afee3bd0]{display:flex;gap:12px;align-items:center}.send-toolbar .send-hint[data-v-afee3bd0]{color:#999;font-size:12px}.link-picurl-row[data-v-afee3bd0]{display:flex;gap:8px}.mini-preview[data-v-afee3bd0]{margin-top:8px;width:80px;height:80px;border-radius:4px;overflow:hidden;background:#f5f5f5}.mini-preview .el-image[data-v-afee3bd0]{width:100%;height:100%}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-_b_PJdrZ.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DsSo_l55.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-BE3d2FB8.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-9YImSnPn.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{D as h,B,G as q,I,C as D}from"./element-plus-6h1hTCrQ.js";import{P as F}from"./index-DsSo_l55.js";import{i as b}from"./index-55neFmjq.js";import{f as G,w,ak as j,G as P,aN as r,J as S,a,O as u,A as U}from"./@vue/runtime-core-C0pg79pw.js";import{y as n,u as y,r as A}from"./@vue/reactivity-BIbyPIZJ.js";import{Q as k}from"./@vue/shared-mAAVTE9n.js";const J={class:"pr-8"},K=G({__name:"account-adjust",props:{show:{type:Boolean,required:!0},value:{type:[Number,String],required:!0}},emits:["update:show","confirm"],setup(d,{emit:V}){const s=y(),i=d,f=V,o=A({action:1,num:"",remark:""}),m=y(),c=U(()=>Number(i.value)+Number(o.num)*(o.action==1?1:-1)),R={num:[{required:!0,message:"请输入调整的金额"}]},x=e=>{if(e.includes("-"))return b.msgError("请输入正整数");o.num=e},C=async()=>{var e;await((e=s.value)==null?void 0:e.validate()),f("confirm",o)},E=()=>{var e;f("update:show",!1),(e=s.value)==null||e.resetFields()};return w(()=>i.show,e=>{var t,l;e?(t=m.value)==null||t.open():(l=m.value)==null||l.close()}),w(c,e=>{e<0&&(b.msgError("调整后余额需大于0"),o.num="")}),(e,t)=>{const l=B,_=I,N=q,v=D,g=h;return j(),P(F,{ref_key:"popupRef",ref:m,title:"余额调整",width:"500px",onConfirm:C,async:!0,onClose:E},{default:r(()=>[S("div",J,[a(g,{ref_key:"formRef",ref:s,model:n(o),"label-width":"120px",rules:R},{default:r(()=>[a(l,{label:"当前余额"},{default:r(()=>[u("¥ "+k(d.value),1)]),_:1}),a(l,{label:"余额增减",required:"",prop:"action"},{default:r(()=>[a(N,{modelValue:n(o).action,"onUpdate:modelValue":t[0]||(t[0]=p=>n(o).action=p)},{default:r(()=>[a(_,{value:1},{default:r(()=>[...t[2]||(t[2]=[u("增加余额",-1)])]),_:1}),a(_,{value:2},{default:r(()=>[...t[3]||(t[3]=[u("扣减余额",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(l,{label:"调整余额",prop:"num"},{default:r(()=>[a(v,{"model-value":n(o).num,placeholder:"请输入调整的金额",type:"number",onInput:x},null,8,["model-value"])]),_:1}),a(l,{label:"调整后余额"},{default:r(()=>[u(" ¥ "+k(n(c)),1)]),_:1}),a(l,{label:"备注",prop:"remark"},{default:r(()=>[a(v,{modelValue:n(o).remark,"onUpdate:modelValue":t[1]||(t[1]=p=>n(o).remark=p),type:"textarea",rows:4},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])])]),_:1},512)}}});export{K as _};
|
||||
import{D as h,B,G as q,I,C as D}from"./element-plus-osWj3D3p.js";import{P as F}from"./index-9YImSnPn.js";import{i as b}from"./index-xZXgRhuH.js";import{f as G,w,ak as j,G as P,aN as r,J as S,a,O as u,A as U}from"./@vue/runtime-core-C0pg79pw.js";import{y as n,u as y,r as A}from"./@vue/reactivity-BIbyPIZJ.js";import{Q as k}from"./@vue/shared-mAAVTE9n.js";const J={class:"pr-8"},K=G({__name:"account-adjust",props:{show:{type:Boolean,required:!0},value:{type:[Number,String],required:!0}},emits:["update:show","confirm"],setup(d,{emit:V}){const s=y(),i=d,f=V,o=A({action:1,num:"",remark:""}),m=y(),c=U(()=>Number(i.value)+Number(o.num)*(o.action==1?1:-1)),R={num:[{required:!0,message:"请输入调整的金额"}]},x=e=>{if(e.includes("-"))return b.msgError("请输入正整数");o.num=e},C=async()=>{var e;await((e=s.value)==null?void 0:e.validate()),f("confirm",o)},E=()=>{var e;f("update:show",!1),(e=s.value)==null||e.resetFields()};return w(()=>i.show,e=>{var t,l;e?(t=m.value)==null||t.open():(l=m.value)==null||l.close()}),w(c,e=>{e<0&&(b.msgError("调整后余额需大于0"),o.num="")}),(e,t)=>{const l=B,_=I,N=q,v=D,g=h;return j(),P(F,{ref_key:"popupRef",ref:m,title:"余额调整",width:"500px",onConfirm:C,async:!0,onClose:E},{default:r(()=>[S("div",J,[a(g,{ref_key:"formRef",ref:s,model:n(o),"label-width":"120px",rules:R},{default:r(()=>[a(l,{label:"当前余额"},{default:r(()=>[u("¥ "+k(d.value),1)]),_:1}),a(l,{label:"余额增减",required:"",prop:"action"},{default:r(()=>[a(N,{modelValue:n(o).action,"onUpdate:modelValue":t[0]||(t[0]=p=>n(o).action=p)},{default:r(()=>[a(_,{value:1},{default:r(()=>[...t[2]||(t[2]=[u("增加余额",-1)])]),_:1}),a(_,{value:2},{default:r(()=>[...t[3]||(t[3]=[u("扣减余额",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(l,{label:"调整余额",prop:"num"},{default:r(()=>[a(v,{"model-value":n(o).num,placeholder:"请输入调整的金额",type:"number",onInput:x},null,8,["model-value"])]),_:1}),a(l,{label:"调整后余额"},{default:r(()=>[u(" ¥ "+k(n(c)),1)]),_:1}),a(l,{label:"备注",prop:"remark"},{default:r(()=>[a(v,{modelValue:n(o).remark,"onUpdate:modelValue":t[1]||(t[1]=p=>n(o).remark=p),type:"textarea",rows:4},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])])]),_:1},512)}}});export{K as _};
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./add-nav.vue_vue_type_script_setup_true_lang-CH3jNlCp.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
import{_ as o}from"./add-nav.vue_vue_type_script_setup_true_lang-0VBUUpOA.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{C as E,B,g as C,i as N}from"./element-plus-6h1hTCrQ.js";import{_ as $}from"./index-vledklw3.js";import{_ as z}from"./picker-B6Dcn_V9.js";import{_ as A}from"./picker-RR6i8slw.js";import{c as D,i as r}from"./index-55neFmjq.js";import{D as I}from"./vuedraggable-C3E4D3Yv.js";import{f as R,ak as p,I as F,J as l,a,aN as d,G,O as J,A as L}from"./@vue/runtime-core-C0pg79pw.js";import{y as c,a as O}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"bg-fill-light flex items-center w-full p-4 mb-4"},S={class:"upload-btn w-[60px] h-[60px]"},T={class:"ml-3 flex-1"},j={class:"flex items-center"},q={class:"flex items-center mt-[18px]"},H={class:"flex-1 flex items-center"},K={class:"drag-move cursor-move ml-auto"},oe=R({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:100},min:{type:Number,default:1}},emits:["update:modelValue"],setup(_,{emit:f}){const t=_,V=f,m=L({get(){return t.modelValue},set(s){V("update:modelValue",s)}}),x=()=>{var s;((s=t.modelValue)==null?void 0:s.length)<t.max?m.value.push({image:"",name:"导航名称",link:{},is_show:"1"}):r.msgError(`最多添加${t.max}个`)},g=s=>{var e;if(((e=t.modelValue)==null?void 0:e.length)<=t.min)return r.msgError(`最少保留${t.min}个`);m.value.splice(s,1)};return(s,e)=>{const i=D,v=A,h=E,k=z,b=C,w=B,y=$,U=N;return p(),F("div",null,[l("div",null,[a(c(I),{class:"draggable",modelValue:c(m),"onUpdate:modelValue":e[0]||(e[0]=o=>O(m)?m.value=o:null),animation:"300",handle:".drag-move","item-key":"index"},{item:d(({element:o,index:u})=>[(p(),G(y,{class:"w-[467px]",key:u,onClose:n=>g(u)},{default:d(()=>[l("div",P,[a(v,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:d(()=>[l("div",S,[a(i,{name:"el-icon-Plus",size:20})])]),_:1},8,["modelValue","onUpdate:modelValue"]),l("div",T,[l("div",j,[e[1]||(e[1]=l("span",{class:"text-tx-regular flex-none mr-3"},"名称",-1)),a(h,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),l("div",q,[e[2]||(e[2]=l("span",{class:"text-tx-regular flex-none mr-3"},"链接",-1)),a(k,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),a(w,{label:"是否显示",class:"mt-[18px]"},{default:d(()=>[l("div",H,[a(b,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),l("div",K,[a(i,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),l("div",null,[a(U,{type:"primary",onClick:x},{default:d(()=>[...e[3]||(e[3]=[J("添加",-1)])]),_:1})])])}}});export{oe as _};
|
||||
import{C as E,B,g as C,i as N}from"./element-plus-osWj3D3p.js";import{_ as $}from"./index-P75bTQgB.js";import{_ as z}from"./picker-CGqg4FNQ.js";import{_ as A}from"./picker-Der0ecbS.js";import{c as D,i as r}from"./index-xZXgRhuH.js";import{D as I}from"./vuedraggable-C3E4D3Yv.js";import{f as R,ak as p,I as F,J as l,a,aN as d,G,O as J,A as L}from"./@vue/runtime-core-C0pg79pw.js";import{y as c,a as O}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"bg-fill-light flex items-center w-full p-4 mb-4"},S={class:"upload-btn w-[60px] h-[60px]"},T={class:"ml-3 flex-1"},j={class:"flex items-center"},q={class:"flex items-center mt-[18px]"},H={class:"flex-1 flex items-center"},K={class:"drag-move cursor-move ml-auto"},oe=R({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:100},min:{type:Number,default:1}},emits:["update:modelValue"],setup(_,{emit:f}){const t=_,V=f,m=L({get(){return t.modelValue},set(s){V("update:modelValue",s)}}),x=()=>{var s;((s=t.modelValue)==null?void 0:s.length)<t.max?m.value.push({image:"",name:"导航名称",link:{},is_show:"1"}):r.msgError(`最多添加${t.max}个`)},g=s=>{var e;if(((e=t.modelValue)==null?void 0:e.length)<=t.min)return r.msgError(`最少保留${t.min}个`);m.value.splice(s,1)};return(s,e)=>{const i=D,v=A,h=E,k=z,b=C,w=B,y=$,U=N;return p(),F("div",null,[l("div",null,[a(c(I),{class:"draggable",modelValue:c(m),"onUpdate:modelValue":e[0]||(e[0]=o=>O(m)?m.value=o:null),animation:"300",handle:".drag-move","item-key":"index"},{item:d(({element:o,index:u})=>[(p(),G(y,{class:"w-[467px]",key:u,onClose:n=>g(u)},{default:d(()=>[l("div",P,[a(v,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:d(()=>[l("div",S,[a(i,{name:"el-icon-Plus",size:20})])]),_:1},8,["modelValue","onUpdate:modelValue"]),l("div",T,[l("div",j,[e[1]||(e[1]=l("span",{class:"text-tx-regular flex-none mr-3"},"名称",-1)),a(h,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),l("div",q,[e[2]||(e[2]=l("span",{class:"text-tx-regular flex-none mr-3"},"链接",-1)),a(k,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),a(w,{label:"是否显示",class:"mt-[18px]"},{default:d(()=>[l("div",H,[a(b,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),l("div",K,[a(i,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),l("div",null,[a(U,{type:"primary",onClick:x},{default:d(()=>[...e[3]||(e[3]=[J("添加",-1)])]),_:1})])])}}});export{oe as _};
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{r as n}from"./index-55neFmjq.js";function e(t){return n.get({url:"/auth.admin/lists",params:t},{ignoreCancelToken:!0})}function i(t){return n.post({url:"/auth.admin/add",params:t})}function r(t){return n.post({url:"/auth.admin/edit",params:t})}function u(t){return n.post({url:"/auth.admin/delete",params:t})}function d(t){return n.get({url:"/auth.admin/detail",params:t})}export{e as a,r as b,u as c,i as d,d as e};
|
||||
import{r as n}from"./index-xZXgRhuH.js";function e(t){return n.get({url:"/auth.admin/lists",params:t},{ignoreCancelToken:!0})}function i(t){return n.post({url:"/auth.admin/add",params:t})}function r(t){return n.post({url:"/auth.admin/edit",params:t})}function u(t){return n.post({url:"/auth.admin/delete",params:t})}function d(t){return n.get({url:"/auth.admin/detail",params:t})}export{e as a,r as b,u as c,i as d,d as e};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{r as e}from"./index-55neFmjq.js";function a(t){return e.get({url:"/article.articleCate/lists",params:t})}function l(t){return e.get({url:"/article.articleCate/all",params:t})}function i(t){return e.post({url:"/article.articleCate/add",params:t})}function c(t){return e.post({url:"/article.articleCate/edit",params:t})}function u(t){return e.post({url:"/article.articleCate/delete",params:t})}function n(t){return e.get({url:"/article.articleCate/detail",params:t})}function s(t){return e.post({url:"/article.articleCate/updateStatus",params:t})}function o(t){return e.get({url:"/article.article/lists",params:t})}function d(t){return e.post({url:"/article.article/add",params:t})}function f(t){return e.post({url:"/article.article/edit",params:t})}function C(t){return e.post({url:"/article.article/delete",params:t})}function p(t){return e.get({url:"/article.article/detail",params:t})}function g(t){return e.post({url:"/article.article/updateStatus",params:t})}export{a,u as b,s as c,c as d,i as e,n as f,p as g,f as h,d as i,l as j,o as k,g as l,C as m};
|
||||
import{r as e}from"./index-xZXgRhuH.js";function a(t){return e.get({url:"/article.articleCate/lists",params:t})}function l(t){return e.get({url:"/article.articleCate/all",params:t})}function i(t){return e.post({url:"/article.articleCate/add",params:t})}function c(t){return e.post({url:"/article.articleCate/edit",params:t})}function u(t){return e.post({url:"/article.articleCate/delete",params:t})}function n(t){return e.get({url:"/article.articleCate/detail",params:t})}function s(t){return e.post({url:"/article.articleCate/updateStatus",params:t})}function o(t){return e.get({url:"/article.article/lists",params:t})}function d(t){return e.post({url:"/article.article/add",params:t})}function f(t){return e.post({url:"/article.article/edit",params:t})}function C(t){return e.post({url:"/article.article/delete",params:t})}function p(t){return e.get({url:"/article.article/detail",params:t})}function g(t){return e.post({url:"/article.article/updateStatus",params:t})}export{a,u as b,s as c,c as d,i as e,n as f,p as g,f as h,d as i,l as j,o as k,g as l,C as m};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Ca8elUNx.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-CH3jNlCp.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DNaDJS2k.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-0VBUUpOA.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Cwa8U5_P.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CW9idRxL.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DdzChMj0.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-CH3jNlCp.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Dp2PD0F6.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-0VBUUpOA.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Byi24hV9.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./picker-RR6i8slw.js";import"./index-DsSo_l55.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-B687Zw9l.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./index-vledklw3.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./usePaging-B_C_SZ2Z.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DsRNG8AO.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./picker-Der0ecbS.js";import"./index-9YImSnPn.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-B9vGwckb.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./index-P75bTQgB.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./usePaging-B_C_SZ2Z.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{m as b,l as c,D as V}from"./element-plus-6h1hTCrQ.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-6xcaC9K4.js";import{f as v,ak as x,I as k,J as E,a as o,aN as e,F as g,A as w}from"./@vue/runtime-core-C0pg79pw.js";import{y as r}from"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";const yt=v({__name:"attr",props:{modelValue:{type:Object,default:()=>({nav:[],menu:{}})}},emits:["update:modelValue"],setup(n,{emit:s}){const u=n,d=s,m=w({get(){return u.modelValue},set(i){d("update:modelValue",i)}});return(i,t)=>{const a=c,f=b,_=V;return x(),k(g,null,[t[2]||(t[2]=E("div",{class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"}," pc导航设置 ",-1)),o(_,{class:"mt-4","label-width":"70px"},{default:e(()=>[o(f,{"model-value":"nav"},{default:e(()=>[o(a,{label:"主导航设置",name:"nav"},{default:e(()=>[o(l,{modelValue:r(m).nav,"onUpdate:modelValue":t[0]||(t[0]=p=>r(m).nav=p)},null,8,["modelValue"])]),_:1}),o(a,{label:"菜单设置",name:"menu"},{default:e(()=>[o(l,{modelValue:r(m).menu,"onUpdate:modelValue":t[1]||(t[1]=p=>r(m).menu=p)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})],64)}}});export{yt as default};
|
||||
import{m as b,l as c,D as V}from"./element-plus-osWj3D3p.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-CDWwwb7g.js";import{f as v,ak as x,I as k,J as E,a as o,aN as e,F as g,A as w}from"./@vue/runtime-core-C0pg79pw.js";import{y as r}from"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";const yt=v({__name:"attr",props:{modelValue:{type:Object,default:()=>({nav:[],menu:{}})}},emits:["update:modelValue"],setup(n,{emit:s}){const u=n,d=s,m=w({get(){return u.modelValue},set(i){d("update:modelValue",i)}});return(i,t)=>{const a=c,f=b,_=V;return x(),k(g,null,[t[2]||(t[2]=E("div",{class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"}," pc导航设置 ",-1)),o(_,{class:"mt-4","label-width":"70px"},{default:e(()=>[o(f,{"model-value":"nav"},{default:e(()=>[o(a,{label:"主导航设置",name:"nav"},{default:e(()=>[o(l,{modelValue:r(m).nav,"onUpdate:modelValue":t[0]||(t[0]=p=>r(m).nav=p)},null,8,["modelValue"])]),_:1}),o(a,{label:"菜单设置",name:"menu"},{default:e(()=>[o(l,{modelValue:r(m).menu,"onUpdate:modelValue":t[1]||(t[1]=p=>r(m).menu=p)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})],64)}}});export{yt as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DxClgwIr.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BXMBQSFw.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-ZHFXoyNu.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./index.vue_vue_type_script_setup_true_lang-DfgBCqWg.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Be2nmFCm.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./index.vue_vue_type_script_setup_true_lang-BQXRM6_y.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CMmNjPvE.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index.vue_vue_type_script_setup_true_lang-DfgBCqWg.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./picker-RR6i8slw.js";import"./index-DsSo_l55.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-B687Zw9l.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./index-vledklw3.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./usePaging-B_C_SZ2Z.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-B__HpciW.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index.vue_vue_type_script_setup_true_lang-BQXRM6_y.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./picker-Der0ecbS.js";import"./index-9YImSnPn.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-B9vGwckb.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./index-P75bTQgB.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./usePaging-B_C_SZ2Z.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-Dcouxod6.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-CSs1DpQp.js";import"./attr-CECezgG5.js";import"./index-vledklw3.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-B6Dcn_V9.js";import"./index-DsSo_l55.js";import"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import"./article-DaMXj9hD.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-RR6i8slw.js";import"./index-B687Zw9l.js";import"./index-D6IS__U-.js";import"./index.vue_vue_type_script_setup_true_lang-CU4vN34y.js";import"./file-Bl00fTDO.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./content.vue_vue_type_script_setup_true_lang-CpnarxEs.js";import"./decoration-img-DGr8eZBc.js";import"./attr.vue_vue_type_script_setup_true_lang-Byi24hV9.js";import"./content-Dtm7T4Lc.js";import"./attr.vue_vue_type_script_setup_true_lang-DxClgwIr.js";import"./content.vue_vue_type_script_setup_true_lang-Br4ZeErc.js";import"./attr.vue_vue_type_script_setup_true_lang-Ca8elUNx.js";import"./add-nav.vue_vue_type_script_setup_true_lang-CH3jNlCp.js";import"./content-BCOjmpzp.js";import"./attr.vue_vue_type_script_setup_true_lang-DdzChMj0.js";import"./content.vue_vue_type_script_setup_true_lang-BIu3Xfg2.js";import"./attr.vue_vue_type_script_setup_true_lang-CfPY9LZg.js";import"./content-cW6CVBV3.js";import"./decoration-CXCDHeoq.js";import"./attr.vue_vue_type_script_setup_true_lang-CMmNjPvE.js";import"./index.vue_vue_type_script_setup_true_lang-DfgBCqWg.js";import"./content-C-CnUgTr.js";import"./content.vue_vue_type_script_setup_true_lang-BaYIBtwJ.js";import"./attr.vue_vue_type_script_setup_true_lang-eatfXr14.js";import"./content-3OpUaWtf.js";import"./attr.vue_vue_type_script_setup_true_lang-Cwa8U5_P.js";import"./content.vue_vue_type_script_setup_true_lang-DNDbw7P9.js";import"./attr.vue_vue_type_script_setup_true_lang-11IwTsyi.js";import"./content-BhKrWJjv.js";export{o as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-Dgf-3PiC.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DbmS5QgH.js";import"./attr-DZ6wkRAQ.js";import"./index-P75bTQgB.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-CGqg4FNQ.js";import"./index-9YImSnPn.js";import"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import"./article-CVr2sQde.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Der0ecbS.js";import"./index-B9vGwckb.js";import"./index-BNTs4h_w.js";import"./index.vue_vue_type_script_setup_true_lang-8jySDNH4.js";import"./file-B0mYsl3b.js";import"./vuedraggable-C3E4D3Yv.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./content.vue_vue_type_script_setup_true_lang-DKaKmkDy.js";import"./decoration-img-CKm1nxte.js";import"./attr.vue_vue_type_script_setup_true_lang-DsRNG8AO.js";import"./content-CG8HWzH9.js";import"./attr.vue_vue_type_script_setup_true_lang-CW9idRxL.js";import"./content.vue_vue_type_script_setup_true_lang-BRZYAhOX.js";import"./attr.vue_vue_type_script_setup_true_lang-DNaDJS2k.js";import"./add-nav.vue_vue_type_script_setup_true_lang-0VBUUpOA.js";import"./content-BDvcF9yO.js";import"./attr.vue_vue_type_script_setup_true_lang-Dp2PD0F6.js";import"./content.vue_vue_type_script_setup_true_lang-Bqha-Grv.js";import"./attr.vue_vue_type_script_setup_true_lang-CfPY9LZg.js";import"./content-ClvUnAmZ.js";import"./decoration-DorZNrhC.js";import"./attr.vue_vue_type_script_setup_true_lang-B__HpciW.js";import"./index.vue_vue_type_script_setup_true_lang-BQXRM6_y.js";import"./content-CuMx5H4u.js";import"./content.vue_vue_type_script_setup_true_lang-ByPSPrxz.js";import"./attr.vue_vue_type_script_setup_true_lang-eatfXr14.js";import"./content-BqaFBvyA.js";import"./attr.vue_vue_type_script_setup_true_lang-BXMBQSFw.js";import"./content.vue_vue_type_script_setup_true_lang-CXXpePlK.js";import"./attr.vue_vue_type_script_setup_true_lang-11IwTsyi.js";import"./content-D_nxNe3i.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{J as y,s as g}from"./element-plus-6h1hTCrQ.js";import{e as b}from"./index-CSs1DpQp.js";import{f as x,ak as o,I as _,a as r,aN as c,J as h,G as i,K as w,at as k}from"./@vue/runtime-core-C0pg79pw.js";import{Q as v}from"./@vue/shared-mAAVTE9n.js";import{y as C}from"./@vue/reactivity-BIbyPIZJ.js";const B={class:"pages-setting"},E={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2 text-xl font-medium"},V=x({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(e,{emit:m}){const d=m,p=a=>{d("update:content",a)};return(a,N)=>{const f=y,u=g;return o(),_("div",B,[r(f,{shadow:"never",class:"!border-none flex"},{default:c(()=>{var t;return[h("div",E,v((t=e.widget)==null?void 0:t.title),1)]}),_:1}),r(u,{class:"w-full",style:{height:"calc(100% - 60px)"}},{default:c(()=>{var t,n,s,l;return[(o(),i(w,null,[(o(),i(k((n=C(b)[(t=e.widget)==null?void 0:t.name])==null?void 0:n.attr),{content:(s=e.widget)==null?void 0:s.content,styles:(l=e.widget)==null?void 0:l.styles,type:e.type,"onUpdate:content":p},null,40,["content","styles","type"]))],1024))]}),_:1})])}}});export{V as _};
|
||||
import{J as y,s as g}from"./element-plus-osWj3D3p.js";import{e as b}from"./index-DbmS5QgH.js";import{f as x,ak as o,I as _,a as r,aN as c,J as h,G as i,K as w,at as k}from"./@vue/runtime-core-C0pg79pw.js";import{Q as v}from"./@vue/shared-mAAVTE9n.js";import{y as C}from"./@vue/reactivity-BIbyPIZJ.js";const B={class:"pages-setting"},E={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2 text-xl font-medium"},V=x({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(e,{emit:m}){const d=m,p=a=>{d("update:content",a)};return(a,N)=>{const f=y,u=g;return o(),_("div",B,[r(f,{shadow:"never",class:"!border-none flex"},{default:c(()=>{var t;return[h("div",E,v((t=e.widget)==null?void 0:t.title),1)]}),_:1}),r(u,{class:"w-full",style:{height:"calc(100% - 60px)"}},{default:c(()=>{var t,n,s,l;return[(o(),i(w,null,[(o(),i(k((n=C(b)[(t=e.widget)==null?void 0:t.name])==null?void 0:n.attr),{content:(s=e.widget)==null?void 0:s.content,styles:(l=e.widget)==null?void 0:l.styles,type:e.type,"onUpdate:content":p},null,40,["content","styles","type"]))],1024))]}),_:1})])}}});export{V as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{J as I,B as O,C as j,g as A,i as F,D as J}from"./element-plus-6h1hTCrQ.js";import{_ as z}from"./index-vledklw3.js";import{c as G,i as g}from"./index-55neFmjq.js";import{_ as H}from"./picker-B6Dcn_V9.js";import{_ as R}from"./picker-RR6i8slw.js";import{D as S}from"./vuedraggable-C3E4D3Yv.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as T,ak as _,I as h,a as t,aN as a,J as s,G as q,O as K,H as L,A as M}from"./@vue/runtime-core-C0pg79pw.js";import{y as p}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"bg-fill-light flex items-center w-full p-4 mt-4"},Q={class:"ml-3 flex-1"},W={class:"flex-1 flex items-center"},X={class:"drag-move cursor-move ml-auto"},Y={key:0,class:"mt-4"},r=5,ce=T({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:k}){const d=k,m=u,f=M({get:()=>m.content,set:l=>{d("update:content",l)}}),b=()=>{var l;if(((l=m.content.data)==null?void 0:l.length)<r){const e=v(m.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),d("update:content",e)}else g.msgError(`最多添加${r}张图片`)},w=l=>{var c;if(((c=m.content.data)==null?void 0:c.length)<=1)return g.msgError("最少保留一张图片");const e=v(m.content);e.data.splice(l,1),d("update:content",e)};return(l,e)=>{const c=R,y=j,i=O,E=H,U=A,C=G,B=z,D=F,N=I,$=J;return _(),h("div",null,[t($,{"label-width":"70px"},{default:a(()=>[t(N,{shadow:"never",class:"!border-none flex mt-2"},{default:a(()=>{var x;return[e[2]||(e[2]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单"),s("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),t(p(S),{class:"draggable",modelValue:p(f).data,"onUpdate:modelValue":e[0]||(e[0]=o=>p(f).data=o),animation:"300",handle:".drag-move","item-key":"index"},{item:a(({element:o,index:V})=>[(_(),q(B,{key:V,onClose:n=>w(V),class:"w-[467px]"},{default:a(()=>[s("div",P,[t(c,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),s("div",Q,[t(i,{label:"图片名称"},{default:a(()=>[t(y,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{class:"mt-[18px]",label:"图片链接"},{default:a(()=>[t(E,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{label:"是否显示",class:"mt-[18px]"},{default:a(()=>[s("div",W,[t(U,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),s("div",X,[t(C,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"]),((x=u.content.data)==null?void 0:x.length)<r?(_(),h("div",Y,[t(D,{class:"w-full",type:"primary",onClick:b},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{ce as _};
|
||||
import{J as I,B as O,C as j,g as A,i as F,D as J}from"./element-plus-osWj3D3p.js";import{_ as z}from"./index-P75bTQgB.js";import{c as G,i as g}from"./index-xZXgRhuH.js";import{_ as H}from"./picker-CGqg4FNQ.js";import{_ as R}from"./picker-Der0ecbS.js";import{D as S}from"./vuedraggable-C3E4D3Yv.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as T,ak as _,I as h,a as t,aN as a,J as s,G as q,O as K,H as L,A as M}from"./@vue/runtime-core-C0pg79pw.js";import{y as p}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"bg-fill-light flex items-center w-full p-4 mt-4"},Q={class:"ml-3 flex-1"},W={class:"flex-1 flex items-center"},X={class:"drag-move cursor-move ml-auto"},Y={key:0,class:"mt-4"},r=5,ce=T({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:k}){const d=k,m=u,f=M({get:()=>m.content,set:l=>{d("update:content",l)}}),b=()=>{var l;if(((l=m.content.data)==null?void 0:l.length)<r){const e=v(m.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),d("update:content",e)}else g.msgError(`最多添加${r}张图片`)},w=l=>{var c;if(((c=m.content.data)==null?void 0:c.length)<=1)return g.msgError("最少保留一张图片");const e=v(m.content);e.data.splice(l,1),d("update:content",e)};return(l,e)=>{const c=R,y=j,i=O,E=H,U=A,C=G,B=z,D=F,N=I,$=J;return _(),h("div",null,[t($,{"label-width":"70px"},{default:a(()=>[t(N,{shadow:"never",class:"!border-none flex mt-2"},{default:a(()=>{var x;return[e[2]||(e[2]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单"),s("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),t(p(S),{class:"draggable",modelValue:p(f).data,"onUpdate:modelValue":e[0]||(e[0]=o=>p(f).data=o),animation:"300",handle:".drag-move","item-key":"index"},{item:a(({element:o,index:V})=>[(_(),q(B,{key:V,onClose:n=>w(V),class:"w-[467px]"},{default:a(()=>[s("div",P,[t(c,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),s("div",Q,[t(i,{label:"图片名称"},{default:a(()=>[t(y,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{class:"mt-[18px]",label:"图片链接"},{default:a(()=>[t(E,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{label:"是否显示",class:"mt-[18px]"},{default:a(()=>[s("div",W,[t(U,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),s("div",X,[t(C,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"]),((x=u.content.data)==null?void 0:x.length)<r?(_(),h("div",Y,[t(D,{class:"w-full",type:"primary",onClick:b},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{ce as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{J as E,B as C,G as F,I as N,C as B,D as z}from"./element-plus-6h1hTCrQ.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-DfgBCqWg.js";import{_ as I}from"./picker-RR6i8slw.js";import{f as O,ak as r,G as s,aN as t,a as l,O as p,H as i,J as y,A as j}from"./@vue/runtime-core-C0pg79pw.js";import{y as a}from"./@vue/reactivity-BIbyPIZJ.js";const T=O({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(m,{emit:g}){const b=g,x=m,o=j({get:()=>x.content,set:_=>{b("update:content",_)}});return(_,e)=>{const u=N,f=F,d=C,k=B,V=I,v=G,U=E,w=z;return r(),s(w,{ref:"form","label-width":"80px",size:"large"},{default:t(()=>[l(U,{shadow:"never",class:"!border-none flex mt-2"},{default:t(()=>[l(d,{label:"页面标题"},{default:t(()=>[l(f,{modelValue:a(o).title_type,"onUpdate:modelValue":e[0]||(e[0]=n=>a(o).title_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[7]||(e[7]=[p("文字",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[8]||(e[8]=[p("图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.title_type==1?(r(),s(d,{key:0},{default:t(()=>[l(k,{modelValue:a(o).title,"onUpdate:modelValue":e[1]||(e[1]=n=>a(o).title=n),maxlength:"8","show-word-limit":"",class:"w-[300px]",placeholder:"请输入页面标题"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.title_type==2?(r(),s(d,{key:1},{default:t(()=>[l(V,{modelValue:a(o).title_img,"onUpdate:modelValue":e[2]||(e[2]=n=>a(o).title_img=n),limit:1,size:"100px"},null,8,["modelValue"]),e[9]||(e[9]=y("div",{class:"form-tips"},"建议图片尺寸:300px*40px",-1))]),_:1})):i("",!0),m.content.title_type==1?(r(),s(d,{key:2,label:"文字颜色"},{default:t(()=>[l(f,{modelValue:a(o).text_color,"onUpdate:modelValue":e[3]||(e[3]=n=>a(o).text_color=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[10]||(e[10]=[p("白色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[11]||(e[11]=[p("黑色",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1})):i("",!0),l(d,{label:"页面背景"},{default:t(()=>[l(f,{modelValue:a(o).bg_type,"onUpdate:modelValue":e[4]||(e[4]=n=>a(o).bg_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[12]||(e[12]=[p("背景颜色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[13]||(e[13]=[p("背景图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.bg_type==1?(r(),s(d,{key:3},{default:t(()=>[l(v,{modelValue:a(o).bg_color,"onUpdate:modelValue":e[5]||(e[5]=n=>a(o).bg_color=n),"reset-color":"#F5F5F5"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.bg_type==2?(r(),s(d,{key:4},{default:t(()=>[l(V,{modelValue:a(o).bg_image,"onUpdate:modelValue":e[6]||(e[6]=n=>a(o).bg_image=n),limit:1,size:"100px"},null,8,["modelValue"]),e[14]||(e[14]=y("div",{class:"form-tips"},"建议图片尺寸:750px*高度不限",-1))]),_:1})):i("",!0)]),_:1})]),_:1},512)}}});export{T as _};
|
||||
import{J as E,B as C,G as F,I as N,C as B,D as z}from"./element-plus-osWj3D3p.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-BQXRM6_y.js";import{_ as I}from"./picker-Der0ecbS.js";import{f as O,ak as r,G as s,aN as t,a as l,O as p,H as i,J as y,A as j}from"./@vue/runtime-core-C0pg79pw.js";import{y as a}from"./@vue/reactivity-BIbyPIZJ.js";const T=O({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(m,{emit:g}){const b=g,x=m,o=j({get:()=>x.content,set:_=>{b("update:content",_)}});return(_,e)=>{const u=N,f=F,d=C,k=B,V=I,v=G,U=E,w=z;return r(),s(w,{ref:"form","label-width":"80px",size:"large"},{default:t(()=>[l(U,{shadow:"never",class:"!border-none flex mt-2"},{default:t(()=>[l(d,{label:"页面标题"},{default:t(()=>[l(f,{modelValue:a(o).title_type,"onUpdate:modelValue":e[0]||(e[0]=n=>a(o).title_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[7]||(e[7]=[p("文字",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[8]||(e[8]=[p("图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.title_type==1?(r(),s(d,{key:0},{default:t(()=>[l(k,{modelValue:a(o).title,"onUpdate:modelValue":e[1]||(e[1]=n=>a(o).title=n),maxlength:"8","show-word-limit":"",class:"w-[300px]",placeholder:"请输入页面标题"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.title_type==2?(r(),s(d,{key:1},{default:t(()=>[l(V,{modelValue:a(o).title_img,"onUpdate:modelValue":e[2]||(e[2]=n=>a(o).title_img=n),limit:1,size:"100px"},null,8,["modelValue"]),e[9]||(e[9]=y("div",{class:"form-tips"},"建议图片尺寸:300px*40px",-1))]),_:1})):i("",!0),m.content.title_type==1?(r(),s(d,{key:2,label:"文字颜色"},{default:t(()=>[l(f,{modelValue:a(o).text_color,"onUpdate:modelValue":e[3]||(e[3]=n=>a(o).text_color=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[10]||(e[10]=[p("白色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[11]||(e[11]=[p("黑色",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1})):i("",!0),l(d,{label:"页面背景"},{default:t(()=>[l(f,{modelValue:a(o).bg_type,"onUpdate:modelValue":e[4]||(e[4]=n=>a(o).bg_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[12]||(e[12]=[p("背景颜色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[13]||(e[13]=[p("背景图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.bg_type==1?(r(),s(d,{key:3},{default:t(()=>[l(v,{modelValue:a(o).bg_color,"onUpdate:modelValue":e[5]||(e[5]=n=>a(o).bg_color=n),"reset-color":"#F5F5F5"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.bg_type==2?(r(),s(d,{key:4},{default:t(()=>[l(V,{modelValue:a(o).bg_image,"onUpdate:modelValue":e[6]||(e[6]=n=>a(o).bg_image=n),limit:1,size:"100px"},null,8,["modelValue"]),e[14]||(e[14]=y("div",{class:"form-tips"},"建议图片尺寸:750px*高度不限",-1))]),_:1})):i("",!0)]),_:1})]),_:1},512)}}});export{T as _};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{J as j,B as A,C as F,g as J,i as S,D as z}from"./element-plus-6h1hTCrQ.js";import{_ as G}from"./index-vledklw3.js";import{c as H,i as k}from"./index-55neFmjq.js";import{_ as R}from"./picker-B6Dcn_V9.js";import{_ as T}from"./picker-RR6i8slw.js";import{D as q}from"./vuedraggable-C3E4D3Yv.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as K,ak as d,I as b,a as o,aN as s,J as n,G as u,H as r,O as L,A as M}from"./@vue/runtime-core-C0pg79pw.js";import{y as _}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"flex-1"},Q={class:"bg-fill-light w-full p-4 mt-4"},W={class:"flex-1"},X={class:"flex-1 flex items-center"},Y={class:"drag-move cursor-move ml-auto"},Z={key:0,class:"mt-4"},f=5,me=K({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(m,{emit:y}){const p=y,c=m,g=M({get:()=>c.content,set:a=>{p("update:content",a)}}),w=()=>{var a;if(((a=c.content.data)==null?void 0:a.length)<f){const e=v(c.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),p("update:content",e)}else k.msgError(`最多添加${f}张图片`)},E=a=>{var i;if(((i=c.content.data)==null?void 0:i.length)<=1)return k.msgError("最少保留一张图片");const e=v(c.content);e.data.splice(a,1),p("update:content",e)};return(a,e)=>{const i=T,U=R,C=F,h=A,B=J,D=H,N=G,$=S,I=j,O=z;return d(),b("div",null,[o(O,{"label-width":"70px"},{default:s(()=>[o(I,{shadow:"never",class:"!border-none flex mt-2"},{default:s(()=>{var x;return[e[2]||(e[2]=n("div",{class:"flex items-end"},[n("div",{class:"text-base text-[#101010] font-medium"},"图片设置"),n("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),n("div",P,[o(_(q),{class:"draggable",modelValue:_(g).data,"onUpdate:modelValue":e[0]||(e[0]=t=>_(g).data=t),animation:"300",handle:".drag-move"},{item:s(({element:t,index:V})=>[(d(),u(N,{key:V,onClose:l=>E(V),class:"w-full"},{default:s(()=>[n("div",Q,[o(i,{width:"396px",height:"196px",modelValue:t.image,"onUpdate:modelValue":l=>t.image=l,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),n("div",W,[o(h,{class:"mt-[18px]",label:"图片链接"},{default:s(()=>[m.type=="mobile"?(d(),u(U,{key:0,modelValue:t.link,"onUpdate:modelValue":l=>t.link=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0),m.type=="pc"?(d(),u(C,{key:1,placeholder:"请输入链接",modelValue:t.link.path,"onUpdate:modelValue":l=>t.link.path=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0)]),_:2},1024),o(h,{label:"是否显示",class:"mt-[18px] !mb-0"},{default:s(()=>[n("div",X,[o(B,{modelValue:t.is_show,"onUpdate:modelValue":l=>t.is_show=l,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),n("div",Y,[o(D,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),((x=m.content.data)==null?void 0:x.length)<f?(d(),b("div",Z,[o($,{class:"w-full",type:"primary",onClick:w},{default:s(()=>[...e[1]||(e[1]=[L("添加图片",-1)])]),_:1})])):r("",!0)]}),_:1})]),_:1})])}}});export{me as _};
|
||||
import{J as j,B as A,C as F,g as J,i as S,D as z}from"./element-plus-osWj3D3p.js";import{_ as G}from"./index-P75bTQgB.js";import{c as H,i as k}from"./index-xZXgRhuH.js";import{_ as R}from"./picker-CGqg4FNQ.js";import{_ as T}from"./picker-Der0ecbS.js";import{D as q}from"./vuedraggable-C3E4D3Yv.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as K,ak as d,I as b,a as o,aN as s,J as n,G as u,H as r,O as L,A as M}from"./@vue/runtime-core-C0pg79pw.js";import{y as _}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"flex-1"},Q={class:"bg-fill-light w-full p-4 mt-4"},W={class:"flex-1"},X={class:"flex-1 flex items-center"},Y={class:"drag-move cursor-move ml-auto"},Z={key:0,class:"mt-4"},f=5,me=K({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(m,{emit:y}){const p=y,c=m,g=M({get:()=>c.content,set:a=>{p("update:content",a)}}),w=()=>{var a;if(((a=c.content.data)==null?void 0:a.length)<f){const e=v(c.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),p("update:content",e)}else k.msgError(`最多添加${f}张图片`)},E=a=>{var i;if(((i=c.content.data)==null?void 0:i.length)<=1)return k.msgError("最少保留一张图片");const e=v(c.content);e.data.splice(a,1),p("update:content",e)};return(a,e)=>{const i=T,U=R,C=F,h=A,B=J,D=H,N=G,$=S,I=j,O=z;return d(),b("div",null,[o(O,{"label-width":"70px"},{default:s(()=>[o(I,{shadow:"never",class:"!border-none flex mt-2"},{default:s(()=>{var x;return[e[2]||(e[2]=n("div",{class:"flex items-end"},[n("div",{class:"text-base text-[#101010] font-medium"},"图片设置"),n("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),n("div",P,[o(_(q),{class:"draggable",modelValue:_(g).data,"onUpdate:modelValue":e[0]||(e[0]=t=>_(g).data=t),animation:"300",handle:".drag-move"},{item:s(({element:t,index:V})=>[(d(),u(N,{key:V,onClose:l=>E(V),class:"w-full"},{default:s(()=>[n("div",Q,[o(i,{width:"396px",height:"196px",modelValue:t.image,"onUpdate:modelValue":l=>t.image=l,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),n("div",W,[o(h,{class:"mt-[18px]",label:"图片链接"},{default:s(()=>[m.type=="mobile"?(d(),u(U,{key:0,modelValue:t.link,"onUpdate:modelValue":l=>t.link=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0),m.type=="pc"?(d(),u(C,{key:1,placeholder:"请输入链接",modelValue:t.link.path,"onUpdate:modelValue":l=>t.link.path=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0)]),_:2},1024),o(h,{label:"是否显示",class:"mt-[18px] !mb-0"},{default:s(()=>[n("div",X,[o(B,{modelValue:t.is_show,"onUpdate:modelValue":l=>t.is_show=l,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),n("div",Y,[o(D,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),((x=m.content.data)==null?void 0:x.length)<f?(d(),b("div",Z,[o($,{class:"w-full",type:"primary",onClick:w},{default:s(()=>[...e[1]||(e[1]=[L("添加图片",-1)])]),_:1})])):r("",!0)]}),_:1})]),_:1})])}}});export{me as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{J as b,B as y,C as E,G as w,I as B,D as C}from"./element-plus-6h1hTCrQ.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-CH3jNlCp.js";import{f as N,ak as k,I as O,a as t,aN as o,J as a,O as u,A as U}from"./@vue/runtime-core-C0pg79pw.js";import{y as s}from"./@vue/reactivity-BIbyPIZJ.js";const g={class:"flex-1"},J=N({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(p,{emit:i}){const f=i,_=p,l=U({get:()=>_.content,set:m=>{f("update:content",m)}});return(m,e)=>{const x=E,c=y,d=b,r=B,v=w,V=C;return k(),O("div",null,[t(V,{"label-width":"70px"},{default:o(()=>[t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[t(c,{label:"标题"},{default:o(()=>[t(x,{class:"w-[396px]",modelValue:s(l).title,"onUpdate:modelValue":e[0]||(e[0]=n=>s(l).title=n)},null,8,["modelValue"])]),_:1})]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[5]||(e[5]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),t(v,{modelValue:s(l).style,"onUpdate:modelValue":e[1]||(e[1]=n=>s(l).style=n)},{default:o(()=>[t(r,{value:1},{default:o(()=>[...e[3]||(e[3]=[u("横排",-1)])]),_:1}),t(r,{value:2},{default:o(()=>[...e[4]||(e[4]=[u("竖排",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"菜单"),a("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),a("div",g,[t(I,{modelValue:s(l).data,"onUpdate:modelValue":e[2]||(e[2]=n=>s(l).data=n)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{J as _};
|
||||
import{J as b,B as y,C as E,G as w,I as B,D as C}from"./element-plus-osWj3D3p.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-0VBUUpOA.js";import{f as N,ak as k,I as O,a as t,aN as o,J as a,O as u,A as U}from"./@vue/runtime-core-C0pg79pw.js";import{y as s}from"./@vue/reactivity-BIbyPIZJ.js";const g={class:"flex-1"},J=N({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(p,{emit:i}){const f=i,_=p,l=U({get:()=>_.content,set:m=>{f("update:content",m)}});return(m,e)=>{const x=E,c=y,d=b,r=B,v=w,V=C;return k(),O("div",null,[t(V,{"label-width":"70px"},{default:o(()=>[t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[t(c,{label:"标题"},{default:o(()=>[t(x,{class:"w-[396px]",modelValue:s(l).title,"onUpdate:modelValue":e[0]||(e[0]=n=>s(l).title=n)},null,8,["modelValue"])]),_:1})]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[5]||(e[5]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),t(v,{modelValue:s(l).style,"onUpdate:modelValue":e[1]||(e[1]=n=>s(l).style=n)},{default:o(()=>[t(r,{value:1},{default:o(()=>[...e[3]||(e[3]=[u("横排",-1)])]),_:1}),t(r,{value:2},{default:o(()=>[...e[4]||(e[4]=[u("竖排",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"菜单"),a("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),a("div",g,[t(I,{modelValue:s(l).data,"onUpdate:modelValue":e[2]||(e[2]=n=>s(l).data=n)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{J as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{J as B,G as F,I as N,B as O,P as U,Q as g,D as C}from"./element-plus-6h1hTCrQ.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-CH3jNlCp.js";import{f as j,ak as d,I as m,a as l,aN as o,J as s,O as x,F as c,ap as v,A as D}from"./@vue/runtime-core-C0pg79pw.js";import{y as n}from"./@vue/reactivity-BIbyPIZJ.js";const G={class:"flex-1 mt-4"},P=j({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(V,{emit:b}){const y=b,w=V,a=D({get:()=>w.content,set:u=>{y("update:content",u)}});return(u,e)=>{const r=N,E=F,p=g,i=U,_=O,f=B,k=C;return d(),m("div",null,[l(k,{"label-width":"70px"},{default:o(()=>[l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),l(E,{modelValue:n(a).style,"onUpdate:modelValue":e[0]||(e[0]=t=>n(a).style=t)},{default:o(()=>[l(r,{value:1},{default:o(()=>[...e[4]||(e[4]=[x("固定显示",-1)])]),_:1}),l(r,{value:2},{default:o(()=>[...e[5]||(e[5]=[x("分页滑动",-1)])]),_:1})]),_:1},8,["modelValue"]),l(_,{label:"每行数量",class:"mt-4"},{default:o(()=>[l(i,{modelValue:n(a).per_line,"onUpdate:modelValue":e[1]||(e[1]=t=>n(a).per_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(5,t=>l(p,{key:t,label:t+"个",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1}),l(_,{label:"显示行数"},{default:o(()=>[l(i,{modelValue:n(a).show_line,"onUpdate:modelValue":e[2]||(e[2]=t=>n(a).show_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(2,t=>l(p,{key:t,label:t+"行",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1})]),_:1}),l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[7]||(e[7]=s("div",{class:"flex items-end"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单设置"),s("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),s("div",G,[l(I,{modelValue:n(a).data,"onUpdate:modelValue":e[3]||(e[3]=t=>n(a).data=t)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{P as _};
|
||||
import{J as B,G as F,I as N,B as O,P as U,Q as g,D as C}from"./element-plus-osWj3D3p.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-0VBUUpOA.js";import{f as j,ak as d,I as m,a as l,aN as o,J as s,O as x,F as c,ap as v,A as D}from"./@vue/runtime-core-C0pg79pw.js";import{y as n}from"./@vue/reactivity-BIbyPIZJ.js";const G={class:"flex-1 mt-4"},P=j({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(V,{emit:b}){const y=b,w=V,a=D({get:()=>w.content,set:u=>{y("update:content",u)}});return(u,e)=>{const r=N,E=F,p=g,i=U,_=O,f=B,k=C;return d(),m("div",null,[l(k,{"label-width":"70px"},{default:o(()=>[l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),l(E,{modelValue:n(a).style,"onUpdate:modelValue":e[0]||(e[0]=t=>n(a).style=t)},{default:o(()=>[l(r,{value:1},{default:o(()=>[...e[4]||(e[4]=[x("固定显示",-1)])]),_:1}),l(r,{value:2},{default:o(()=>[...e[5]||(e[5]=[x("分页滑动",-1)])]),_:1})]),_:1},8,["modelValue"]),l(_,{label:"每行数量",class:"mt-4"},{default:o(()=>[l(i,{modelValue:n(a).per_line,"onUpdate:modelValue":e[1]||(e[1]=t=>n(a).per_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(5,t=>l(p,{key:t,label:t+"个",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1}),l(_,{label:"显示行数"},{default:o(()=>[l(i,{modelValue:n(a).show_line,"onUpdate:modelValue":e[2]||(e[2]=t=>n(a).show_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(2,t=>l(p,{key:t,label:t+"行",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1})]),_:1}),l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[7]||(e[7]=s("div",{class:"flex items-end"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单设置"),s("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),s("div",G,[l(I,{modelValue:n(a).data,"onUpdate:modelValue":e[3]||(e[3]=t=>n(a).data=t)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{P as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{J as V,B as w,C as x,D as b}from"./element-plus-6h1hTCrQ.js";import{_ as g}from"./picker-RR6i8slw.js";import{f as k,ak as E,I as U,a as e,aN as n,J as y,A as B}from"./@vue/runtime-core-C0pg79pw.js";import{y as o}from"./@vue/reactivity-BIbyPIZJ.js";const j=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:r}){const p=r,i=u,l=B({get:()=>i.content,set:d=>{p("update:content",d)}});return(d,t)=>{const s=x,m=w,_=g,c=V,f=b;return E(),U("div",null,[e(f,{"label-width":"90px",size:"large","label-position":"top"},{default:n(()=>[e(c,{shadow:"never",class:"!border-none flex mt-2"},{default:n(()=>[e(m,{label:"平台名称"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).title,"onUpdate:modelValue":t[0]||(t[0]=a=>o(l).title=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"客服二维码"},{default:n(()=>[y("div",null,[e(_,{modelValue:o(l).qrcode,"onUpdate:modelValue":t[1]||(t[1]=a=>o(l).qrcode=a),"exclude-domain":""},null,8,["modelValue"])])]),_:1}),e(m,{label:"备注"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).remark,"onUpdate:modelValue":t[2]||(t[2]=a=>o(l).remark=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"联系电话"},{default:n(()=>[e(s,{class:"w-[400px]",modelValue:o(l).mobile,"onUpdate:modelValue":t[3]||(t[3]=a=>o(l).mobile=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"服务时间"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).time,"onUpdate:modelValue":t[4]||(t[4]=a=>o(l).time=a)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})])}}});export{j as _};
|
||||
import{J as V,B as w,C as x,D as b}from"./element-plus-osWj3D3p.js";import{_ as g}from"./picker-Der0ecbS.js";import{f as k,ak as E,I as U,a as e,aN as n,J as y,A as B}from"./@vue/runtime-core-C0pg79pw.js";import{y as o}from"./@vue/reactivity-BIbyPIZJ.js";const j=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:r}){const p=r,i=u,l=B({get:()=>i.content,set:d=>{p("update:content",d)}});return(d,t)=>{const s=x,m=w,_=g,c=V,f=b;return E(),U("div",null,[e(f,{"label-width":"90px",size:"large","label-position":"top"},{default:n(()=>[e(c,{shadow:"never",class:"!border-none flex mt-2"},{default:n(()=>[e(m,{label:"平台名称"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).title,"onUpdate:modelValue":t[0]||(t[0]=a=>o(l).title=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"客服二维码"},{default:n(()=>[y("div",null,[e(_,{modelValue:o(l).qrcode,"onUpdate:modelValue":t[1]||(t[1]=a=>o(l).qrcode=a),"exclude-domain":""},null,8,["modelValue"])])]),_:1}),e(m,{label:"备注"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).remark,"onUpdate:modelValue":t[2]||(t[2]=a=>o(l).remark=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"联系电话"},{default:n(()=>[e(s,{class:"w-[400px]",modelValue:o(l).mobile,"onUpdate:modelValue":t[3]||(t[3]=a=>o(l).mobile=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"服务时间"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).time,"onUpdate:modelValue":t[4]||(t[4]=a=>o(l).time=a)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})])}}});export{j as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-BflKoHU-.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./menu-DDPrAoWK.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./role-DKAG1xTY.js";import"./index-DsSo_l55.js";export{o as default};
|
||||
import{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-DzYDHGm2.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./menu-lw9nZKd4.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./role-Dws5Gwe2.js";import"./index-9YImSnPn.js";export{o as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{D as I,s as q,B as G,H as J,a2 as M,L as O}from"./element-plus-6h1hTCrQ.js";import{m as U}from"./menu-DDPrAoWK.js";import{a as j}from"./role-DKAG1xTY.js";import{P as z}from"./index-DsSo_l55.js";import{w as Q}from"./index-55neFmjq.js";import{f as W,ak as k,I as X,a as l,aN as u,aP as Y,G as Z,J as y,n as x}from"./@vue/runtime-core-C0pg79pw.js";import{y as c,a as $,u as f,o as r,r as ee}from"./@vue/reactivity-BIbyPIZJ.js";const te={class:"edit-popup"},ue=W({__name:"auth",emits:["success","close"],setup(ae,{expose:C,emit:b}){const _=b,o=f(),h=f(),d=f(),g=r(!1),i=r(!0),m=r(!1),v=r([]),p=r([]),s=ee({id:"",name:"",desc:"",sort:0,menu_id:[]}),E={name:[{required:!0,message:"请输入名称",trigger:["blur"]}]},w=()=>{m.value=!0,U().then(e=>{p.value=e,v.value=Q(e),x(()=>{A()}),m.value=!1})},R=()=>{var a,n;const e=(a=o.value)==null?void 0:a.getCheckedKeys(),t=(n=o.value)==null?void 0:n.getHalfCheckedKeys();return e==null||e.unshift.apply(e,t),e},A=()=>{s.menu_id.forEach(e=>{x(()=>{var t;(t=o.value)==null||t.setChecked(e,!0,!1)})})},D=e=>{const t=p.value;for(let a=0;a<t.length;a++)o.value.store.nodesMap[t[a].id].expanded=e},K=e=>{var t,a;e?(t=o.value)==null||t.setCheckedKeys(v.value.map(n=>n.id)):(a=o.value)==null||a.setCheckedKeys([])},B=async()=>{var e,t;await((e=h.value)==null?void 0:e.validate()),s.menu_id=R(),await j(s),(t=d.value)==null||t.close(),_("success")},V=()=>{_("close")},S=()=>{var e;(e=d.value)==null||e.open()},T=async e=>{for(const t in s)e[t]!=null&&e[t]!=null&&(s[t]=e[t])};return w(),C({open:S,setFormData:T}),(e,t)=>{const a=J,n=M,F=G,L=q,N=I,P=O;return k(),X("div",te,[l(z,{ref_key:"popupRef",ref:d,title:"分配权限",async:!0,width:"550px",onConfirm:B,onClose:V},{default:u(()=>[Y((k(),Z(N,{class:"ls-form",ref_key:"formRef",ref:h,rules:E,model:c(s),"label-width":"60px"},{default:u(()=>[l(L,{class:"h-[400px] sm:h-[600px]"},{default:u(()=>[l(F,{label:"权限",prop:"menu_id"},{default:u(()=>[y("div",null,[l(a,{label:"展开/折叠",onChange:D}),l(a,{label:"全选/不全选",onChange:K}),l(a,{modelValue:c(i),"onUpdate:modelValue":t[0]||(t[0]=H=>$(i)?i.value=H:null),label:"父子联动"},null,8,["modelValue"]),y("div",null,[l(n,{ref_key:"treeRef",ref:o,data:c(p),props:{label:"name",children:"children"},"check-strictly":!c(i),"node-key":"id","default-expand-all":c(g),"show-checkbox":""},null,8,["data","check-strictly","default-expand-all"])])])]),_:1})]),_:1})]),_:1},8,["model"])),[[P,c(m)]])]),_:1},512)])}}});export{ue as _};
|
||||
@@ -0,0 +1 @@
|
||||
import{D as I,s as q,B as G,H as J,Z as M,L as O}from"./element-plus-osWj3D3p.js";import{m as U}from"./menu-lw9nZKd4.js";import{a as Z}from"./role-Dws5Gwe2.js";import{P as j}from"./index-9YImSnPn.js";import{x as z}from"./index-xZXgRhuH.js";import{f as Q,ak as k,I as W,a as l,aN as u,aP as X,G as Y,J as y,n as x}from"./@vue/runtime-core-C0pg79pw.js";import{y as c,a as $,u as f,o as r,r as ee}from"./@vue/reactivity-BIbyPIZJ.js";const te={class:"edit-popup"},ue=Q({__name:"auth",emits:["success","close"],setup(oe,{expose:C,emit:b}){const _=b,a=f(),h=f(),d=f(),g=r(!1),i=r(!0),m=r(!1),v=r([]),p=r([]),s=ee({id:"",name:"",desc:"",sort:0,menu_id:[]}),E={name:[{required:!0,message:"请输入名称",trigger:["blur"]}]},w=()=>{m.value=!0,U().then(e=>{p.value=e,v.value=z(e),x(()=>{A()}),m.value=!1})},R=()=>{var o,n;const e=(o=a.value)==null?void 0:o.getCheckedKeys(),t=(n=a.value)==null?void 0:n.getHalfCheckedKeys();return e==null||e.unshift.apply(e,t),e},A=()=>{s.menu_id.forEach(e=>{x(()=>{var t;(t=a.value)==null||t.setChecked(e,!0,!1)})})},D=e=>{const t=p.value;for(let o=0;o<t.length;o++)a.value.store.nodesMap[t[o].id].expanded=e},K=e=>{var t,o;e?(t=a.value)==null||t.setCheckedKeys(v.value.map(n=>n.id)):(o=a.value)==null||o.setCheckedKeys([])},B=async()=>{var e,t;await((e=h.value)==null?void 0:e.validate()),s.menu_id=R(),await Z(s),(t=d.value)==null||t.close(),_("success")},V=()=>{_("close")},S=()=>{var e;(e=d.value)==null||e.open()},T=async e=>{for(const t in s)e[t]!=null&&e[t]!=null&&(s[t]=e[t])};return w(),C({open:S,setFormData:T}),(e,t)=>{const o=J,n=M,F=G,L=q,N=I,P=O;return k(),W("div",te,[l(j,{ref_key:"popupRef",ref:d,title:"分配权限",async:!0,width:"550px",onConfirm:B,onClose:V},{default:u(()=>[X((k(),Y(N,{class:"ls-form",ref_key:"formRef",ref:h,rules:E,model:c(s),"label-width":"60px"},{default:u(()=>[l(L,{class:"h-[400px] sm:h-[600px]"},{default:u(()=>[l(F,{label:"权限",prop:"menu_id"},{default:u(()=>[y("div",null,[l(o,{label:"展开/折叠",onChange:D}),l(o,{label:"全选/不全选",onChange:K}),l(o,{modelValue:c(i),"onUpdate:modelValue":t[0]||(t[0]=H=>$(i)?i.value=H:null),label:"父子联动"},null,8,["modelValue"]),y("div",null,[l(n,{ref_key:"treeRef",ref:a,data:c(p),props:{label:"name",children:"children"},"check-strictly":!c(i),"node-key":"id","default-expand-all":c(g),"show-checkbox":""},null,8,["data","check-strictly","default-expand-all"])])])]),_:1})]),_:1})]),_:1},8,["model"])),[[P,c(m)]])]),_:1},512)])}}});export{ue as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{K as L,D as N,B as K,C as I,P as O,Q as z,i as J,J as Q,M as R,N as S,L as $}from"./element-plus-6h1hTCrQ.js";import{_ as j}from"./index.vue_vue_type_script_setup_true_lang-CLVBLrJv.js";import{h as q}from"./index-55neFmjq.js";import{_ as A}from"./index.vue_vue_type_script_setup_true_lang-CLhPF1Ro.js";import{w as G}from"./@vue/runtime-dom-iFk_KP8y.js";import{a as M,g as H}from"./finance-C9v2y7Wt.js";import{u as W}from"./useDictOptions-CA4QiMnI.js";import{u as X}from"./usePaging-B_C_SZ2Z.js";import{f as v,ak as s,I as h,a as e,aN as n,F as Y,ap as Z,G as w,O as p,aP as ee,J as _}from"./@vue/runtime-core-C0pg79pw.js";import{y as o,a as te,r as oe}from"./@vue/reactivity-BIbyPIZJ.js";import{Q as y,o as ae}from"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./lodash-D3kF6u-c.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const ne={class:"flex items-center"},le={class:"flex justify-end mt-4"},ie=v({name:"balanceDetail"}),Xe=v({...ie,setup(re){const l=oe({user_info:"",change_type:"",start_time:"",end_time:""}),{pager:r,getLists:d,resetPage:c,resetParams:C}=X({fetchFun:M,params:l}),{optionsData:x}=W({change_type:{api:H}});return d(),(me,a)=>{const V=L,E=I,m=K,u=z,T=O,k=A,f=J,B=N,g=Q,i=S,D=q,P=R,U=j,F=$;return s(),h("div",null,[e(g,{class:"!border-none",shadow:"never"},{default:n(()=>[e(V,{type:"warning",title:"温馨提示:用户账户变动记录",closable:!1,"show-icon":""}),e(B,{ref:"formRef",class:"mb-[-16px] mt-[16px]",model:o(l),inline:!0},{default:n(()=>[e(m,{class:"w-[280px]",label:"用户信息"},{default:n(()=>[e(E,{modelValue:o(l).user_info,"onUpdate:modelValue":a[0]||(a[0]=t=>o(l).user_info=t),placeholder:"请输入用户账号/昵称/手机号",clearable:"",onKeyup:G(o(c),["enter"])},null,8,["modelValue","onKeyup"])]),_:1}),e(m,{class:"w-[280px]",label:"变动类型"},{default:n(()=>[e(T,{modelValue:o(l).change_type,"onUpdate:modelValue":a[1]||(a[1]=t=>o(l).change_type=t)},{default:n(()=>[e(u,{label:"全部",value:""}),(s(!0),h(Y,null,Z(o(x).change_type,(t,b)=>(s(),w(u,{key:b,label:t,value:b},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),e(m,{label:"记录时间"},{default:n(()=>[e(k,{startTime:o(l).start_time,"onUpdate:startTime":a[2]||(a[2]=t=>o(l).start_time=t),endTime:o(l).end_time,"onUpdate:endTime":a[3]||(a[3]=t=>o(l).end_time=t)},null,8,["startTime","endTime"])]),_:1}),e(m,null,{default:n(()=>[e(f,{type:"primary",onClick:o(c)},{default:n(()=>[...a[5]||(a[5]=[p("查询",-1)])]),_:1},8,["onClick"]),e(f,{onClick:o(C)},{default:n(()=>[...a[6]||(a[6]=[p("重置",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["model"])]),_:1}),e(g,{class:"!border-none mt-4",shadow:"never"},{default:n(()=>[ee((s(),w(P,{size:"large",data:o(r).lists},{default:n(()=>[e(i,{label:"用户账号",prop:"account","min-width":"100"}),e(i,{label:"用户昵称","min-width":"160"},{default:n(({row:t})=>[_("div",ne,[e(D,{class:"flex-none mr-2",src:t.avatar,width:40,height:40,"preview-teleported":"",fit:"contain"},null,8,["src"]),p(" "+y(t.nickname),1)])]),_:1}),e(i,{label:"手机号码",prop:"mobile","min-width":"100"}),e(i,{label:"变动金额",prop:"change_amount","min-width":"100"},{default:n(({row:t})=>[_("span",{class:ae({"text-error":t.action==2})},y(t.change_amount),3)]),_:1}),e(i,{label:"剩余金额",prop:"left_amount","min-width":"100"}),e(i,{label:"变动类型",prop:"change_type_desc","min-width":"120"}),e(i,{label:"来源单号",prop:"source_sn","min-width":"100"}),e(i,{label:"记录时间",prop:"create_time","min-width":"120"})]),_:1},8,["data"])),[[F,o(r).loading]]),_("div",le,[e(U,{modelValue:o(r),"onUpdate:modelValue":a[4]||(a[4]=t=>te(r)?r.value=t:null),onChange:o(d)},null,8,["modelValue","onChange"])])]),_:1})])}}});export{Xe as default};
|
||||
import{K as L,D as N,B as K,C as I,P as O,Q as z,i as J,J as Q,M as R,N as S,L as $}from"./element-plus-osWj3D3p.js";import{_ as j}from"./index.vue_vue_type_script_setup_true_lang-CGaXpMKH.js";import{h as q}from"./index-xZXgRhuH.js";import{_ as A}from"./index.vue_vue_type_script_setup_true_lang-BCTRSL78.js";import{w as G}from"./@vue/runtime-dom-iFk_KP8y.js";import{a as M,g as H}from"./finance-_Zy0NXqv.js";import{u as W}from"./useDictOptions-BNfwjYNp.js";import{u as X}from"./usePaging-B_C_SZ2Z.js";import{f as v,ak as s,I as h,a as e,aN as n,F as Y,ap as Z,G as w,O as p,aP as ee,J as _}from"./@vue/runtime-core-C0pg79pw.js";import{y as o,a as te,r as oe}from"./@vue/reactivity-BIbyPIZJ.js";import{Q as y,o as ae}from"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./lodash-D3kF6u-c.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const ne={class:"flex items-center"},le={class:"flex justify-end mt-4"},ie=v({name:"balanceDetail"}),Xe=v({...ie,setup(re){const l=oe({user_info:"",change_type:"",start_time:"",end_time:""}),{pager:r,getLists:d,resetPage:c,resetParams:C}=X({fetchFun:M,params:l}),{optionsData:x}=W({change_type:{api:H}});return d(),(me,a)=>{const V=L,E=I,m=K,u=z,T=O,k=A,f=J,B=N,g=Q,i=S,D=q,P=R,U=j,F=$;return s(),h("div",null,[e(g,{class:"!border-none",shadow:"never"},{default:n(()=>[e(V,{type:"warning",title:"温馨提示:用户账户变动记录",closable:!1,"show-icon":""}),e(B,{ref:"formRef",class:"mb-[-16px] mt-[16px]",model:o(l),inline:!0},{default:n(()=>[e(m,{class:"w-[280px]",label:"用户信息"},{default:n(()=>[e(E,{modelValue:o(l).user_info,"onUpdate:modelValue":a[0]||(a[0]=t=>o(l).user_info=t),placeholder:"请输入用户账号/昵称/手机号",clearable:"",onKeyup:G(o(c),["enter"])},null,8,["modelValue","onKeyup"])]),_:1}),e(m,{class:"w-[280px]",label:"变动类型"},{default:n(()=>[e(T,{modelValue:o(l).change_type,"onUpdate:modelValue":a[1]||(a[1]=t=>o(l).change_type=t)},{default:n(()=>[e(u,{label:"全部",value:""}),(s(!0),h(Y,null,Z(o(x).change_type,(t,b)=>(s(),w(u,{key:b,label:t,value:b},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),e(m,{label:"记录时间"},{default:n(()=>[e(k,{startTime:o(l).start_time,"onUpdate:startTime":a[2]||(a[2]=t=>o(l).start_time=t),endTime:o(l).end_time,"onUpdate:endTime":a[3]||(a[3]=t=>o(l).end_time=t)},null,8,["startTime","endTime"])]),_:1}),e(m,null,{default:n(()=>[e(f,{type:"primary",onClick:o(c)},{default:n(()=>[...a[5]||(a[5]=[p("查询",-1)])]),_:1},8,["onClick"]),e(f,{onClick:o(C)},{default:n(()=>[...a[6]||(a[6]=[p("重置",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["model"])]),_:1}),e(g,{class:"!border-none mt-4",shadow:"never"},{default:n(()=>[ee((s(),w(P,{size:"large",data:o(r).lists},{default:n(()=>[e(i,{label:"用户账号",prop:"account","min-width":"100"}),e(i,{label:"用户昵称","min-width":"160"},{default:n(({row:t})=>[_("div",ne,[e(D,{class:"flex-none mr-2",src:t.avatar,width:40,height:40,"preview-teleported":"",fit:"contain"},null,8,["src"]),p(" "+y(t.nickname),1)])]),_:1}),e(i,{label:"手机号码",prop:"mobile","min-width":"100"}),e(i,{label:"变动金额",prop:"change_amount","min-width":"100"},{default:n(({row:t})=>[_("span",{class:ae({"text-error":t.action==2})},y(t.change_amount),3)]),_:1}),e(i,{label:"剩余金额",prop:"left_amount","min-width":"100"}),e(i,{label:"变动类型",prop:"change_type_desc","min-width":"120"}),e(i,{label:"来源单号",prop:"source_sn","min-width":"100"}),e(i,{label:"记录时间",prop:"create_time","min-width":"120"})]),_:1},8,["data"])),[[F,o(r).loading]]),_("div",le,[e(U,{modelValue:o(r),"onUpdate:modelValue":a[4]||(a[4]=t=>te(r)?r.value=t:null),onChange:o(d)},null,8,["modelValue","onChange"])])]),_:1})])}}});export{Xe as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{K as c,J as _,M as d,N as f,i as u}from"./element-plus-6h1hTCrQ.js";import{i as h,z as b}from"./index-55neFmjq.js";import{f as i,ak as w,I as C,a as t,aN as o,O as k}from"./@vue/runtime-core-C0pg79pw.js";import{y,o as E}from"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const x={class:"cache"},N=i({name:"cache"}),st=i({...N,setup(g){const m=E([{content:"系统缓存",desc:"系统运行过程中产生的各类缓存数据"}]),n=async()=>{await h.confirm("确认清除系统缓存?"),await b(),window.location.reload()};return(v,r)=>{const p=c,a=_,e=f,l=u,s=d;return w(),C("div",x,[t(a,{class:"!border-none",shadow:"never"},{default:o(()=>[t(p,{type:"warning",title:"温馨提示:管理系统运行过程中产生的缓存",closable:!1,"show-icon":""})]),_:1}),t(a,{class:"!border-none mt-4",shadow:"never"},{default:o(()=>[t(s,{data:y(m),size:"large"},{default:o(()=>[t(e,{label:"管理内容",prop:"content","min-width":"130"}),t(e,{label:"内容说明",prop:"desc","min-width":"180"}),t(e,{label:"操作",width:"130",fixed:"right"},{default:o(()=>[t(l,{type:"primary",link:"",onClick:n},{default:o(()=>[...r[0]||(r[0]=[k("清除系统缓存",-1)])]),_:1})]),_:1})]),_:1},8,["data"])]),_:1})])}}});export{st as default};
|
||||
import{K as c,J as _,M as d,N as f,i as u}from"./element-plus-osWj3D3p.js";import{i as h,B as b}from"./index-xZXgRhuH.js";import{f as i,ak as w,I as C,a as t,aN as o,O as k}from"./@vue/runtime-core-C0pg79pw.js";import{y,o as E}from"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const x={class:"cache"},B=i({name:"cache"}),st=i({...B,setup(N){const m=E([{content:"系统缓存",desc:"系统运行过程中产生的各类缓存数据"}]),n=async()=>{await h.confirm("确认清除系统缓存?"),await b(),window.location.reload()};return(g,r)=>{const p=c,a=_,e=f,l=u,s=d;return w(),C("div",x,[t(a,{class:"!border-none",shadow:"never"},{default:o(()=>[t(p,{type:"warning",title:"温馨提示:管理系统运行过程中产生的缓存",closable:!1,"show-icon":""})]),_:1}),t(a,{class:"!border-none mt-4",shadow:"never"},{default:o(()=>[t(s,{data:y(m),size:"large"},{default:o(()=>[t(e,{label:"管理内容",prop:"content","min-width":"130"}),t(e,{label:"内容说明",prop:"desc","min-width":"180"}),t(e,{label:"操作",width:"130",fixed:"right"},{default:o(()=>[t(l,{type:"primary",link:"",onClick:n},{default:o(()=>[...r[0]||(r[0]=[k("清除系统缓存",-1)])]),_:1})]),_:1})]),_:1},8,["data"])]),_:1})])}}});export{st as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{E as p,B as b,C as v,D as E,i as h}from"./element-plus-6h1hTCrQ.js";import{u as V,g as C,P,c as B,d as F,_ as I}from"./index-55neFmjq.js";import{w as L}from"./@vue/runtime-dom-iFk_KP8y.js";import{u as N}from"./useLockFn-DaSAjE2Q.js";import{_ as z}from"./footer.vue_vue_type_script_setup_true_lang-Bb6zG7Ce.js";import{a as R}from"./vue-router-CYz6RFzi.js";import{f as S,b as U,ak as q,I as D,J as i,a as s,aN as t,O as K}from"./@vue/runtime-core-C0pg79pw.js";import{y as u,u as M,r as O}from"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const T={class:"change-password flex flex-col"},$={class:"flex-1 flex items-center justify-center"},j={class:"change-password-card bg-body rounded-md px-10 py-10 w-[480px]"},G=S({__name:"change-password",setup(J){const n=M(),_=R(),d=V();U(()=>{C()||(p.error("请先登录"),_.push(P.LOGIN))});const e=O({password:"",password_confirm:""}),w={password:[{required:!0,message:"请输入新密码",trigger:"blur"},{min:6,message:"密码长度不能少于6位",trigger:"blur"}],password_confirm:[{required:!0,validator:(a,o,r)=>{o===""?r(new Error("请再次输入密码")):o!==e.password?r(new Error("两次输入的密码不一致")):r()},trigger:"blur"}]},l=async()=>{var a;await((a=n.value)==null?void 0:a.validate());try{await F({password:e.password,password_confirm:e.password_confirm}),p.success("密码修改成功,请重新登录"),d.isPaw=1,await d.logout()}catch(o){p.error((o==null?void 0:o.msg)||(o==null?void 0:o.message)||"密码修改失败")}},{isLock:g,lockFn:x}=N(l);return(a,o)=>{const r=B,c=v,f=b,y=E,k=h;return q(),D("div",T,[i("div",$,[i("div",j,[o[3]||(o[3]=i("div",{class:"text-center text-2xl font-medium mb-2"},"首次登录",-1)),o[4]||(o[4]=i("div",{class:"text-center text-gray-500 text-sm mb-8"},"为了您的账号安全,请修改初始密码",-1)),s(y,{ref_key:"formRef",ref:n,model:e,size:"large",rules:w},{default:t(()=>[s(f,{prop:"password"},{default:t(()=>[s(c,{modelValue:e.password,"onUpdate:modelValue":o[0]||(o[0]=m=>e.password=m),type:"password","show-password":"",placeholder:"请输入新密码"},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1}),s(f,{prop:"password_confirm"},{default:t(()=>[s(c,{modelValue:e.password_confirm,"onUpdate:modelValue":o[1]||(o[1]=m=>e.password_confirm=m),type:"password","show-password":"",placeholder:"请再次输入新密码",onKeyup:L(l,["enter"])},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1})]),_:1},8,["model"]),s(k,{type:"primary",size:"large",loading:u(g),onClick:u(x),class:"w-full"},{default:t(()=>[...o[2]||(o[2]=[K(" 确认修改 ",-1)])]),_:1},8,["loading","onClick"])])]),s(z)])}}}),Ro=I(G,[["__scopeId","data-v-bbd4ab41"]]);export{Ro as default};
|
||||
import{E as p,B as b,C as v,D as E,i as h}from"./element-plus-osWj3D3p.js";import{u as V,g as C,P,c as B,d as F,_ as I}from"./index-xZXgRhuH.js";import{w as L}from"./@vue/runtime-dom-iFk_KP8y.js";import{u as N}from"./useLockFn-DaSAjE2Q.js";import{_ as z}from"./footer.vue_vue_type_script_setup_true_lang-C6pBtIyu.js";import{a as R}from"./vue-router-CYz6RFzi.js";import{f as S,b as U,ak as q,I as D,J as i,a as s,aN as t,O as K}from"./@vue/runtime-core-C0pg79pw.js";import{y as u,u as M,r as O}from"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const T={class:"change-password flex flex-col"},$={class:"flex-1 flex items-center justify-center"},j={class:"change-password-card bg-body rounded-md px-10 py-10 w-[480px]"},G=S({__name:"change-password",setup(J){const n=M(),_=R(),d=V();U(()=>{C()||(p.error("请先登录"),_.push(P.LOGIN))});const e=O({password:"",password_confirm:""}),w={password:[{required:!0,message:"请输入新密码",trigger:"blur"},{min:6,message:"密码长度不能少于6位",trigger:"blur"}],password_confirm:[{required:!0,validator:(a,o,r)=>{o===""?r(new Error("请再次输入密码")):o!==e.password?r(new Error("两次输入的密码不一致")):r()},trigger:"blur"}]},l=async()=>{var a;await((a=n.value)==null?void 0:a.validate());try{await F({password:e.password,password_confirm:e.password_confirm}),p.success("密码修改成功,请重新登录"),d.isPaw=1,await d.logout()}catch(o){p.error((o==null?void 0:o.msg)||(o==null?void 0:o.message)||"密码修改失败")}},{isLock:g,lockFn:x}=N(l);return(a,o)=>{const r=B,c=v,f=b,y=E,k=h;return q(),D("div",T,[i("div",$,[i("div",j,[o[3]||(o[3]=i("div",{class:"text-center text-2xl font-medium mb-2"},"首次登录",-1)),o[4]||(o[4]=i("div",{class:"text-center text-gray-500 text-sm mb-8"},"为了您的账号安全,请修改初始密码",-1)),s(y,{ref_key:"formRef",ref:n,model:e,size:"large",rules:w},{default:t(()=>[s(f,{prop:"password"},{default:t(()=>[s(c,{modelValue:e.password,"onUpdate:modelValue":o[0]||(o[0]=m=>e.password=m),type:"password","show-password":"",placeholder:"请输入新密码"},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1}),s(f,{prop:"password_confirm"},{default:t(()=>[s(c,{modelValue:e.password_confirm,"onUpdate:modelValue":o[1]||(o[1]=m=>e.password_confirm=m),type:"password","show-password":"",placeholder:"请再次输入新密码",onKeyup:L(l,["enter"])},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1})]),_:1},8,["model"]),s(k,{type:"primary",size:"large",loading:u(g),onClick:u(x),class:"w-full"},{default:t(()=>[...o[2]||(o[2]=[K(" 确认修改 ",-1)])]),_:1},8,["loading","onClick"])])]),s(z)])}}}),Ro=I(G,[["__scopeId","data-v-bbd4ab41"]]);export{Ro as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{r as t}from"./index-55neFmjq.js";function o(e){return t.get({url:"/tools.generator/generateTable",params:e})}function n(e){return t.get({url:"/tools.generator/dataTable",params:e})}function a(e){return t.post({url:"/tools.generator/selectTable",params:e})}function l(e){return t.get({url:"/tools.generator/detail",params:e})}function s(e){return t.post({url:"/tools.generator/syncColumn",params:e})}function u(e){return t.post({url:"/tools.generator/delete",params:e})}function g(e){return t.post({url:"/tools.generator/edit",params:e})}function i(e){return t.post({url:"/tools.generator/preview",params:e})}function c(e){return t.post({url:"/tools.generator/generate",params:e})}function f(){return t.get({url:"/tools.generator/getModels"})}export{f as a,o as b,u as c,i as d,c as e,n as f,g,a as h,s,l as t};
|
||||
import{r as t}from"./index-xZXgRhuH.js";function o(e){return t.get({url:"/tools.generator/generateTable",params:e})}function n(e){return t.get({url:"/tools.generator/dataTable",params:e})}function a(e){return t.post({url:"/tools.generator/selectTable",params:e})}function l(e){return t.get({url:"/tools.generator/detail",params:e})}function s(e){return t.post({url:"/tools.generator/syncColumn",params:e})}function u(e){return t.post({url:"/tools.generator/delete",params:e})}function g(e){return t.post({url:"/tools.generator/edit",params:e})}function i(e){return t.post({url:"/tools.generator/preview",params:e})}function c(e){return t.post({url:"/tools.generator/generate",params:e})}function f(){return t.get({url:"/tools.generator/getModels"})}export{f as a,o as b,u as c,i as d,c as e,n as f,g,a as h,s,l as t};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./code-preview.vue_vue_type_script_setup_true_lang-oLdzHDvj.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
import{_ as o}from"./code-preview.vue_vue_type_script_setup_true_lang-gujKCv5T.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{m as B,l as N,s as T,i as $,$ as j}from"./element-plus-6h1hTCrQ.js";import{c as D,i as d}from"./index-55neFmjq.js";import{u as F}from"./vue-clipboard3-DByT_rEQ.js";import{f as S,ar as U,ak as c,I as i,a as t,aN as a,F as A,ap as G,G as I,J as u,O as J,A as L}from"./@vue/runtime-core-C0pg79pw.js";import{a as p,y as _,o as O}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"code-preview"},R={class:"flex",style:{height:"50vh"}},W=S({__name:"code-preview",props:{modelValue:{type:Boolean},code:{}},emits:["update:modelValue"],setup(r,{emit:f}){const b=r,V=f,{toClipboard:g}=F(),n=O("index0"),h=async l=>{try{await g(l),d.msgSuccess("复制成功")}catch{d.msgError("复制失败")}},s=L({get(){return b.modelValue},set(l){V("update:modelValue",l)}});return(l,e)=>{const v=U("highlightjs"),y=T,k=D,C=$,x=N,E=B,w=j;return c(),i("div",P,[t(w,{modelValue:_(s),"onUpdate:modelValue":e[1]||(e[1]=o=>p(s)?s.value=o:null),width:"900px",title:"代码预览"},{default:a(()=>[t(E,{modelValue:_(n),"onUpdate:modelValue":e[0]||(e[0]=o=>p(n)?n.value=o:null)},{default:a(()=>[(c(!0),i(A,null,G(r.code,(o,m)=>(c(),I(x,{label:o.name,name:`index${m}`,key:m},{default:a(()=>[u("div",R,[t(y,{class:"flex-1"},{default:a(()=>[t(v,{autodetect:"",code:o.content},null,8,["code"])]),_:2},1024),u("div",null,[t(C,{onClick:q=>h(o.content),type:"primary",link:""},{icon:a(()=>[t(k,{name:"el-icon-CopyDocument"})]),default:a(()=>[e[2]||(e[2]=J(" 复制 ",-1))]),_:1},8,["onClick"])])])]),_:2},1032,["label","name"]))),128))]),_:1},8,["modelValue"])]),_:1},8,["modelValue"])])}}});export{W as _};
|
||||
import{m as B,l as N,s as T,i as $,V as j}from"./element-plus-osWj3D3p.js";import{c as D,i as d}from"./index-xZXgRhuH.js";import{u as F}from"./vue-clipboard3-DByT_rEQ.js";import{f as S,ar as U,ak as c,I as i,a as t,aN as a,F as A,ap as G,G as I,J as u,O as J,A as L}from"./@vue/runtime-core-C0pg79pw.js";import{a as p,y as _,o as O}from"./@vue/reactivity-BIbyPIZJ.js";const P={class:"code-preview"},R={class:"flex",style:{height:"50vh"}},W=S({__name:"code-preview",props:{modelValue:{type:Boolean},code:{}},emits:["update:modelValue"],setup(r,{emit:f}){const V=r,b=f,{toClipboard:g}=F(),n=O("index0"),h=async l=>{try{await g(l),d.msgSuccess("复制成功")}catch{d.msgError("复制失败")}},s=L({get(){return V.modelValue},set(l){b("update:modelValue",l)}});return(l,e)=>{const v=U("highlightjs"),y=T,k=D,C=$,x=N,E=B,w=j;return c(),i("div",P,[t(w,{modelValue:_(s),"onUpdate:modelValue":e[1]||(e[1]=o=>p(s)?s.value=o:null),width:"900px",title:"代码预览"},{default:a(()=>[t(E,{modelValue:_(n),"onUpdate:modelValue":e[0]||(e[0]=o=>p(n)?n.value=o:null)},{default:a(()=>[(c(!0),i(A,null,G(r.code,(o,m)=>(c(),I(x,{label:o.name,name:`index${m}`,key:m},{default:a(()=>[u("div",R,[t(y,{class:"flex-1"},{default:a(()=>[t(v,{autodetect:"",code:o.content},null,8,["code"])]),_:2},1024),u("div",null,[t(C,{onClick:q=>h(o.content),type:"primary",link:""},{icon:a(()=>[t(k,{name:"el-icon-CopyDocument"})]),default:a(()=>[e[2]||(e[2]=J(" 复制 ",-1))]),_:1},8,["onClick"])])])]),_:2},1032,["label","name"]))),128))]),_:1},8,["modelValue"])]),_:1},8,["modelValue"])])}}});export{W as _};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{r}from"./index-55neFmjq.js";function u(e){return r.get({url:"/user.user/lists",params:e},{ignoreCancelToken:!0})}function s(e){return r.get({url:"/user.user/detail",params:e})}function n(e){return r.post({url:"/user.user/edit",params:e})}function o(e){return r.post({url:"/user.user/adjustMoney",params:e})}export{o as a,u as b,s as g,n as u};
|
||||
import{r}from"./index-xZXgRhuH.js";function u(e){return r.get({url:"/user.user/lists",params:e},{ignoreCancelToken:!0})}function s(e){return r.get({url:"/user.user/detail",params:e})}function n(e){return r.post({url:"/user.user/edit",params:e})}function o(e){return r.post({url:"/user.user/adjustMoney",params:e})}export{o as a,u as b,s as g,n as u};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-BIu3Xfg2.js";import"./decoration-img-DGr8eZBc.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-Bqha-Grv.js";import"./decoration-img-CKm1nxte.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as y,_ as v}from"./index-55neFmjq.js";import d from"./decoration-img-DGr8eZBc.js";import{f as b,ak as t,I as e,J as i,H as m,F as x,ap as f,a as n,A as g}from"./@vue/runtime-core-C0pg79pw.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{y as u}from"./@vue/reactivity-BIbyPIZJ.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./lodash-D3kF6u-c.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const k={class:"my-service"},w={key:0,class:"title px-[15px] py-[10px]"},B={key:1,class:"flex flex-wrap pt-[20px] pb-[10px]"},I={class:"mt-[7px]"},N={key:2},V={class:"ml-[10px] flex-1"},j=b({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(o){const _=o,a=g(()=>{var s;return((s=_.content.data)==null?void 0:s.filter(l=>l.is_show=="1"))||[]});return(s,l)=>{const h=y;return t(),e("div",k,[o.content.title?(t(),e("div",w,[i("div",null,c(o.content.title),1)])):m("",!0),o.content.style==1?(t(),e("div",B,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex flex-col items-center w-1/4 mb-[15px]"},[n(d,{width:"26px",height:"26px",src:r.image,alt:""},null,8,["src"]),i("div",I,c(r.name),1)]))),128))])):m("",!0),o.content.style==2?(t(),e("div",N,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex items-center border-b border-[#e5e5e5] h-[50px] px-[12px]"},[n(d,{width:"24px",height:"24px",src:r.image,alt:""},null,8,["src"]),i("div",V,c(r.name),1),i("div",null,[n(h,{name:"el-icon-ArrowRight"})])]))),128))])):m("",!0)])}}}),xt=v(j,[["__scopeId","data-v-2f09c27b"]]);export{xt as default};
|
||||
import{c as y,_ as v}from"./index-xZXgRhuH.js";import d from"./decoration-img-CKm1nxte.js";import{f as b,ak as t,I as e,J as i,H as m,F as x,ap as f,a as n,A as g}from"./@vue/runtime-core-C0pg79pw.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{y as u}from"./@vue/reactivity-BIbyPIZJ.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./lodash-D3kF6u-c.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const k={class:"my-service"},w={key:0,class:"title px-[15px] py-[10px]"},B={key:1,class:"flex flex-wrap pt-[20px] pb-[10px]"},I={class:"mt-[7px]"},N={key:2},V={class:"ml-[10px] flex-1"},j=b({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(o){const _=o,a=g(()=>{var s;return((s=_.content.data)==null?void 0:s.filter(l=>l.is_show=="1"))||[]});return(s,l)=>{const h=y;return t(),e("div",k,[o.content.title?(t(),e("div",w,[i("div",null,c(o.content.title),1)])):m("",!0),o.content.style==1?(t(),e("div",B,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex flex-col items-center w-1/4 mb-[15px]"},[n(d,{width:"26px",height:"26px",src:r.image,alt:""},null,8,["src"]),i("div",I,c(r.name),1)]))),128))])):m("",!0),o.content.style==2?(t(),e("div",N,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex items-center border-b border-[#e5e5e5] h-[50px] px-[12px]"},[n(d,{width:"24px",height:"24px",src:r.image,alt:""},null,8,["src"]),i("div",V,c(r.name),1),i("div",null,[n(h,{name:"el-icon-ArrowRight"})])]))),128))])):m("",!0)])}}}),xt=v(j,[["__scopeId","data-v-2f09c27b"]]);export{xt as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-DNDbw7P9.js";import"./decoration-img-DGr8eZBc.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-BRZYAhOX.js";import"./decoration-img-CKm1nxte.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as i,c as m}from"./index-55neFmjq.js";import{ak as p,I as e,J as t,a as s}from"./@vue/runtime-core-C0pg79pw.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const c={},a={class:"search"},n={class:"search-con flex items-center px-[15px]"};function _(d,o){const r=m;return p(),e("div",a,[t("div",n,[s(r,{name:"el-icon-Search",size:17}),o[0]||(o[0]=t("span",{class:"ml-[5px]"},"请输入关键词搜索",-1))])])}const W=i(c,[["render",_],["__scopeId","data-v-3514bdd8"]]);export{W as default};
|
||||
import{_ as i,c as m}from"./index-xZXgRhuH.js";import{ak as p,I as e,J as t,a as s}from"./@vue/runtime-core-C0pg79pw.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const c={},a={class:"search"},n={class:"search-con flex items-center px-[15px]"};function _(d,o){const r=m;return p(),e("div",a,[t("div",n,[s(r,{name:"el-icon-Search",size:17}),o[0]||(o[0]=t("span",{class:"ml-[5px]"},"请输入关键词搜索",-1))])])}const W=i(c,[["render",_],["__scopeId","data-v-3514bdd8"]]);export{W as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import s from"./decoration-img-DGr8eZBc.js";import{f as p,ak as r,I as m,J as e,a as c,H as n,O as a,F as l}from"./@vue/runtime-core-C0pg79pw.js";import{Q as i}from"./@vue/shared-mAAVTE9n.js";import{_ as x}from"./index-55neFmjq.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const d={class:"customer-service bg-white flex flex-col justify-center items-center mx-[18px] mt-[15px] rounded-[10px] px-[10px] pb-[50px]"},f={class:"w-full border-solid border-0 border-b border-[#f5f5f5] p-[15px] text-center text-[#101010] text-base font-medium"},u={class:"mt-[30px]"},b={key:0,class:"text-sm mt-[20px] font-medium"},h={key:1,class:"text-sm mt-[12px] flex flex-wrap"},w=["href"],v={key:2,class:"text-muted text-sm mt-[15px]"},y=p({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(t){return(k,o)=>(r(),m(l,null,[o[0]||(o[0]=e("view",{class:"bg-white p-[15px] flex text-[#101010] font-medium text-lg"}," 联系我们 ",-1)),e("view",d,[e("view",f,i(t.content.title),1),e("view",u,[c(s,{width:"100px",height:"100px",src:t.content.qrcode,alt:""},null,8,["src"])]),t.content.remark?(r(),m("view",b,i(t.content.remark),1)):n("",!0),t.content.mobile?(r(),m("view",h,[e("a",{class:"ml-[5px] phone text-primary underline",href:"tel:"+t.content.mobile},i(t.content.mobile),9,w)])):n("",!0),t.content.time?(r(),m("view",v," 服务时间:"+i(t.content.time),1)):n("",!0)]),o[1]||(o[1]=a(" Î ",-1))],64))}}),nt=x(y,[["__scopeId","data-v-ed28524a"]]);export{nt as default};
|
||||
import s from"./decoration-img-CKm1nxte.js";import{f as p,ak as r,I as m,J as e,a as c,H as n,O as a,F as l}from"./@vue/runtime-core-C0pg79pw.js";import{Q as i}from"./@vue/shared-mAAVTE9n.js";import{_ as x}from"./index-xZXgRhuH.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const d={class:"customer-service bg-white flex flex-col justify-center items-center mx-[18px] mt-[15px] rounded-[10px] px-[10px] pb-[50px]"},f={class:"w-full border-solid border-0 border-b border-[#f5f5f5] p-[15px] text-center text-[#101010] text-base font-medium"},u={class:"mt-[30px]"},b={key:0,class:"text-sm mt-[20px] font-medium"},h={key:1,class:"text-sm mt-[12px] flex flex-wrap"},w=["href"],v={key:2,class:"text-muted text-sm mt-[15px]"},y=p({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(t){return(k,o)=>(r(),m(l,null,[o[0]||(o[0]=e("view",{class:"bg-white p-[15px] flex text-[#101010] font-medium text-lg"}," 联系我们 ",-1)),e("view",d,[e("view",f,i(t.content.title),1),e("view",u,[c(s,{width:"100px",height:"100px",src:t.content.qrcode,alt:""},null,8,["src"])]),t.content.remark?(r(),m("view",b,i(t.content.remark),1)):n("",!0),t.content.mobile?(r(),m("view",h,[e("a",{class:"ml-[5px] phone text-primary underline",href:"tel:"+t.content.mobile},i(t.content.mobile),9,w)])):n("",!0),t.content.time?(r(),m("view",v," 服务时间:"+i(t.content.time),1)):n("",!0)]),o[1]||(o[1]=a(" Î ",-1))],64))}}),nt=x(y,[["__scopeId","data-v-ed28524a"]]);export{nt as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-Br4ZeErc.js";import"./decoration-img-DGr8eZBc.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-CXXpePlK.js";import"./decoration-img-CKm1nxte.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c,_ as n}from"./index-55neFmjq.js";import{g as l}from"./decoration-CXCDHeoq.js";import{f as d,ak as o,I as s,J as t,F as _,ap as x,H as f,a as u}from"./@vue/runtime-core-C0pg79pw.js";import{Q as i}from"./@vue/shared-mAAVTE9n.js";import{y as v,o as y}from"./@vue/reactivity-BIbyPIZJ.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./lodash-D3kF6u-c.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const w={class:"news"},b={key:0,class:"mr-[10px]"},g=["src"],h={class:"flex flex-col justify-between flex-1"},k={class:"text-[15px] font-medium line-clamp-2"},j={class:"line-clamp-1 text-sm mt-[8px]"},D={class:"text-[#999] text-xs w-full flex justify-between mt-[8px]"},V={class:"flex items-center"},B={class:"ml-[5px]"},N=d({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(C){const r=y([]);return(async()=>{const p=await l({limit:10});r.value=p})(),(p,m)=>{const a=c;return o(),s("div",w,[m[0]||(m[0]=t("div",{class:"flex items-center news-title mx-[10px] my-[15px] text-[17px] font-medium"}," 最新资讯 ",-1)),(o(!0),s(_,null,x(v(r),e=>(o(),s("div",{key:e.id,class:"news-card flex bg-white px-[10px] py-[16px] text-[#333] border-[#f2f2f2] border-b"},[e.image?(o(),s("div",b,[t("img",{src:e.image,class:"w-[120px] h-[90px] object-contain"},null,8,g)])):f("",!0),t("div",h,[t("div",k,i(e.title),1),t("div",j,i(e.desc),1),t("div",D,[t("div",null,i(e.create_time),1),t("div",V,[u(a,{name:"el-icon-View"}),t("div",B,i(e.click),1)])])])]))),128))])}}}),ft=n(N,[["__scopeId","data-v-dba98882"]]);export{ft as default};
|
||||
import{c,_ as n}from"./index-xZXgRhuH.js";import{g as l}from"./decoration-DorZNrhC.js";import{f as d,ak as o,I as s,J as t,F as _,ap as x,H as f,a as u}from"./@vue/runtime-core-C0pg79pw.js";import{Q as i}from"./@vue/shared-mAAVTE9n.js";import{y as v,o as y}from"./@vue/reactivity-BIbyPIZJ.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./lodash-D3kF6u-c.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const w={class:"news"},b={key:0,class:"mr-[10px]"},g=["src"],h={class:"flex flex-col justify-between flex-1"},k={class:"text-[15px] font-medium line-clamp-2"},j={class:"line-clamp-1 text-sm mt-[8px]"},D={class:"text-[#999] text-xs w-full flex justify-between mt-[8px]"},V={class:"flex items-center"},B={class:"ml-[5px]"},N=d({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(C){const r=y([]);return(async()=>{const p=await l({limit:10});r.value=p})(),(p,m)=>{const a=c;return o(),s("div",w,[m[0]||(m[0]=t("div",{class:"flex items-center news-title mx-[10px] my-[15px] text-[17px] font-medium"}," 最新资讯 ",-1)),(o(!0),s(_,null,x(v(r),e=>(o(),s("div",{key:e.id,class:"news-card flex bg-white px-[10px] py-[16px] text-[#333] border-[#f2f2f2] border-b"},[e.image?(o(),s("div",b,[t("img",{src:e.image,class:"w-[120px] h-[90px] object-contain"},null,8,g)])):f("",!0),t("div",h,[t("div",k,i(e.title),1),t("div",j,i(e.desc),1),t("div",D,[t("div",null,i(e.create_time),1),t("div",V,[u(a,{name:"el-icon-View"}),t("div",B,i(e.click),1)])])])]))),128))])}}}),ft=n(N,[["__scopeId","data-v-dba98882"]]);export{ft as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as t}from"./index-55neFmjq.js";import{ak as o,I as r}from"./@vue/runtime-core-C0pg79pw.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const m={},i={class:"page-mate"};function p(e,c){return o(),r("div",i)}const S=t(m,[["render",p]]);export{S as default};
|
||||
import{_ as t}from"./index-xZXgRhuH.js";import{ak as o,I as r}from"./@vue/runtime-core-C0pg79pw.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const m={},i={class:"page-mate"};function p(e,c){return o(),r("div",i)}const S=t(m,[["render",p]]);export{S as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import c from"./decoration-img-DGr8eZBc.js";import{f as n,ak as r,I as o,F as l,ap as f,a as d,J as u,A as _}from"./@vue/runtime-core-C0pg79pw.js";import{p as x,Q as y}from"./@vue/shared-mAAVTE9n.js";import{y as b}from"./@vue/reactivity-BIbyPIZJ.js";import{_ as h}from"./index-55neFmjq.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const g={class:"tabbar flex"},v={class:"leading-3 text-[12px] mt-[4px]"},k=n({__name:"content",props:{style:{type:Object,default:()=>({})},list:{type:Array,default:()=>[]}},setup(e){const m=e,s=_(()=>{var t;return((t=m.list)==null?void 0:t.filter(i=>i.is_show==1))||[]});return(t,i)=>(r(),o("div",g,[(r(!0),o(l,null,f(b(s),(p,a)=>(r(),o("div",{key:a,class:"tabbar-item flex flex-col justify-center items-center flex-1",style:x({color:e.style.default_color})},[d(c,{width:"22px",height:"22px",src:p.unselected,fit:"cover"},null,8,["src"]),u("div",v,y(p.name),1)],4))),128))]))}}),st=h(k,[["__scopeId","data-v-0405bccb"]]);export{st as default};
|
||||
import c from"./decoration-img-CKm1nxte.js";import{f as n,ak as r,I as o,F as l,ap as f,a as d,J as u,A as _}from"./@vue/runtime-core-C0pg79pw.js";import{p as x,Q as y}from"./@vue/shared-mAAVTE9n.js";import{y as b}from"./@vue/reactivity-BIbyPIZJ.js";import{_ as h}from"./index-xZXgRhuH.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const g={class:"tabbar flex"},v={class:"leading-3 text-[12px] mt-[4px]"},k=n({__name:"content",props:{style:{type:Object,default:()=>({})},list:{type:Array,default:()=>[]}},setup(e){const m=e,s=_(()=>{var t;return((t=m.list)==null?void 0:t.filter(i=>i.is_show==1))||[]});return(t,i)=>(r(),o("div",g,[(r(!0),o(l,null,f(b(s),(p,a)=>(r(),o("div",{key:a,class:"tabbar-item flex flex-col justify-center items-center flex-1",style:x({color:e.style.default_color})},[d(c,{width:"22px",height:"22px",src:p.unselected,fit:"cover"},null,8,["src"]),u("div",v,y(p.name),1)],4))),128))]))}}),st=h(k,[["__scopeId","data-v-0405bccb"]]);export{st as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-CpnarxEs.js";import"./decoration-img-DGr8eZBc.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-55neFmjq.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-DKaKmkDy.js";import"./decoration-img-CKm1nxte.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C0pg79pw.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-xZXgRhuH.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as r}from"./index-55neFmjq.js";import{ak as p,I as i,J as o}from"./@vue/runtime-core-C0pg79pw.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./element-plus-6h1hTCrQ.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-jYCthPJY.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const m="/admin/assets/default_avatar-C6VB7PGm.png",e={},s={class:"user-info flex items-center px-[25px]"};function a(n,t){return p(),i("div",s,[...t[0]||(t[0]=[o("img",{src:m,class:"w-[60px] h-[60px]",alt:""},null,-1),o("div",{class:"text-white text-[18px] ml-[10px]"},"未登录",-1)])])}const T=r(e,[["render",a],["__scopeId","data-v-4b1b613f"]]);export{T as default};
|
||||
import{_ as r}from"./index-xZXgRhuH.js";import{ak as p,I as i,J as o}from"./@vue/runtime-core-C0pg79pw.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./@vue/reactivity-BIbyPIZJ.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./element-plus-osWj3D3p.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./@element-plus/icons-vue-l4gXVnmh.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const m="/admin/assets/default_avatar-C6VB7PGm.png",e={},s={class:"user-info flex items-center px-[25px]"};function a(n,t){return p(),i("div",s,[...t[0]||(t[0]=[o("img",{src:m,class:"w-[60px] h-[60px]",alt:""},null,-1),o("div",{class:"text-white text-[18px] ml-[10px]"},"未登录",-1)])])}const T=r(e,[["render",a],["__scopeId","data-v-4b1b613f"]]);export{T as default};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user