新增
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# ============================================
|
||||
# 物流查询配置示例
|
||||
# ============================================
|
||||
#
|
||||
# 快递100 API 配置(推荐)
|
||||
# 注册地址:https://www.kuaidi100.com/
|
||||
#
|
||||
# 使用说明:
|
||||
# 1. 注册快递100企业账号
|
||||
# 2. 申请API接口权限
|
||||
# 3. 获取 CUSTOMER 和 KEY
|
||||
# 4. 将以下配置复制到 .env 文件中
|
||||
# 5. 填写你的 CUSTOMER 和 KEY
|
||||
# 6. 重启服务器
|
||||
# ============================================
|
||||
|
||||
# 快递100 Customer(必填)
|
||||
LOGISTICS_KUAIDI100_CUSTOMER=你的customer
|
||||
|
||||
# 快递100 Key(必填)
|
||||
LOGISTICS_KUAIDI100_KEY=你的key
|
||||
|
||||
# 快递100 查询接口地址(可选,默认值如下)
|
||||
LOGISTICS_KUAIDI100_QUERY_URL=https://poll.kuaidi100.com/poll/query.do
|
||||
|
||||
# 临时关闭快递100查询(可选,保留密钥但不使用)
|
||||
# LOGISTICS_KUAIDI100_DISABLE=false
|
||||
|
||||
# ============================================
|
||||
# 注意事项
|
||||
# ============================================
|
||||
#
|
||||
# 1. 顺丰查询需要收件人手机号后4位验证
|
||||
# 系统会自动从订单中获取手机号
|
||||
#
|
||||
# 2. 如果未配置快递100,系统会提供官网查询链接
|
||||
# - 顺丰:https://www.sf-express.com/
|
||||
# - 京东:https://www.jdl.com/
|
||||
#
|
||||
# 3. 支持的快递公司:
|
||||
# - sf / shunfeng (顺丰速运)
|
||||
# - jd (京东快递)
|
||||
# - auto (自动识别)
|
||||
#
|
||||
# 4. 查询失败排查:
|
||||
# - 检查运单号是否正确
|
||||
# - 确认快递已揽收
|
||||
# - 检查快递100账户余额
|
||||
# - 顺丰需确认手机号正确
|
||||
# ============================================
|
||||
+50
-1
@@ -1 +1,50 @@
|
||||
APP_DEBUG = true
|
||||
APP_DEBUG = true
|
||||
|
||||
[APP]
|
||||
DEFAULT_TIMEZONE = "Asia/Shanghai"
|
||||
|
||||
[DATABASE]
|
||||
TYPE = "mysql"
|
||||
HOSTNAME = "39.97.232.35"
|
||||
DATABASE = "cs_zyt"
|
||||
USERNAME = "cs_zyt"
|
||||
PASSWORD = "3e64R8XcfJpbBhEf"
|
||||
HOSTPORT = "3306"
|
||||
CHARSET = "utf8mb4"
|
||||
DEBUG = "1"
|
||||
PREFIX = "zyt_"
|
||||
|
||||
[LANG]
|
||||
default_lang = "zh-cn"
|
||||
|
||||
[PROJECT]
|
||||
UNIQUE_IDENTIFICATION = "5687"
|
||||
DEMO_ENV = ""
|
||||
|
||||
[WORK_WECHAT]
|
||||
CORP_ID = "ww8623e34e60d48bec"
|
||||
AGENT_ID = "1000031"
|
||||
SECRET = "bLD-1HtnimxLuF1A-24-DeD0nBri0T_Dc1BzE6zbZb4"
|
||||
CONTACT_SECRET = "aEvXpVIVoXWaFAYM-YCCMRGSO3l931PTcdPSTrAEgg8"
|
||||
# true=强制非 root 绑定企微;false=关闭;也可在根级写 WORK_WECHAT_FORCE_BIND_LOGIN
|
||||
FORCE_BIND_LOGIN = false
|
||||
[TRTC]
|
||||
SDK_APP_ID = "1600132918"
|
||||
SECRET_KEY = "d93e9195b247e42e1cd707e450b678a90115c93877df91b1f2649778ca442c37"
|
||||
ENABLE = "true"
|
||||
|
||||
[LANG]
|
||||
default_lang = zh-cn
|
||||
|
||||
[PROJECT]
|
||||
UNIQUE_IDENTIFICATION = likeadmin
|
||||
# 演示环境
|
||||
DEMO_ENV = false
|
||||
|
||||
# 物流轨迹(快递100):https://api.kuaidi100.com
|
||||
; ThinkPHP .env 为 INI:下列建议写在分区声明之前;若误写在 trtc 分区内,config 已兼容
|
||||
# 同时填 CUSTOMER、KEY 即启用;临时关闭设 LOGISTICS_KUAIDI100_DISABLE = true
|
||||
LOGISTICS_KUAIDI100_CUSTOMER =
|
||||
LOGISTICS_KUAIDI100_KEY =
|
||||
# LOGISTICS_KUAIDI100_DISABLE = false
|
||||
# LOGISTICS_KUAIDI100_QUERY_URL = https://poll.kuaidi100.com/poll/query.do
|
||||
@@ -50,13 +50,23 @@ class LoginController extends BaseAdminController
|
||||
$agentId = env('work_wechat.agent_id', '');
|
||||
|
||||
if (empty($corpId) || empty($agentId)) {
|
||||
return $this->data(['enabled' => false]);
|
||||
return $this->data([
|
||||
'enabled' => false,
|
||||
'require_bind_nonroot' => false,
|
||||
'force_bind_login' => LoginLogic::isForceBindWorkWechatFromEnv(),
|
||||
]);
|
||||
}
|
||||
|
||||
$oauthOk = LoginLogic::isWorkWechatOAuthConfigured();
|
||||
$forceBind = LoginLogic::isForceBindWorkWechatFromEnv();
|
||||
|
||||
return $this->data([
|
||||
'enabled' => true,
|
||||
'corp_id' => $corpId,
|
||||
'agent_id' => $agentId,
|
||||
/** 与 .env FORCE_BIND_LOGIN 一致:为 true 且 OAuth 配全时非 root 须先绑定 */
|
||||
'require_bind_nonroot' => $forceBind && $oauthOk,
|
||||
'force_bind_login' => $forceBind,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ use app\adminapi\validate\auth\AdminValidate;
|
||||
use app\adminapi\logic\auth\AdminLogic;
|
||||
use app\adminapi\logic\LoginLogic;
|
||||
use app\adminapi\validate\auth\editSelfValidate;
|
||||
use app\common\cache\AdminTokenCache;
|
||||
use app\common\model\auth\Admin;
|
||||
|
||||
/**
|
||||
@@ -169,9 +170,14 @@ class AdminController extends BaseAdminController
|
||||
return $this->fail('企业微信授权失败: ' . ($response['errmsg'] ?? '未知错误'));
|
||||
}
|
||||
|
||||
$wxUserId = $response['userid'] ?? '';
|
||||
if (empty($wxUserId)) {
|
||||
return $this->fail('未获取到企业微信用户身份');
|
||||
$wxUserId = LoginLogic::workWechatUserIdFromAuthResponse($response);
|
||||
if ($wxUserId === '') {
|
||||
$hasOpenId = trim((string) ($response['openid'] ?? $response['OpenId'] ?? '')) !== '';
|
||||
return $this->fail(
|
||||
$hasOpenId
|
||||
? '当前扫码账号非企业通讯录成员(或尚未同步到通讯录),无法绑定。请使用已在企业微信通讯录中的成员扫码,或联系管理员将你加入企业后再试'
|
||||
: '未获取到企业微信成员 userid。请确认 .env 中 work_wechat.secret 为「该自建应用」的 Secret(与 agent_id 对应),且绑定页完整 URL 已加入应用可信域名'
|
||||
);
|
||||
}
|
||||
|
||||
// 检查是否已被其他管理员绑定
|
||||
@@ -182,10 +188,15 @@ class AdminController extends BaseAdminController
|
||||
return $this->fail('该企业微信账号已被其他管理员绑定');
|
||||
}
|
||||
|
||||
Admin::update([
|
||||
'id' => $this->adminId,
|
||||
'work_wechat_userid' => $wxUserId,
|
||||
]);
|
||||
$affected = Admin::where('id', $this->adminId)->update(['work_wechat_userid' => $wxUserId]);
|
||||
if ($affected === 0) {
|
||||
return $this->fail('保存绑定失败,请确认账号有效后重试');
|
||||
}
|
||||
|
||||
$token = $this->request->header('token');
|
||||
if ($token) {
|
||||
(new AdminTokenCache())->deleteAdminInfo($token);
|
||||
}
|
||||
|
||||
return $this->success('绑定成功', ['work_wechat_userid' => $wxUserId]);
|
||||
}
|
||||
@@ -195,10 +206,7 @@ class AdminController extends BaseAdminController
|
||||
*/
|
||||
public function unbindWorkWechat()
|
||||
{
|
||||
Admin::update([
|
||||
'id' => $this->adminId,
|
||||
'work_wechat_userid' => '',
|
||||
]);
|
||||
Admin::where('id', $this->adminId)->update(['work_wechat_userid' => '']);
|
||||
|
||||
return $this->success('解绑成功');
|
||||
}
|
||||
|
||||
@@ -25,6 +25,27 @@ class OrderController extends BaseAdminController
|
||||
return $this->dataLists(new OrderLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 指定诊单下已支付支付单列表(创建/编辑处方业务订单时多选关联)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function paidOrdersForDiagnosis()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->get('diagnosis_id', 0);
|
||||
if ($diagnosisId <= 0) {
|
||||
return $this->fail('诊单ID必填');
|
||||
}
|
||||
$exceptPo = (int) $this->request->get('prescription_order_id', 0);
|
||||
$lists = OrderLogic::listPaidOrdersForDiagnosis(
|
||||
$diagnosisId,
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
$exceptPo > 0 ? $exceptPo : null
|
||||
);
|
||||
|
||||
return $this->success('', ['lists' => $lists]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 同步企业微信对外收款账单到订单
|
||||
* 员工直接在企业微信发起收款(未经过后台创建)时,通过此接口拉取并创建订单
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\lists\tcm\PrescriptionOrderLists;
|
||||
use app\adminapi\logic\order\OrderLogic;
|
||||
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
|
||||
use app\adminapi\validate\tcm\PrescriptionOrderValidate;
|
||||
|
||||
/**
|
||||
* 处方业务订单(非支付单)
|
||||
*/
|
||||
class PrescriptionOrderController extends BaseAdminController
|
||||
{
|
||||
public function lists()
|
||||
{
|
||||
return $this->dataLists(new PrescriptionOrderLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定诊单下已支付支付单(创建/编辑业务订单时多选关联)
|
||||
*/
|
||||
public function paidPayOrders()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('paidPayOrders');
|
||||
$exceptPo = (int) $this->request->get('prescription_order_id', 0);
|
||||
$lists = OrderLogic::listPaidOrdersForDiagnosis(
|
||||
(int) $params['diagnosis_id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
$exceptPo > 0 ? $exceptPo : null
|
||||
);
|
||||
|
||||
return $this->success('', ['lists' => $lists]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('create');
|
||||
$result = PrescriptionOrderLogic::create($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('创建成功', $result);
|
||||
}
|
||||
|
||||
public function detail()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('detail');
|
||||
$detail = PrescriptionOrderLogic::detail((int) $params['id'], $this->adminId, $this->adminInfo);
|
||||
if ($detail === null) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->data($detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快递轨迹查询(对接快递100;未配置时仍可跳转顺丰/京东官网)
|
||||
*/
|
||||
public function logisticsTrace()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('logisticsTrace');
|
||||
$expressOverride = trim((string) $this->request->get('express_company', ''));
|
||||
$data = PrescriptionOrderLogic::logisticsTrace(
|
||||
(int) $params['id'],
|
||||
$expressOverride,
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($data === null) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('', $data);
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('edit');
|
||||
$result = PrescriptionOrderLogic::edit($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('保存成功', $result);
|
||||
}
|
||||
|
||||
public function auditPrescription()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('auditPrescription');
|
||||
$result = PrescriptionOrderLogic::auditPrescription(
|
||||
(int) $params['id'],
|
||||
(string) $params['action'],
|
||||
(string) ($params['remark'] ?? ''),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('操作成功', $result);
|
||||
}
|
||||
|
||||
public function auditPayment()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('auditPayment');
|
||||
$result = PrescriptionOrderLogic::auditPaymentSlip(
|
||||
(int) $params['id'],
|
||||
(string) $params['action'],
|
||||
(string) ($params['remark'] ?? ''),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('操作成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 医助/创建人撤回:仅「待双审通过」可撤(未通过或双审均驳回等仍为该状态)
|
||||
*/
|
||||
public function withdraw()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('withdraw');
|
||||
$result = PrescriptionOrderLogic::withdraw((int) $params['id'], $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('已撤回', $result);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ declare (strict_types=1);
|
||||
|
||||
namespace app\adminapi\http\middleware;
|
||||
|
||||
use app\adminapi\logic\LoginLogic;
|
||||
use app\common\{
|
||||
cache\AdminAuthCache,
|
||||
service\JsonService
|
||||
@@ -48,11 +49,23 @@ class AuthMiddleware
|
||||
return JsonService::fail('ip地址发生变化,请重新登录', [], -1);
|
||||
}
|
||||
|
||||
// 非 root 待绑企微:放行绑定 / 解绑 / 个人信息 / 退出(避免无菜单权限;action 与路由大小写一致)
|
||||
if (LoginLogic::adminMustBindWorkWechat($request->adminInfo)) {
|
||||
if (LoginLogic::isWorkWechatBindExemptActionName((string) $request->action())) {
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
//系统默认超级管理员,无需权限验证
|
||||
if (1 === $request->adminInfo['root']) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
// 面诊进度看板:仅登录即可拉医生列表 + 预约列表(须带 progress_board=1,见 AdminLists / AppointmentLists 内限制)
|
||||
if ($this->isFaceProgressBoardPublicLists($request)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$adminAuthCache = new AdminAuthCache($request->adminInfo['admin_id']);
|
||||
|
||||
// 当前访问路径
|
||||
@@ -90,4 +103,19 @@ class AuthMiddleware
|
||||
}, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 面诊进度专用:auth.admin/lists、doctor.appointment/lists + progress_board=1,不校验菜单权限
|
||||
*/
|
||||
private function isFaceProgressBoardPublicLists($request): bool
|
||||
{
|
||||
if ((int) $request->param('progress_board', 0) !== 1) {
|
||||
return false;
|
||||
}
|
||||
if (strtolower((string) $request->action()) !== 'lists') {
|
||||
return false;
|
||||
}
|
||||
$c = strtolower((string) $request->controller());
|
||||
|
||||
return in_array($c, ['auth.admin', 'doctor.appointment'], true);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ declare (strict_types=1);
|
||||
|
||||
namespace app\adminapi\http\middleware;
|
||||
|
||||
use app\adminapi\logic\LoginLogic;
|
||||
use app\common\cache\AdminTokenCache;
|
||||
use app\adminapi\service\AdminTokenService;
|
||||
use app\common\service\JsonService;
|
||||
@@ -72,7 +73,34 @@ class LoginMiddleware
|
||||
$request->adminInfo = $adminInfo;
|
||||
$request->adminId = $adminInfo['admin_id'] ?? 0;
|
||||
|
||||
// 非 root 须绑定企微:免登录接口不拦截(如 getConfig),避免 init 死循环
|
||||
if (!empty($adminInfo) && LoginLogic::adminMustBindWorkWechat($adminInfo) && !$isNotNeedLogin) {
|
||||
if (!self::isWorkWechatBindExemptAction($request)) {
|
||||
return JsonService::fail(
|
||||
'请先绑定企业微信后再使用系统',
|
||||
[],
|
||||
LoginLogic::CODE_NEED_BIND_WORK_WECHAT,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
private static function isWorkWechatBindExemptAction($request): bool
|
||||
{
|
||||
if (LoginLogic::isWorkWechatBindExemptActionName((string) $request->action())) {
|
||||
return true;
|
||||
}
|
||||
// 与 AuthMiddleware 一致:未绑企微时仍允许打开面诊进度所需只读列表
|
||||
if ((int) $request->param('progress_board', 0) === 1 && strtolower((string) $request->action()) === 'lists') {
|
||||
$c = strtolower((string) $request->controller());
|
||||
|
||||
return in_array($c, ['auth.admin', 'doctor.appointment'], true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,7 +71,39 @@ class OperationLog
|
||||
$systemLog->type = $request->isGet() ? 'GET' : 'POST';
|
||||
$systemLog->params = json_encode($params, true);
|
||||
$systemLog->ip = $request->ip();
|
||||
$systemLog->result = $response->getContent();
|
||||
$systemLog->result = $this->shortenOperationLogResult((string) $response->getContent());
|
||||
return $systemLog->save();
|
||||
}
|
||||
|
||||
/** MySQL TEXT 上限约 64KB,列表接口常含 base64 签名导致超长 */
|
||||
private function shortenOperationLogResult(string $content): string
|
||||
{
|
||||
$maxBytes = 62000;
|
||||
$decoded = json_decode($content, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
|
||||
$this->stripLargeLogFields($decoded);
|
||||
$content = json_encode($decoded, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
if (strlen($content) > $maxBytes) {
|
||||
$content = substr($content, 0, $maxBytes) . '...[truncated]';
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function stripLargeLogFields(array &$data): void
|
||||
{
|
||||
foreach ($data as $key => &$value) {
|
||||
if (is_array($value)) {
|
||||
$this->stripLargeLogFields($value);
|
||||
continue;
|
||||
}
|
||||
if (! is_string($key)) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($key, ['doctor_signature', 'tongue_image'], true) && is_string($value) && strlen($value) > 200) {
|
||||
$value = '[omitted:' . strlen($value) . ' bytes]';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,12 +112,28 @@ class AdminLists extends BaseAdminDataLists implements ListsExtendInterface, Lis
|
||||
public function queryWhere()
|
||||
{
|
||||
$where = [];
|
||||
if (isset($this->params['role_id']) && $this->params['role_id'] != '') {
|
||||
$adminIds = AdminRole::where('role_id', $this->params['role_id'])->column('admin_id');
|
||||
$progressBoard = (int) ($this->params['progress_board'] ?? 0) === 1;
|
||||
|
||||
if ($progressBoard) {
|
||||
// 面诊进度:固定只拉「医生」角色且未禁用,忽略客户端篡改的 role_id
|
||||
$adminIds = AdminRole::where('role_id', 1)->column('admin_id');
|
||||
if (!empty($adminIds)) {
|
||||
$where[] = ['id', 'in', $adminIds];
|
||||
}
|
||||
$where[] = ['disable', '=', 0];
|
||||
} else {
|
||||
if (isset($this->params['role_id']) && $this->params['role_id'] != '') {
|
||||
$adminIds = AdminRole::where('role_id', $this->params['role_id'])->column('admin_id');
|
||||
if (!empty($adminIds)) {
|
||||
$where[] = ['id', 'in', $adminIds];
|
||||
}
|
||||
}
|
||||
// 排除禁止登录(disable=1),医生选择器等场景
|
||||
if ((int) ($this->params['exclude_disabled'] ?? 0) === 1) {
|
||||
$where[] = ['disable', '=', 0];
|
||||
}
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,14 +64,29 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
$this->searchWhere[] = ['a.patient_id', '=', (int) $this->params['patient_id']];
|
||||
}
|
||||
|
||||
// 构建查询
|
||||
// 按接诊医生筛选(管理端医生进度看板等)
|
||||
if (!empty($this->params['doctor_id'])) {
|
||||
$this->searchWhere[] = ['a.doctor_id', '=', (int) $this->params['doctor_id']];
|
||||
}
|
||||
|
||||
// 排除已取消挂号 status=2(医生进度看板等;未显式筛选「已取消」时生效)
|
||||
if ((int) ($this->params['exclude_cancelled'] ?? 0) === 1) {
|
||||
$sf = $this->params['status'] ?? '';
|
||||
if ($sf === '' || (int) $sf !== 2) {
|
||||
$this->searchWhere[] = ['a.status', '<>', 2];
|
||||
}
|
||||
}
|
||||
|
||||
// 构建查询(searchWhere 为空时避免部分环境下 where([]) 异常)
|
||||
$query = Appointment::alias('a')
|
||||
->with('diagnosis')
|
||||
->leftJoin('tcm_diagnosis u', 'a.patient_id = u.id')
|
||||
->leftJoin('admin ad', 'a.doctor_id = ad.id')
|
||||
->leftJoin('admin asst', 'a.assistant_id = asst.id')
|
||||
->field('a.*, u.patient_name as patient_name, u.phone as patient_phone, u.gender as gender, u.age as age, u.weight as weight, u.height as height, ad.name as doctor_name, asst.name as assistant_name, u.id as diagnosis_id')
|
||||
->where($this->searchWhere);
|
||||
->leftJoin('admin asst', 'u.assistant_id = asst.id')
|
||||
->field('a.*, u.patient_name as patient_name, u.phone as patient_phone, u.gender as gender, u.age as age, u.weight as weight, u.height as height, u.assistant_id as assistant_id, ad.name as doctor_name, asst.name as assistant_name, u.id as diagnosis_id');
|
||||
if ($this->searchWhere !== []) {
|
||||
$query->where($this->searchWhere);
|
||||
}
|
||||
|
||||
// 是否确认诊单:1=已确认 0=未确认
|
||||
if (isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') {
|
||||
@@ -85,14 +100,18 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是医生角色(role_id=1),只显示挂自己号的预约
|
||||
if (in_array(1, $roleIds)) {
|
||||
$query->where('a.doctor_id', $this->adminId);
|
||||
}
|
||||
|
||||
// 如果是医助角色(role_id=2),只显示自己添加的患者的预约
|
||||
if (in_array(2, $roleIds)) {
|
||||
$query->where('u.assistant_id', $this->adminId);
|
||||
// 面诊进度看板:可切换查看各医生挂号,不按当前账号角色收窄
|
||||
$progressBoard = (int) ($this->params['progress_board'] ?? 0) === 1;
|
||||
if (!$progressBoard) {
|
||||
// 如果是医生角色(role_id=1),只显示挂自己号的预约
|
||||
if (in_array(1, $roleIds)) {
|
||||
$query->where('a.doctor_id', $this->adminId);
|
||||
}
|
||||
|
||||
// 如果是医助角色(role_id=2),只显示自己添加的患者的预约
|
||||
if (in_array(2, $roleIds)) {
|
||||
$query->where('u.assistant_id', $this->adminId);
|
||||
}
|
||||
}
|
||||
|
||||
// 诊单软删除后不再展示对应挂号(leftJoin 时无诊单或诊单未删)
|
||||
@@ -118,11 +137,19 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
$confirmedMap = array_flip($confirmedIds ?: []);
|
||||
}
|
||||
// 开方状态:诊单是否有处方(按 diagnosis_id 查)
|
||||
// prescription_today_only=1:仅统计「今日创建」的处方(医生进度看板用,与历史处方区分)
|
||||
$rxTodayOnly = (int) ($this->params['prescription_today_only'] ?? 0) === 1;
|
||||
$prescribedDiagnosisIds = [];
|
||||
if (!empty($diagnosisIds)) {
|
||||
$prescribedDiagnosisIds = Prescription::whereIn('diagnosis_id', $diagnosisIds)
|
||||
$rxQ = Prescription::whereIn('diagnosis_id', $diagnosisIds)
|
||||
->whereNull('delete_time')
|
||||
->column('diagnosis_id');
|
||||
->where('void_status', 0);
|
||||
if ($rxTodayOnly) {
|
||||
$dayStart = strtotime(date('Y-m-d 00:00:00'));
|
||||
$dayEnd = strtotime(date('Y-m-d 23:59:59'));
|
||||
$rxQ->whereBetween('create_time', [$dayStart, $dayEnd]);
|
||||
}
|
||||
$prescribedDiagnosisIds = $rxQ->column('diagnosis_id');
|
||||
$prescribedDiagnosisIds = array_flip($prescribedDiagnosisIds ?: []);
|
||||
}
|
||||
// 当前页预约关联的处方(按 appointment_id,取最新一条):用于「开方/查看」与审核状态
|
||||
@@ -131,6 +158,7 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
if (!empty($appointmentIds)) {
|
||||
$rxRows = Prescription::whereIn('appointment_id', $appointmentIds)
|
||||
->whereNull('delete_time')
|
||||
->where('void_status', 0)
|
||||
->order('id', 'desc')
|
||||
->field(['id', 'appointment_id', 'audit_status', 'void_status'])
|
||||
->select()
|
||||
@@ -208,6 +236,17 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
$query->where('a.patient_id', '=', (int) $this->params['patient_id']);
|
||||
}
|
||||
|
||||
if (!empty($this->params['doctor_id'])) {
|
||||
$query->where('a.doctor_id', '=', (int) $this->params['doctor_id']);
|
||||
}
|
||||
|
||||
if ((int) ($this->params['exclude_cancelled'] ?? 0) === 1) {
|
||||
$sf = $this->params['status'] ?? '';
|
||||
if ($sf === '' || (int) $sf !== 2) {
|
||||
$query->where('a.status', '<>', 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') {
|
||||
$confirmed = (int)$this->params['diagnosis_confirmed'];
|
||||
$tbl = (new DiagnosisViewRecord())->getTable();
|
||||
@@ -219,11 +258,14 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array(1, $roleIds)) {
|
||||
$query->where('a.doctor_id', $this->adminId);
|
||||
}
|
||||
if (in_array(2, $roleIds)) {
|
||||
$query->where('u.assistant_id', $this->adminId);
|
||||
$progressBoard = (int) ($this->params['progress_board'] ?? 0) === 1;
|
||||
if (!$progressBoard) {
|
||||
if (in_array(1, $roleIds)) {
|
||||
$query->where('a.doctor_id', $this->adminId);
|
||||
}
|
||||
if (in_array(2, $roleIds)) {
|
||||
$query->where('u.assistant_id', $this->adminId);
|
||||
}
|
||||
}
|
||||
|
||||
$query->whereRaw('(u.id IS NULL OR u.delete_time IS NULL)');
|
||||
|
||||
@@ -21,6 +21,7 @@ use app\common\model\doctor\Appointment;
|
||||
use app\common\model\tcm\Prescription;
|
||||
use app\common\model\tcm\CallRecord;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\auth\AdminDept;
|
||||
use app\common\model\auth\AdminRole;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
|
||||
@@ -96,6 +97,21 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
}
|
||||
}
|
||||
|
||||
// 仅已开方(有处方)的诊单:随访列表传 only_has_prescription=1;问诊等页面不传则不过滤
|
||||
if (isset($this->params['only_has_prescription']) && (string) $this->params['only_has_prescription'] === '1') {
|
||||
$rxTbl = (new Prescription())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$rxTbl} rx WHERE rx.diagnosis_id = {$diagTbl}.id AND rx.delete_time IS NULL");
|
||||
}
|
||||
|
||||
// 医助所属部门(随访等页面传 assistant_dept_id):只看待定部门下医助负责的诊单
|
||||
if (isset($this->params['assistant_dept_id']) && $this->params['assistant_dept_id'] !== '' && (int) $this->params['assistant_dept_id'] > 0) {
|
||||
$deptId = (int) $this->params['assistant_dept_id'];
|
||||
$adTbl = (new AdminDept())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$adTbl} ad WHERE ad.admin_id = {$diagTbl}.assistant_id AND ad.dept_id = {$deptId}");
|
||||
}
|
||||
|
||||
// 按挂号日期+时间升序。若传了 appointment_date(当天/明天等筛选),只按「该日」的挂号排序与展示,避免仍按历史最早一天把昨天号顶到最前
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
@@ -114,9 +130,10 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
|
||||
// 关联挂号:doctor_appointment.patient_id 存诊单主键 id(与 Appointment 列表 join 一致)
|
||||
$diagnosisIds = array_filter(array_unique(array_column($lists, 'id')));
|
||||
|
||||
if (!empty($diagnosisIds)) {
|
||||
$appointmentMap = [];
|
||||
$subQuery = Appointment::where('patient_id', 'in', $diagnosisIds)
|
||||
@@ -124,20 +141,36 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
if (!empty($this->params['appointment_date'])) {
|
||||
$subQuery->where('appointment_date', (string) $this->params['appointment_date']);
|
||||
}
|
||||
|
||||
$subQuery
|
||||
->field('id, patient_id, doctor_id, appointment_date, appointment_time, status, create_time')
|
||||
->order('appointment_date', 'asc')
|
||||
->order('appointment_time', 'asc')
|
||||
->order('id', 'asc');
|
||||
$appointments = $subQuery->select()->toArray();
|
||||
|
||||
foreach ($appointments as $apt) {
|
||||
$did = $apt['patient_id'];
|
||||
$did = (int) ($apt['patient_id'] ?? 0);
|
||||
if ($did <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($appointmentMap[$did])) {
|
||||
$appointmentMap[$did] = $apt;
|
||||
$appointmentMap[$did] = [];
|
||||
}
|
||||
$appointmentMap[$did][] = $apt;
|
||||
}
|
||||
|
||||
// 获取医生名称
|
||||
$doctorIds = [];
|
||||
foreach ($appointmentMap as $aptList) {
|
||||
foreach ($aptList as $apt) {
|
||||
$docId = (int) ($apt['doctor_id'] ?? 0);
|
||||
if ($docId > 0) {
|
||||
$doctorIds[] = $docId;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 获取医生名称
|
||||
$doctorIds = array_unique(array_column($appointmentMap, 'doctor_id'));
|
||||
$doctorIds = array_values(array_unique($doctorIds));
|
||||
$doctorNames = [];
|
||||
if (!empty($doctorIds)) {
|
||||
$doctors = Admin::whereIn('id', $doctorIds)->column('name', 'id');
|
||||
@@ -145,8 +178,9 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
}
|
||||
// 合并到诊单列表
|
||||
foreach ($lists as &$item) {
|
||||
$apt = $appointmentMap[$item['id']] ?? null;
|
||||
if ($apt) {
|
||||
$aptList = $appointmentMap[(int) $item['id']] ?? [];
|
||||
if (!empty($aptList)) {
|
||||
$apt = $aptList[0];
|
||||
$item['has_appointment'] = 1;
|
||||
$item['appointment_id'] = $apt['id'];
|
||||
$item['appointment_status'] = (int) ($apt['status'] ?? 0);
|
||||
@@ -157,6 +191,21 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$timePart = substr($timePart, 0, 5); // 09:00:00 -> 09:00
|
||||
}
|
||||
$item['appointment_time_text'] = trim(($apt['appointment_date'] ?? '') . ' ' . $timePart);
|
||||
$item['appointments'] = array_map(function ($a) use ($doctorNames) {
|
||||
$timePart = $a['appointment_time'] ?? '';
|
||||
if (strlen((string) $timePart) > 5) {
|
||||
$timePart = substr((string) $timePart, 0, 5);
|
||||
}
|
||||
$doctorId = (int) ($a['doctor_id'] ?? 0);
|
||||
|
||||
return [
|
||||
'id' => (int) ($a['id'] ?? 0),
|
||||
'status' => (int) ($a['status'] ?? 0),
|
||||
'doctor_id' => $doctorId,
|
||||
'doctor_name' => (string) ($doctorNames[$doctorId] ?? '-'),
|
||||
'time_text' => trim((string) ($a['appointment_date'] ?? '') . ' ' . (string) $timePart),
|
||||
];
|
||||
}, $aptList);
|
||||
} else {
|
||||
$item['has_appointment'] = 0;
|
||||
$item['appointment_id'] = null;
|
||||
@@ -164,6 +213,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$item['appointment_doctor_id'] = null;
|
||||
$item['appointment_doctor_name'] = '';
|
||||
$item['appointment_time_text'] = '';
|
||||
$item['appointments'] = [];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -174,6 +224,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$item['appointment_doctor_id'] = null;
|
||||
$item['appointment_doctor_name'] = '';
|
||||
$item['appointment_time_text'] = '';
|
||||
$item['appointments'] = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,6 +242,66 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$item['has_prescription'] = isset($prescriptionMap[$item['id']]) ? 1 : 0;
|
||||
}
|
||||
|
||||
// 复诊展示:业务上「已开方」即算有复诊,取该诊单下最新一条处方的时间与医师(优先未作废)
|
||||
$followupByDiag = [];
|
||||
$rxCountByDiag = [];
|
||||
if ($diagnosisIds !== []) {
|
||||
$rxAll = Prescription::whereIn('diagnosis_id', $diagnosisIds)
|
||||
->whereNull('delete_time')
|
||||
->field(['id', 'diagnosis_id', 'doctor_name', 'creator_id', 'prescription_date', 'create_time', 'void_status'])
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
foreach ($rxAll as $rx) {
|
||||
$dCount = (int) ($rx['diagnosis_id'] ?? 0);
|
||||
if ($dCount > 0) {
|
||||
$rxCountByDiag[$dCount] = ($rxCountByDiag[$dCount] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
foreach ($rxAll as $rx) {
|
||||
$d = (int) ($rx['diagnosis_id'] ?? 0);
|
||||
if ($d <= 0 || isset($followupByDiag[$d])) {
|
||||
continue;
|
||||
}
|
||||
if ((int) ($rx['void_status'] ?? 0) === 0) {
|
||||
$followupByDiag[$d] = $rx;
|
||||
}
|
||||
}
|
||||
foreach ($rxAll as $rx) {
|
||||
$d = (int) ($rx['diagnosis_id'] ?? 0);
|
||||
if ($d <= 0 || isset($followupByDiag[$d])) {
|
||||
continue;
|
||||
}
|
||||
$followupByDiag[$d] = $rx;
|
||||
}
|
||||
$creatorIds = array_values(array_unique(array_filter(array_column($followupByDiag, 'creator_id'))));
|
||||
$creatorNames = [];
|
||||
if ($creatorIds !== []) {
|
||||
$creatorNames = Admin::whereIn('id', $creatorIds)->whereNull('delete_time')->column('name', 'id');
|
||||
}
|
||||
foreach ($followupByDiag as $d => $rx) {
|
||||
$doctorName = trim((string) ($rx['doctor_name'] ?? ''));
|
||||
$cid = (int) ($rx['creator_id'] ?? 0);
|
||||
if ($doctorName === '' && $cid > 0) {
|
||||
$doctorName = (string) ($creatorNames[$cid] ?? '');
|
||||
}
|
||||
$followupByDiag[$d] = [
|
||||
'time_text' => $this->formatPrescriptionFollowupTime($rx),
|
||||
'doctor_name' => $doctorName !== '' ? $doctorName : '—',
|
||||
'voided' => (int) ($rx['void_status'] ?? 0) !== 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
foreach ($lists as &$item) {
|
||||
$did = (int) $item['id'];
|
||||
$fu = $followupByDiag[$did] ?? null;
|
||||
$item['followup_time_text'] = ($item['has_prescription'] && $fu) ? ($fu['time_text'] ?? '') : '';
|
||||
$item['followup_doctor_name'] = ($item['has_prescription'] && $fu) ? ($fu['doctor_name'] ?? '—') : '';
|
||||
$item['followup_rx_voided'] = ($item['has_prescription'] && $fu && !empty($fu['voided'])) ? 1 : 0;
|
||||
// 开方次数即复诊次数:1 张处方 = 第 1 次复诊,以此类推
|
||||
$item['followup_prescription_count'] = (int) ($rxCountByDiag[$did] ?? 0);
|
||||
}
|
||||
|
||||
// 最近一条通话记录状态(列表行展示:通话中 / 已结束等)
|
||||
$latestCallByDiag = [];
|
||||
if (!empty($diagnosisIds)) {
|
||||
@@ -214,6 +325,20 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
return $lists;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $rx 处方一行
|
||||
*/
|
||||
private function formatPrescriptionFollowupTime(array $rx): string
|
||||
{
|
||||
$ct = (int) ($rx['create_time'] ?? 0);
|
||||
$pd = trim((string) ($rx['prescription_date'] ?? ''));
|
||||
if ($pd !== '') {
|
||||
return $pd . ($ct > 0 ? ' ' . date('H:i', $ct) : '');
|
||||
}
|
||||
|
||||
return $ct > 0 ? date('Y-m-d H:i', $ct) : '—';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed>|null $rec tcm_call_record 一行
|
||||
* @return array{state:string,label:string,end_time?:int,start_time?:int}
|
||||
|
||||
@@ -8,6 +8,7 @@ use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\adminapi\logic\tcm\PrescriptionLogic;
|
||||
use app\common\model\tcm\Prescription;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
|
||||
/**
|
||||
* 处方列表
|
||||
@@ -80,6 +81,7 @@ class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterfa
|
||||
$query->where(function ($q) use ($adminId, $roleIds) {
|
||||
$q->whereOr('is_shared', '=', 1);
|
||||
$q->whereOr('creator_id', '=', $adminId);
|
||||
$q->whereOr('assistant_id', '=', $adminId);
|
||||
foreach ($roleIds as $rid) {
|
||||
if ($rid > 0) {
|
||||
$q->whereOrRaw('FIND_IN_SET(?, `visible_role_ids`)', [(string) $rid]);
|
||||
@@ -105,7 +107,42 @@ class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterfa
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
|
||||
$rxIds = array_column($lists, 'id');
|
||||
$rxIds = array_map('intval', $rxIds);
|
||||
$rejectedRx = [];
|
||||
$bizRejectRemark = [];
|
||||
$hasBizOrderRx = [];
|
||||
if ($rxIds !== []) {
|
||||
$bizRejectRows = PrescriptionOrder::whereIn('prescription_id', $rxIds)
|
||||
->where('prescription_audit_status', 2)
|
||||
->whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->field(['prescription_id', 'prescription_audit_remark', 'id'])
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
foreach ($bizRejectRows as $br) {
|
||||
$pid = (int) ($br['prescription_id'] ?? 0);
|
||||
if ($pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$rejectedRx[$pid] = true;
|
||||
if (!isset($bizRejectRemark[$pid])) {
|
||||
$bizRejectRemark[$pid] = (string) ($br['prescription_audit_remark'] ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
$orderRxIds = array_unique(array_map(
|
||||
'intval',
|
||||
PrescriptionOrder::whereIn('prescription_id', $rxIds)
|
||||
->whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->column('prescription_id')
|
||||
));
|
||||
$hasBizOrderRx = array_fill_keys($orderRxIds, true);
|
||||
}
|
||||
|
||||
// 处理字段格式
|
||||
foreach ($lists as &$item) {
|
||||
// 设置默认值
|
||||
@@ -117,6 +154,10 @@ class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterfa
|
||||
$item['audit_status'] = (int) ($item['audit_status'] ?? 1);
|
||||
$item['void_status'] = (int) ($item['void_status'] ?? 0);
|
||||
$item['visible_role_ids'] = PrescriptionLogic::visibleRoleIdsToArray((string) ($item['visible_role_ids'] ?? ''));
|
||||
$rid = (int) ($item['id'] ?? 0);
|
||||
$item['business_prescription_audit_rejected'] = !empty($rejectedRx[$rid]) ? 1 : 0;
|
||||
$item['business_prescription_audit_remark'] = (string) ($bizRejectRemark[$rid] ?? '');
|
||||
$item['has_prescription_order'] = !empty($hasBizOrderRx[$rid]) ? 1 : 0;
|
||||
|
||||
// 将 dietary_taboo 从逗号分隔的字符串转换为数组(前端需要数组格式)
|
||||
if (!empty($item['dietary_taboo']) && is_string($item['dietary_taboo'])) {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\tcm;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||
|
||||
class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['prescription_id', 'fulfillment_status'],
|
||||
'%like%' => ['order_no'],
|
||||
];
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$query = PrescriptionOrder::where($this->searchWhere)->whereNull('delete_time');
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
$diagIds = Diagnosis::where('assistant_id', $this->adminId)->whereNull('delete_time')->column('id');
|
||||
$query->where(function ($q) use ($diagIds) {
|
||||
$q->where('creator_id', $this->adminId);
|
||||
if ($diagIds !== []) {
|
||||
$q->whereOr('diagnosis_id', 'in', $diagIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
$lists = $query
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
foreach ($lists as &$item) {
|
||||
PrescriptionOrderLogic::maskInternalCostIfNeeded($item, $this->adminInfo);
|
||||
$item['linked_pay_order_count'] = (int) PrescriptionOrderPayOrder::where(
|
||||
'prescription_order_id',
|
||||
(int) ($item['id'] ?? 0)
|
||||
)->count();
|
||||
}
|
||||
unset($item);
|
||||
|
||||
return $lists;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
$query = PrescriptionOrder::where($this->searchWhere)->whereNull('delete_time');
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
$diagIds = Diagnosis::where('assistant_id', $this->adminId)->whereNull('delete_time')->column('id');
|
||||
$query->where(function ($q) use ($diagIds) {
|
||||
$q->where('creator_id', $this->adminId);
|
||||
if ($diagIds !== []) {
|
||||
$q->whereOr('diagnosis_id', 'in', $diagIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (int) $query->count();
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,83 @@ use think\facade\Log;
|
||||
*/
|
||||
class LoginLogic extends BaseLogic
|
||||
{
|
||||
/** 非 root 未绑定企微时接口返回,与 axios 约定一致 */
|
||||
public const CODE_NEED_BIND_WORK_WECHAT = 10;
|
||||
|
||||
/**
|
||||
* 企业微信网页授权 / 扫码绑定所需配置是否齐全
|
||||
*/
|
||||
public static function isWorkWechatOAuthConfigured(): bool
|
||||
{
|
||||
$corpId = (string) env('work_wechat.corp_id', '');
|
||||
$secret = (string) env('work_wechat.secret', '');
|
||||
$agentId = (string) env('work_wechat.agent_id', '');
|
||||
|
||||
return $corpId !== '' && $secret !== '' && $agentId !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* .env 是否开启「非 root 须绑定企微」。
|
||||
* 推荐在 [work_wechat] 下写 FORCE_BIND_LOGIN=true;勿在节内写 WORK_WECHAT_FORCE_BIND_LOGIN(会变成双前缀键读不到)。
|
||||
*/
|
||||
public static function isForceBindWorkWechatFromEnv(): bool
|
||||
{
|
||||
$candidates = [
|
||||
env('WORK_WECHAT_FORCE_BIND_LOGIN', false),
|
||||
env('work_wechat.force_bind_login', false),
|
||||
env('work_wechat.work_wechat_force_bind_login', false),
|
||||
];
|
||||
$v = false;
|
||||
foreach ($candidates as $c) {
|
||||
if ($c !== false && $c !== null && $c !== '') {
|
||||
$v = $c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_bool($v)) {
|
||||
return $v;
|
||||
}
|
||||
$v = strtolower(trim((string) $v));
|
||||
|
||||
return in_array($v, ['1', 'true', 'yes', 'on'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* .env 开启强制绑定 + 企微 OAuth 已配置 + 非 root + 未绑定 work_wechat_userid
|
||||
*
|
||||
* @param array{root?:int|string,work_wechat_userid?:string} $adminInfo
|
||||
*/
|
||||
public static function adminMustBindWorkWechat(array $adminInfo): bool
|
||||
{
|
||||
if (!self::isForceBindWorkWechatFromEnv()) {
|
||||
return false;
|
||||
}
|
||||
if (!self::isWorkWechatOAuthConfigured()) {
|
||||
return false;
|
||||
}
|
||||
if ((int) ($adminInfo['root'] ?? 0) === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return trim((string) ($adminInfo['work_wechat_userid'] ?? '')) === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启「须绑定企微」时,这些 action 仍须放行(与 $request->action() 比较,不区分大小写)。
|
||||
* 路由/网关若把 action 变成全小写,严格 in_array('bindWorkWechat') 会失败,导致绑定接口被误判为 code=10,扫码页反复刷新。
|
||||
*/
|
||||
public static function isWorkWechatBindExemptActionName(string $action): bool
|
||||
{
|
||||
$a = strtolower(trim($action));
|
||||
|
||||
return in_array($a, [
|
||||
'bindworkwechat',
|
||||
'unbindworkwechat',
|
||||
'myself',
|
||||
'logout',
|
||||
], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 管理员账号登录
|
||||
* @param $params
|
||||
@@ -55,15 +132,29 @@ class LoginLogic extends BaseLogic
|
||||
//返回登录信息
|
||||
$avatar = $admin->avatar ? $admin->avatar : Config::get('project.default_image.admin_avatar');
|
||||
$avatar = FileService::getFileUrl($avatar);
|
||||
return [
|
||||
$row = [
|
||||
'name' => $adminInfo['name'],
|
||||
'avatar' => $avatar,
|
||||
'role_name' => $adminInfo['role_name'],
|
||||
'token' => $adminInfo['token'],
|
||||
'is_paw' => $admin->is_paw ?? 1, // 0=需要修改密码,1=正常
|
||||
];
|
||||
$row['need_bind_work_wechat'] = self::adminMustBindWorkWechat([
|
||||
'root' => (int) ($admin->root ?? 0),
|
||||
'work_wechat_userid' => (string) ($admin->work_wechat_userid ?? ''),
|
||||
]);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 auth/getuserinfo 响应解析企业成员 userid。
|
||||
* 非通讯录成员时接口可能只返回 openid / external_userid,无 userid。
|
||||
*/
|
||||
public static function workWechatUserIdFromAuthResponse(array $response): string
|
||||
{
|
||||
return trim((string) ($response['userid'] ?? $response['UserId'] ?? ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 企业微信授权登录
|
||||
@@ -98,9 +189,14 @@ class LoginLogic extends BaseLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
$wxUserId = $response['userid'] ?? '';
|
||||
if (empty($wxUserId)) {
|
||||
self::setError('未获取到企业微信用户身份,可能是外部联系人');
|
||||
$wxUserId = self::workWechatUserIdFromAuthResponse($response);
|
||||
if ($wxUserId === '') {
|
||||
$hasOpenId = trim((string) ($response['openid'] ?? $response['OpenId'] ?? '')) !== '';
|
||||
self::setError(
|
||||
$hasOpenId
|
||||
? '当前身份非企业通讯录成员(或未同步到通讯录),无法用此账号登录后台,请使用企业内成员账号或联系管理员将你加入通讯录'
|
||||
: '未获取到企业微信成员 userid,请检查自建应用 Secret、可信域名是否与当前扫码应用一致'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -135,6 +231,8 @@ class LoginLogic extends BaseLogic
|
||||
'role_name' => $adminInfo['role_name'],
|
||||
'token' => $adminInfo['token'],
|
||||
'is_paw' => $admin->is_paw ?? 1, // 0=需要修改密码,1=正常
|
||||
// 企微扫码登录即已绑定 userid
|
||||
'need_bind_work_wechat' => false,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
namespace app\adminapi\logic\auth;
|
||||
|
||||
use app\adminapi\logic\LoginLogic;
|
||||
use app\common\cache\AdminAuthCache;
|
||||
use app\common\enum\YesNoEnum;
|
||||
use app\common\logic\BaseLogic;
|
||||
@@ -314,6 +315,11 @@ class AdminLogic extends BaseLogic
|
||||
$authRoleIds = AdminRole::where('admin_id', $params['id'])->column('role_id');
|
||||
$admin['role_ids'] = array_values(array_map('intval', $authRoleIds));
|
||||
|
||||
$admin['need_bind_work_wechat'] = LoginLogic::adminMustBindWorkWechat([
|
||||
'root' => (int) ($admin['root'] ?? 0),
|
||||
'work_wechat_userid' => (string) ($admin['work_wechat_userid'] ?? ''),
|
||||
]);
|
||||
|
||||
$result['user'] = $admin;
|
||||
// 当前管理员角色拥有的菜单
|
||||
$result['menu'] = MenuLogic::getMenuByAdminId($params['id']);
|
||||
|
||||
@@ -7,6 +7,9 @@ namespace app\adminapi\logic\order;
|
||||
use app\common\model\Order;
|
||||
use app\common\model\OrderDetail;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||
use app\common\service\wechat\WechatWorkExternalPayService;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
@@ -73,7 +76,7 @@ class OrderLogic
|
||||
|
||||
/**
|
||||
* @notes 从企业微信对外收款账单同步订单(员工直接在企业微信发起收款,未经过后台创建)
|
||||
* 拉取 get_bill_list 接口的已支付记录,创建或更新本地订单
|
||||
* 拉取 get_bill_list:trade_state 1=已完成(已支付) 3=已完成有退款;会创建订单,并在状态变化时更新(如已支付→已退款)
|
||||
* @param int $beginTime 开始时间戳(秒)
|
||||
* @param int $endTime 结束时间戳(秒)
|
||||
* @return array ['created' => int, 'updated' => int, 'skipped' => int, 'errors' => string[]]
|
||||
@@ -108,10 +111,13 @@ class OrderLogic
|
||||
|
||||
foreach ($billList as $bill) {
|
||||
$tradeState = (int)($bill['trade_state'] ?? 0);
|
||||
// 1:已完成(已支付) 3:已完成有退款 — 见企业微信 get_bill_list 文档
|
||||
if (!in_array($tradeState, [1, 3], true)) {
|
||||
$result['skipped']++;
|
||||
continue;
|
||||
}
|
||||
$targetStatus = $tradeState === 3 ? 4 : 2; // 4=已退款 2=已支付
|
||||
|
||||
$orderNo = (string)($bill['out_trade_no'] ?? $bill['trade_no'] ?? '');
|
||||
$totalFee = (int)($bill['total_fee'] ?? $bill['total_amount'] ?? 0);
|
||||
$tradeNo = (string)($bill['transaction_id'] ?? $bill['trade_no'] ?? '');
|
||||
@@ -134,34 +140,76 @@ class OrderLogic
|
||||
}
|
||||
|
||||
$payerExternalUserid = (string)($bill['external_userid'] ?? '');
|
||||
$paymentTimeStr = $payTime
|
||||
? (is_numeric($payTime) ? date('Y-m-d H:i:s', (int)$payTime) : (string)$payTime)
|
||||
: date('Y-m-d H:i:s');
|
||||
|
||||
$order = Order::where('order_no', $orderNo)->find();
|
||||
if ($order) {
|
||||
if ($order->status == 1) {
|
||||
$order->status = 2;
|
||||
$order->payment_method = 'wechat';
|
||||
$order->payment_time = $payTime ? (is_numeric($payTime) ? date('Y-m-d H:i:s', (int)$payTime) : $payTime) : date('Y-m-d H:i:s');
|
||||
$needSave = false;
|
||||
$currentStatus = (int)$order->status;
|
||||
|
||||
if ($currentStatus !== $targetStatus) {
|
||||
// 待支付:随账单变为已支付或已退款(含未同步到「已支付」即发生退款)
|
||||
if ($currentStatus === 1) {
|
||||
$order->status = $targetStatus;
|
||||
$needSave = true;
|
||||
} elseif ($currentStatus === 2 && $targetStatus === 4) {
|
||||
$order->status = 4;
|
||||
$needSave = true;
|
||||
} elseif ($currentStatus === 4 && $targetStatus === 2) {
|
||||
// 账单从「有退款」变回「已完成」等异常纠偏
|
||||
$order->status = 2;
|
||||
$needSave = true;
|
||||
}
|
||||
// 已取消(3) 不自动改支付状态,避免覆盖后台取消
|
||||
}
|
||||
|
||||
if ($currentStatus === 1 || $targetStatus === 2) {
|
||||
if ($order->payment_method !== 'wechat') {
|
||||
$order->payment_method = 'wechat';
|
||||
$needSave = true;
|
||||
}
|
||||
if ($paymentTimeStr !== '' && (string)$order->payment_time !== $paymentTimeStr) {
|
||||
$order->payment_time = $paymentTimeStr;
|
||||
$needSave = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($tradeNo !== '' && (string)$order->trade_no !== $tradeNo) {
|
||||
$order->trade_no = $tradeNo;
|
||||
$needSave = true;
|
||||
}
|
||||
|
||||
if (abs((float)$order->amount - $amount) > 0.000001) {
|
||||
$order->amount = $amount;
|
||||
$needSave = true;
|
||||
}
|
||||
|
||||
$defaultCreatorIdInt = (int)$defaultCreatorId;
|
||||
if ($billPayeeUserid && $creatorId !== $defaultCreatorIdInt && (int)$order->creator_id === $defaultCreatorIdInt) {
|
||||
$order->payee_userid = $billPayeeUserid;
|
||||
$order->payer_external_userid = $payerExternalUserid;
|
||||
$order->creator_id = $creatorId;
|
||||
$order->order_type = $orderType;
|
||||
$needSave = true;
|
||||
} elseif ($billPayeeUserid !== '' && (string)$order->payee_userid !== $billPayeeUserid) {
|
||||
$order->payee_userid = $billPayeeUserid;
|
||||
$needSave = true;
|
||||
}
|
||||
if ($payerExternalUserid !== '' && (string)$order->payer_external_userid !== $payerExternalUserid) {
|
||||
$order->payer_external_userid = $payerExternalUserid;
|
||||
$needSave = true;
|
||||
}
|
||||
|
||||
if ($amount == 5.00 && (int)$order->order_type !== 1) {
|
||||
$order->order_type = 1;
|
||||
$needSave = true;
|
||||
}
|
||||
|
||||
if ($needSave) {
|
||||
$order->save();
|
||||
$result['updated']++;
|
||||
} else {
|
||||
$needSave = false;
|
||||
if ($billPayeeUserid && $creatorId !== $defaultCreatorId && (int)$order->creator_id === $defaultCreatorId) {
|
||||
$order->payee_userid = $billPayeeUserid;
|
||||
$order->payer_external_userid = $payerExternalUserid;
|
||||
$order->creator_id = $creatorId;
|
||||
$needSave = true;
|
||||
}
|
||||
if ($amount == 5.00 && (int)$order->order_type !== 1) {
|
||||
$order->order_type = 1;
|
||||
$needSave = true;
|
||||
}
|
||||
if ($needSave) {
|
||||
$order->save();
|
||||
}
|
||||
$result['skipped']++;
|
||||
}
|
||||
} else {
|
||||
@@ -172,11 +220,18 @@ class OrderLogic
|
||||
$order->creator_id = $creatorId;
|
||||
$order->order_type = $orderType;
|
||||
$order->amount = $amount;
|
||||
$order->status = 2;
|
||||
$order->status = $targetStatus;
|
||||
$order->payment_method = 'wechat';
|
||||
$order->payment_time = $payTime ? (is_numeric($payTime) ? date('Y-m-d H:i:s', (int)$payTime) : $payTime) : date('Y-m-d H:i:s');
|
||||
$order->payment_time = $paymentTimeStr;
|
||||
$order->trade_no = $tradeNo;
|
||||
$order->remark = '企业微信直接收款同步,待关联患者';
|
||||
$remark = '企业微信直接收款同步,待关联患者';
|
||||
if ($tradeState === 3) {
|
||||
$refundCent = (int)($bill['total_refund_fee'] ?? 0);
|
||||
if ($refundCent > 0) {
|
||||
$remark .= '(账单含退款' . round($refundCent / 100, 2) . '元)';
|
||||
}
|
||||
}
|
||||
$order->remark = $remark;
|
||||
$order->payee_userid = $billPayeeUserid;
|
||||
$order->payer_external_userid = $payerExternalUserid;
|
||||
$order->save();
|
||||
@@ -652,15 +707,17 @@ class OrderLogic
|
||||
|
||||
/**
|
||||
* @notes 订单统计(按订单类型或退款)
|
||||
* @param array $params order_type(0退款,1挂号费,2问诊费,3药品费用,4首付,5尾款,6其他), days(0今天,7,30)
|
||||
* @param array $params order_type(-1全部已支付类型合计,0退款,1挂号费,2问诊费,3药品费用,4首付,5尾款,6其他), days(0今天,7,30)
|
||||
* @return array
|
||||
*/
|
||||
public static function orderStats(array $params = [])
|
||||
{
|
||||
$orderType = isset($params['order_type']) ? (int)$params['order_type'] : 1;
|
||||
if (!array_key_exists($orderType, self::$orderTypeNames)) {
|
||||
$allPaidOrderTypes = [1, 2, 3, 4, 5, 6];
|
||||
$orderType = array_key_exists('order_type', $params) ? (int) $params['order_type'] : 1;
|
||||
if ($orderType !== -1 && $orderType !== 0 && !array_key_exists($orderType, self::$orderTypeNames)) {
|
||||
$orderType = 1;
|
||||
}
|
||||
$orderTypeName = $orderType === -1 ? '全部(已支付)' : self::$orderTypeNames[$orderType];
|
||||
$days = isset($params['days']) ? (int)$params['days'] : 7;
|
||||
|
||||
$endTime = !empty($params['end_time']) ? strtotime($params['end_time']) : time();
|
||||
@@ -682,6 +739,8 @@ class OrderLogic
|
||||
->whereNull('delete_time');
|
||||
if ($orderType === 0) {
|
||||
$query->where('status', 4);
|
||||
} elseif ($orderType === -1) {
|
||||
$query->whereIn('order_type', $allPaidOrderTypes)->where('status', 2);
|
||||
} else {
|
||||
$query->where('order_type', $orderType)->where('status', 2);
|
||||
}
|
||||
@@ -696,7 +755,7 @@ class OrderLogic
|
||||
if (empty($creatorIds)) {
|
||||
return [
|
||||
'order_type' => $orderType,
|
||||
'order_type_name' => self::$orderTypeNames[$orderType],
|
||||
'order_type_name' => $orderTypeName,
|
||||
'date_range' => [date('Y-m-d', $startTime), date('Y-m-d', $endTime)],
|
||||
'today_total' => 0,
|
||||
'today_amount' => '0.00',
|
||||
@@ -738,6 +797,8 @@ class OrderLogic
|
||||
->whereNull('delete_time');
|
||||
if ($orderType === 0) {
|
||||
$todayQuery->where('status', 4);
|
||||
} elseif ($orderType === -1) {
|
||||
$todayQuery->whereIn('order_type', $allPaidOrderTypes)->where('status', 2);
|
||||
} else {
|
||||
$todayQuery->where('order_type', $orderType)->where('status', 2);
|
||||
}
|
||||
@@ -835,7 +896,7 @@ class OrderLogic
|
||||
|
||||
return [
|
||||
'order_type' => $orderType,
|
||||
'order_type_name' => self::$orderTypeNames[$orderType],
|
||||
'order_type_name' => $orderTypeName,
|
||||
'date_range' => [date('Y-m-d', $startTime), date('Y-m-d', $endTime)],
|
||||
'today_total' => $todayTotal,
|
||||
'today_amount' => number_format($todayAmount, 2, '.', ''),
|
||||
@@ -848,4 +909,129 @@ class OrderLogic
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 与订单列表一致:超管或主管角色可见他人创建的订单
|
||||
*/
|
||||
public static function isOrderListSupervisor(int $adminId, array $adminInfo): bool
|
||||
{
|
||||
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
|
||||
return true;
|
||||
}
|
||||
$supervisorRoles = [0, 3];
|
||||
$myRoles = array_map('intval', $adminInfo['role_id'] ?? []);
|
||||
|
||||
return count(array_intersect($myRoles, $supervisorRoles)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 某诊单下已支付支付单,供关联业务订单多选(主管/诊单医助看该诊单全部;否则仅本人创建)
|
||||
* 已占用(关联到未撤回/未取消的业务订单)的支付单会排除;编辑某业务订单时传 $exceptPrescriptionOrderId 以保留当前单已选中的项
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function listPaidOrdersForDiagnosis(int $diagnosisId, int $adminId, array $adminInfo, ?int $exceptPrescriptionOrderId = null): array
|
||||
{
|
||||
if ($diagnosisId <= 0) {
|
||||
return [];
|
||||
}
|
||||
$exists = Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->count() > 0;
|
||||
if (!$exists) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$q = Order::where('patient_id', $diagnosisId)
|
||||
->where('status', 2)
|
||||
->whereNull('delete_time');
|
||||
|
||||
if (!self::isOrderListSupervisor($adminId, $adminInfo)) {
|
||||
$assistantId = (int) Diagnosis::where('id', $diagnosisId)->value('assistant_id');
|
||||
if ($assistantId !== $adminId) {
|
||||
$q->where('creator_id', $adminId);
|
||||
}
|
||||
}
|
||||
|
||||
$rows = $q
|
||||
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark'])
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$activePoIds = PrescriptionOrder::whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->column('id');
|
||||
$busyPayIds = [];
|
||||
if ($activePoIds !== []) {
|
||||
$busyPayIds = PrescriptionOrderPayOrder::whereIn('prescription_order_id', $activePoIds)
|
||||
->column('pay_order_id');
|
||||
$busyPayIds = array_unique(array_map('intval', $busyPayIds));
|
||||
}
|
||||
$whiteList = [];
|
||||
if ($exceptPrescriptionOrderId !== null && $exceptPrescriptionOrderId > 0) {
|
||||
$whiteList = array_map(
|
||||
'intval',
|
||||
PrescriptionOrderPayOrder::where('prescription_order_id', $exceptPrescriptionOrderId)->column('pay_order_id')
|
||||
);
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($rows as $row) {
|
||||
$oid = (int) ($row['id'] ?? 0);
|
||||
if ($oid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$busy = in_array($oid, $busyPayIds, true);
|
||||
$allowed = in_array($oid, $whiteList, true);
|
||||
if ($busy && ! $allowed) {
|
||||
continue;
|
||||
}
|
||||
$out[] = $row;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验支付单均可关联到指定诊单(已支付、归属与权限)
|
||||
*
|
||||
* @param int[] $ids zyt_order.id
|
||||
*/
|
||||
public static function assertPayOrdersLinkable(array $ids, int $diagnosisId, int $adminId, array $adminInfo): ?string
|
||||
{
|
||||
$ids = array_values(array_unique(array_filter(array_map('intval', $ids), static fn (int $v): bool => $v > 0)));
|
||||
if ($diagnosisId <= 0) {
|
||||
return '诊单无效';
|
||||
}
|
||||
if ($ids === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$diagExists = Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->count() > 0;
|
||||
if (!$diagExists) {
|
||||
return '诊单不存在';
|
||||
}
|
||||
|
||||
$supervisor = self::isOrderListSupervisor($adminId, $adminInfo);
|
||||
$assistantId = (int) Diagnosis::where('id', $diagnosisId)->value('assistant_id');
|
||||
$isDiagAssistant = $assistantId === $adminId;
|
||||
|
||||
$orders = Order::whereIn('id', $ids)->whereNull('delete_time')->select();
|
||||
if (count($orders) !== count($ids)) {
|
||||
return '部分支付单不存在或已删除';
|
||||
}
|
||||
|
||||
foreach ($orders as $o) {
|
||||
if ((int) $o->patient_id !== $diagnosisId) {
|
||||
return '支付单与诊单不匹配';
|
||||
}
|
||||
if ((int) $o->status !== 2) {
|
||||
return '仅能关联已支付订单';
|
||||
}
|
||||
if (! $supervisor && ! $isDiagAssistant && (int) $o->creator_id !== $adminId) {
|
||||
return '无权限关联所选支付单';
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2066,7 +2066,57 @@ class DiagnosisLogic extends BaseLogic
|
||||
->order('a.id', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
|
||||
if ($assistants === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$adminIds = array_column($assistants, 'id');
|
||||
$adminDepts = \app\common\model\auth\AdminDept::whereIn('admin_id', $adminIds)
|
||||
->select()
|
||||
->toArray();
|
||||
$adminToDeptIds = [];
|
||||
foreach ($adminDepts as $ad) {
|
||||
$aid = (int) ($ad['admin_id'] ?? 0);
|
||||
if ($aid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$adminToDeptIds[$aid][] = (int) ($ad['dept_id'] ?? 0);
|
||||
}
|
||||
$allDeptIds = [];
|
||||
foreach ($adminToDeptIds as $deptIdList) {
|
||||
foreach ($deptIdList as $did) {
|
||||
if ($did > 0) {
|
||||
$allDeptIds[$did] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$allDeptIds = array_keys($allDeptIds);
|
||||
$deptNameMap = [];
|
||||
if ($allDeptIds !== []) {
|
||||
$deptNameMap = \app\common\model\dept\Dept::whereIn('id', $allDeptIds)
|
||||
->whereNull('delete_time')
|
||||
->column('name', 'id');
|
||||
}
|
||||
foreach ($assistants as &$row) {
|
||||
$aid = (int) ($row['id'] ?? 0);
|
||||
$idsForAdmin = [];
|
||||
foreach ($adminToDeptIds[$aid] ?? [] as $did) {
|
||||
if ($did > 0) {
|
||||
$idsForAdmin[] = $did;
|
||||
}
|
||||
}
|
||||
$row['dept_ids'] = array_values(array_unique($idsForAdmin));
|
||||
$names = [];
|
||||
foreach ($row['dept_ids'] as $did) {
|
||||
if (!empty($deptNameMap[$did])) {
|
||||
$names[] = (string) $deptNameMap[$did];
|
||||
}
|
||||
}
|
||||
$row['dept_names'] = $names !== [] ? implode('、', array_unique($names)) : '';
|
||||
}
|
||||
unset($row);
|
||||
|
||||
return $assistants;
|
||||
} catch (\Exception $e) {
|
||||
\think\facade\Log::error('获取医助列表失败: ' . $e->getMessage());
|
||||
@@ -2737,7 +2787,9 @@ class DiagnosisLogic extends BaseLogic
|
||||
'systolic_pressure' => !empty($params['systolic_pressure']) ? intval($params['systolic_pressure']) : null,
|
||||
'diastolic_pressure' => !empty($params['diastolic_pressure']) ? intval($params['diastolic_pressure']) : null,
|
||||
'fasting_blood_sugar' => !empty($params['fasting_blood_sugar']) ? floatval($params['fasting_blood_sugar']) : null,
|
||||
'diabetes_discovery_year' => !empty($params['diabetes_discovery_year']) ? intval($params['diabetes_discovery_year']) : null,
|
||||
'diabetes_discovery_year' => isset($params['diabetes_discovery_year'])
|
||||
? (trim((string) $params['diabetes_discovery_year']) !== '' ? trim((string) $params['diabetes_discovery_year']) : null)
|
||||
: null,
|
||||
'local_hospital_diagnosis' => $params['local_hospital_diagnosis'] ?? '',
|
||||
'local_hospital_name' => $params['local_hospital_name'] ?? '',
|
||||
'local_hospital_visit_date' => $params['local_hospital_visit_date'] ?? '',
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace app\adminapi\logic\tcm;
|
||||
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\tcm\Prescription;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\service\wechat\WechatWorkAppMessageService;
|
||||
use think\facade\Config;
|
||||
@@ -82,6 +83,11 @@ class PrescriptionLogic
|
||||
return true;
|
||||
}
|
||||
|
||||
$assistantId = is_array($row) ? (int) ($row['assistant_id'] ?? 0) : (int) ($row->assistant_id ?? 0);
|
||||
if ($assistantId > 0 && $assistantId === $adminId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$isShared = is_array($row) ? (int) ($row['is_shared'] ?? 0) : (int) $row->is_shared;
|
||||
if ($isShared === 1) {
|
||||
return true;
|
||||
@@ -187,6 +193,12 @@ class PrescriptionLogic
|
||||
$sn = self::generateSn();
|
||||
}
|
||||
|
||||
$assistantIdForRx = 0;
|
||||
if ($diagnosisIdRule > 0) {
|
||||
$diagAssistant = Diagnosis::where('id', $diagnosisIdRule)->value('assistant_id');
|
||||
$assistantIdForRx = (int) ($diagAssistant ?? 0);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'sn' => $sn,
|
||||
'prescription_name' => $params['prescription_name'] ?? '',
|
||||
@@ -228,11 +240,13 @@ class PrescriptionLogic
|
||||
'audit_by_name' => '',
|
||||
'audit_remark' => '',
|
||||
'creator_id' => $adminId,
|
||||
'assistant_id' => $assistantIdForRx,
|
||||
];
|
||||
|
||||
$prescription = new Prescription();
|
||||
$prescription->save($data);
|
||||
return (int)$prescription->id;
|
||||
|
||||
return (int) $prescription->id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,10 +261,13 @@ class PrescriptionLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
// 已通过且未作废:不可编辑(与消费者端仅「查看」一致)
|
||||
// 已通过且未作废:不可编辑;例外:业务订单「处方审核」已驳回时允许医生改方,保存后业务订单侧审核会重置为待审
|
||||
if ((int) ($prescription->audit_status ?? 1) === 1 && (int) ($prescription->void_status ?? 0) === 0) {
|
||||
self::setError('该处方已通过审核,不可编辑');
|
||||
return false;
|
||||
if (!PrescriptionOrderLogic::allowDoctorEditApprovedPrescriptionDueToBusinessReject((int) $params['id'])) {
|
||||
self::setError('该处方已通过审核,不可编辑');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 已驳回:仅当该诊单+当天+同一创建人下没有另一条「已通过且未作废」的处方时允许重新编辑(改后待审核、作废一并清除)
|
||||
@@ -300,8 +317,17 @@ class PrescriptionLogic
|
||||
|
||||
$wasVoid = (int) ($prescription->void_status ?? 0) === 1;
|
||||
|
||||
$assistantIdForRx = (int) ($prescription->assistant_id ?? 0);
|
||||
if ($newDiagnosisId > 0) {
|
||||
$diagAssistant = Diagnosis::where('id', $newDiagnosisId)->value('assistant_id');
|
||||
$assistantIdForRx = (int) ($diagAssistant ?? 0);
|
||||
} else {
|
||||
$assistantIdForRx = 0;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'diagnosis_id' => $newDiagnosisId,
|
||||
'assistant_id' => $assistantIdForRx,
|
||||
'prescription_name' => $params['prescription_name'] ?? $prescription->prescription_name,
|
||||
'prescription_type' => $params['prescription_type'] ?? $prescription->prescription_type,
|
||||
'patient_name' => $params['patient_name'] ?? $prescription->patient_name,
|
||||
@@ -344,6 +370,8 @@ class PrescriptionLogic
|
||||
}
|
||||
|
||||
$prescription->save($data);
|
||||
PrescriptionOrderLogic::onConsumerPrescriptionSaved((int) $params['id']);
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
@@ -395,6 +423,15 @@ class PrescriptionLogic
|
||||
$arr['gender_desc'] = $arr['gender'] == 1 ? '男' : '女';
|
||||
$arr['visible_role_ids'] = self::visibleRoleIdsToArray($arr['visible_role_ids'] ?? '');
|
||||
|
||||
$bizPo = PrescriptionOrder::where('prescription_id', $id)
|
||||
->where('prescription_audit_status', 2)
|
||||
->whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
$arr['business_prescription_audit_rejected'] = $bizPo ? 1 : 0;
|
||||
$arr['business_prescription_audit_remark'] = $bizPo ? (string) ($bizPo->prescription_audit_remark ?? '') : '';
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,780 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\logic\tcm;
|
||||
|
||||
use app\adminapi\logic\order\OrderLogic;
|
||||
use app\common\model\Order;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||
use app\common\service\ExpressTrackService;
|
||||
use think\facade\Config;
|
||||
|
||||
class PrescriptionOrderLogic
|
||||
{
|
||||
private static string $error = '';
|
||||
|
||||
public static function setError(string $msg): void
|
||||
{
|
||||
self::$error = $msg;
|
||||
}
|
||||
|
||||
public static function getError(): string
|
||||
{
|
||||
return self::$error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $allowRoleIds
|
||||
*/
|
||||
private static function roleIntersect(array $adminInfo, array $allowRoleIds): bool
|
||||
{
|
||||
$myRoles = array_map('intval', $adminInfo['role_id'] ?? []);
|
||||
$allow = array_map('intval', $allowRoleIds);
|
||||
|
||||
return count(array_intersect($myRoles, $allow)) > 0;
|
||||
}
|
||||
|
||||
/** 与 order 列表一致:超管或 order_edit_all_roles 可见全部业务订单 */
|
||||
public static function canSeeAllPrescriptionOrders(array $adminInfo): bool
|
||||
{
|
||||
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
|
||||
return true;
|
||||
}
|
||||
$roles = Config::get('project.order_edit_all_roles', [0, 3]);
|
||||
|
||||
return self::roleIntersect($adminInfo, is_array($roles) ? $roles : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PrescriptionOrder $row
|
||||
*/
|
||||
public static function canAccessOrder($row, int $adminId, array $adminInfo): bool
|
||||
{
|
||||
if (self::canSeeAllPrescriptionOrders($adminInfo)) {
|
||||
return true;
|
||||
}
|
||||
if ((int) $row->creator_id === $adminId) {
|
||||
return true;
|
||||
}
|
||||
$aid = (int) Diagnosis::where('id', (int) $row->diagnosis_id)->whereNull('delete_time')->value('assistant_id');
|
||||
|
||||
return $aid === $adminId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PrescriptionOrder $row
|
||||
*/
|
||||
public static function canWithdrawOrder($row, int $adminId, array $adminInfo): bool
|
||||
{
|
||||
return self::canAccessOrder($row, $adminId, $adminInfo);
|
||||
}
|
||||
|
||||
public static function canViewInternalCost(array $adminInfo): bool
|
||||
{
|
||||
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
|
||||
return true;
|
||||
}
|
||||
$allow = Config::get('project.prescription_order_finance_roles', [0, 3]);
|
||||
$allow = array_map('intval', is_array($allow) ? $allow : []);
|
||||
$myRoles = array_map('intval', $adminInfo['role_id'] ?? []);
|
||||
|
||||
return count(array_intersect($myRoles, $allow)) > 0;
|
||||
}
|
||||
|
||||
public static function canAuditPrescriptionOrder(array $adminInfo): bool
|
||||
{
|
||||
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
|
||||
return true;
|
||||
}
|
||||
$allow = Config::get('project.prescription_audit_roles', [0, 3, 6]);
|
||||
|
||||
return self::roleIntersect($adminInfo, is_array($allow) ? $allow : []);
|
||||
}
|
||||
|
||||
public static function canAuditPaymentSlipOrder(array $adminInfo): bool
|
||||
{
|
||||
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
|
||||
return true;
|
||||
}
|
||||
$allow = Config::get('project.prescription_order_payment_audit_roles', [0, 3]);
|
||||
|
||||
return self::roleIntersect($adminInfo, is_array($allow) ? $allow : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $row
|
||||
*/
|
||||
public static function maskInternalCostIfNeeded(array &$row, array $adminInfo): void
|
||||
{
|
||||
if (!self::canViewInternalCost($adminInfo)) {
|
||||
unset($row['internal_cost']);
|
||||
}
|
||||
}
|
||||
|
||||
public static function generateOrderNo(): string
|
||||
{
|
||||
return 'PO' . date('YmdHis') . mt_rand(100000, 999999);
|
||||
}
|
||||
|
||||
private static function normalizeExpressCompany($raw): string
|
||||
{
|
||||
$ec = strtolower(trim((string) ($raw ?? '')));
|
||||
if ($ec === '') {
|
||||
return 'auto';
|
||||
}
|
||||
if (!in_array($ec, ['sf', 'jd', 'jt', 'jtexpress', 'auto'], true)) {
|
||||
return 'auto';
|
||||
}
|
||||
// 统一 jtexpress 为 jt
|
||||
if ($ec === 'jtexpress') {
|
||||
return 'jt';
|
||||
}
|
||||
|
||||
return $ec;
|
||||
}
|
||||
|
||||
/** 业务订单「处方审核」驳回后,允许医生继续编辑已通过的消费者处方 */
|
||||
public static function allowDoctorEditApprovedPrescriptionDueToBusinessReject(int $prescriptionId): bool
|
||||
{
|
||||
return PrescriptionOrder::where('prescription_id', $prescriptionId)
|
||||
->where('prescription_audit_status', 2)
|
||||
->whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 医生保存消费者处方后:重置关联业务订单的处方/支付单审核为待审(因处方内容已变)
|
||||
*/
|
||||
public static function onConsumerPrescriptionSaved(int $prescriptionId): void
|
||||
{
|
||||
$rows = PrescriptionOrder::where('prescription_id', $prescriptionId)
|
||||
->where('prescription_audit_status', 2)
|
||||
->whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->select();
|
||||
foreach ($rows as $order) {
|
||||
$order->prescription_audit_status = 0;
|
||||
$order->prescription_audit_remark = '';
|
||||
$order->payment_slip_audit_status = 0;
|
||||
$order->payment_slip_audit_remark = '';
|
||||
self::syncFulfillmentStatus($order);
|
||||
$order->save();
|
||||
}
|
||||
}
|
||||
|
||||
private static function syncFulfillmentStatus(PrescriptionOrder $order): void
|
||||
{
|
||||
$fs = (int) $order->fulfillment_status;
|
||||
if ($fs === 3 || $fs === 4) {
|
||||
return;
|
||||
}
|
||||
$pa = (int) $order->prescription_audit_status;
|
||||
$pay = (int) $order->payment_slip_audit_status;
|
||||
if ($pa === 1 && $pay === 1) {
|
||||
$order->fulfillment_status = 2;
|
||||
} elseif ($pa === 2 || $pay === 2) {
|
||||
$order->fulfillment_status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $raw
|
||||
* @return int[]
|
||||
*/
|
||||
private static function normalizePayOrderIds($raw): array
|
||||
{
|
||||
if (!is_array($raw)) {
|
||||
return [];
|
||||
}
|
||||
$ids = array_map('intval', $raw);
|
||||
|
||||
return array_values(array_unique(array_filter($ids, static fn (int $v): bool => $v > 0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除业务订单与支付单的关联(撤回/驳回后支付单可再次被选用)
|
||||
*/
|
||||
private static function clearPayOrderLinks(PrescriptionOrder $order): void
|
||||
{
|
||||
PrescriptionOrderPayOrder::where('prescription_order_id', (int) $order->id)->delete();
|
||||
$order->linked_pay_order_id = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付单不可同时关联多条「有效」业务订单(未删除且未撤回/取消);$exceptPrescriptionOrderId 为当前编辑单 ID 时跳过自检
|
||||
*
|
||||
* @param int[] $payOrderIds
|
||||
*/
|
||||
private static function assertPayOrdersExclusive(array $payOrderIds, ?int $exceptPrescriptionOrderId): ?string
|
||||
{
|
||||
$ids = array_values(array_unique(array_filter(array_map('intval', $payOrderIds), static fn (int $v): bool => $v > 0)));
|
||||
if ($ids === []) {
|
||||
return null;
|
||||
}
|
||||
$activePoIds = PrescriptionOrder::whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->column('id');
|
||||
if ($activePoIds === []) {
|
||||
return null;
|
||||
}
|
||||
$activeSet = array_fill_keys(array_map('intval', $activePoIds), true);
|
||||
$links = PrescriptionOrderPayOrder::whereIn('pay_order_id', $ids)->select();
|
||||
foreach ($links as $link) {
|
||||
$poId = (int) $link->prescription_order_id;
|
||||
if ($exceptPrescriptionOrderId !== null && $poId === $exceptPrescriptionOrderId) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($activeSet[$poId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return '支付单 #' . (int) $link->pay_order_id . ' 已关联其他有效业务订单,不可重复关联';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $payOrderIds
|
||||
*/
|
||||
private static function replacePayOrderLinks(int $prescriptionOrderId, array $payOrderIds): void
|
||||
{
|
||||
PrescriptionOrderPayOrder::where('prescription_order_id', $prescriptionOrderId)->delete();
|
||||
$t = time();
|
||||
foreach ($payOrderIds as $pid) {
|
||||
$link = new PrescriptionOrderPayOrder();
|
||||
$link->prescription_order_id = $prescriptionOrderId;
|
||||
$link->pay_order_id = $pid;
|
||||
$link->create_time = $t;
|
||||
$link->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
private static function linkedPayOrderIdList(int $prescriptionOrderId): array
|
||||
{
|
||||
return array_map(
|
||||
'intval',
|
||||
PrescriptionOrderPayOrder::where('prescription_order_id', $prescriptionOrderId)->order('id', 'asc')->column('pay_order_id')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private static function linkedPayOrdersPayload(array $ids): array
|
||||
{
|
||||
if ($ids === []) {
|
||||
return [];
|
||||
}
|
||||
$rows = Order::whereIn('id', $ids)->whereNull('delete_time')
|
||||
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark'])
|
||||
->order('id', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $arr
|
||||
*/
|
||||
private static function attachLinkedPayOrders(array &$arr): void
|
||||
{
|
||||
$id = (int) ($arr['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
$arr['pay_order_ids'] = [];
|
||||
$arr['linked_pay_orders'] = [];
|
||||
|
||||
return;
|
||||
}
|
||||
$ids = self::linkedPayOrderIdList($id);
|
||||
$arr['pay_order_ids'] = $ids;
|
||||
$arr['linked_pay_orders'] = self::linkedPayOrdersPayload($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $params
|
||||
* @return array<string,mixed>|false
|
||||
*/
|
||||
public static function create(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
$rxId = (int) $params['prescription_id'];
|
||||
$diagId = (int) $params['diagnosis_id'];
|
||||
$payOrderIds = self::normalizePayOrderIds($params['pay_order_ids'] ?? []);
|
||||
|
||||
$rx = PrescriptionLogic::detail($rxId, $adminId, $adminInfo);
|
||||
if ($rx === null) {
|
||||
$err = PrescriptionLogic::getError();
|
||||
|
||||
self::$error = $err !== '' ? $err : '处方不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
if ((int) ($rx['diagnosis_id'] ?? 0) !== $diagId) {
|
||||
self::$error = '诊单与处方不匹配';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PrescriptionOrder::where('prescription_id', $rxId)->whereNull('delete_time')->where('fulfillment_status', '<>', 4)->count() > 0) {
|
||||
self::$error = '该处方已存在有效业务订单(未撤回前不可重复创建)';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$diag = Diagnosis::where('id', $diagId)->whereNull('delete_time')->find();
|
||||
if (!$diag) {
|
||||
self::$error = '诊单不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($payOrderIds !== []) {
|
||||
$linkErr = OrderLogic::assertPayOrdersLinkable($payOrderIds, $diagId, $adminId, $adminInfo);
|
||||
if ($linkErr !== null) {
|
||||
self::$error = $linkErr;
|
||||
|
||||
return false;
|
||||
}
|
||||
$exErr = self::assertPayOrdersExclusive($payOrderIds, null);
|
||||
if ($exErr !== null) {
|
||||
self::$error = $exErr;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$internalCost = null;
|
||||
if (isset($params['internal_cost']) && $params['internal_cost'] !== '' && $params['internal_cost'] !== null) {
|
||||
if (self::canViewInternalCost($adminInfo)) {
|
||||
$internalCost = round((float) $params['internal_cost'], 2);
|
||||
}
|
||||
}
|
||||
|
||||
$medDays = $params['medication_days'] ?? null;
|
||||
$medDays = $medDays === '' || $medDays === null ? null : (int) $medDays;
|
||||
|
||||
$order = new PrescriptionOrder();
|
||||
$order->order_no = self::generateOrderNo();
|
||||
$order->prescription_id = $rxId;
|
||||
$order->diagnosis_id = $diagId;
|
||||
$order->creator_id = $adminId;
|
||||
$order->recipient_name = (string) $params['recipient_name'];
|
||||
$order->recipient_phone = (string) $params['recipient_phone'];
|
||||
$order->shipping_address = (string) $params['shipping_address'];
|
||||
$order->is_follow_up = (int) ($params['is_follow_up'] ?? 0) === 1 ? 1 : 0;
|
||||
$order->medication_days = $medDays > 0 ? $medDays : null;
|
||||
$order->prev_staff = (string) ($params['prev_staff'] ?? '');
|
||||
$order->service_channel = (string) ($params['service_channel'] ?? '');
|
||||
$order->service_package = (string) ($params['service_package'] ?? '');
|
||||
$order->tracking_number = (string) ($params['tracking_number'] ?? '');
|
||||
$order->express_company = self::normalizeExpressCompany($params['express_company'] ?? 'auto');
|
||||
$order->fee_type = (int) $params['fee_type'];
|
||||
$order->amount = round((float) $params['amount'], 2);
|
||||
$order->internal_cost = $internalCost;
|
||||
$order->remark_extra = (string) ($params['remark_extra'] ?? '');
|
||||
$order->linked_pay_order_id = $payOrderIds !== [] ? $payOrderIds[0] : null;
|
||||
$order->prescription_audit_status = 0;
|
||||
$order->prescription_audit_remark = '';
|
||||
$order->payment_slip_audit_status = 0;
|
||||
$order->payment_slip_audit_remark = '';
|
||||
$order->fulfillment_status = 1;
|
||||
|
||||
try {
|
||||
$order->save();
|
||||
} catch (\Throwable $e) {
|
||||
self::$error = $e->getMessage();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($payOrderIds !== []) {
|
||||
self::replacePayOrderLinks((int) $order->id, $payOrderIds);
|
||||
}
|
||||
|
||||
$out = $order->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public static function detail(int $id, int $adminId, array $adminInfo): ?array
|
||||
{
|
||||
self::$error = '';
|
||||
$row = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$row) {
|
||||
self::$error = '订单不存在';
|
||||
|
||||
return null;
|
||||
}
|
||||
if (!self::canAccessOrder($row, $adminId, $adminInfo)) {
|
||||
self::$error = '无权限查看';
|
||||
|
||||
return null;
|
||||
}
|
||||
$arr = $row->toArray();
|
||||
self::maskInternalCostIfNeeded($arr, $adminInfo);
|
||||
self::attachLinkedPayOrders($arr);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流轨迹(顺丰/京东等,优先快递100;未配置密钥时返回官网链接)
|
||||
*
|
||||
* @return array<string,mixed>|null
|
||||
*/
|
||||
public static function logisticsTrace(int $id, string $expressCompanyOverride, int $adminId, array $adminInfo): ?array
|
||||
{
|
||||
self::$error = '';
|
||||
$row = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$row) {
|
||||
self::$error = '订单不存在';
|
||||
|
||||
return null;
|
||||
}
|
||||
if (!self::canAccessOrder($row, $adminId, $adminInfo)) {
|
||||
self::$error = '无权限查看';
|
||||
|
||||
return null;
|
||||
}
|
||||
$num = trim((string) ($row->tracking_number ?? ''));
|
||||
if ($num === '') {
|
||||
self::$error = '未填写快递单号';
|
||||
|
||||
return null;
|
||||
}
|
||||
$ec = trim($expressCompanyOverride) !== '' ? self::normalizeExpressCompany($expressCompanyOverride) : self::normalizeExpressCompany($row->express_company ?? 'auto');
|
||||
|
||||
// 优先从数据库查询物流追踪信息
|
||||
$trackingData = \app\common\service\ExpressTrackingService::getDetailByTrackingNumber($num);
|
||||
|
||||
if ($trackingData && !empty($trackingData['traces'])) {
|
||||
// 从数据库获取到数据,直接返回
|
||||
$payload = [
|
||||
'carrier' => $trackingData['express_company'],
|
||||
'carrier_label' => $trackingData['express_company_name'],
|
||||
'kuaidi_com' => $trackingData['express_company'],
|
||||
'traces' => array_map(function($trace) {
|
||||
return [
|
||||
'time' => $trace['trace_time'],
|
||||
'ftime' => $trace['trace_time'],
|
||||
'context' => $trace['trace_context'],
|
||||
'location' => $trace['location'],
|
||||
'status' => $trace['status'],
|
||||
'statusCode' => $trace['status_code'],
|
||||
];
|
||||
}, $trackingData['traces']),
|
||||
'state' => $trackingData['current_state'],
|
||||
'state_text' => $trackingData['current_state_text'],
|
||||
'source' => 'database',
|
||||
'hint' => '',
|
||||
'official_url' => '',
|
||||
'last_query_time' => date('Y-m-d H:i:s', $trackingData['last_query_time']),
|
||||
'query_count' => $trackingData['query_count'],
|
||||
];
|
||||
} else {
|
||||
// 数据库没有数据,调用快递100 API
|
||||
$payload = ExpressTrackService::query($ec, $num, (string) ($row->recipient_phone ?? ''));
|
||||
$payload['source'] = 'api';
|
||||
}
|
||||
|
||||
$payload['official_urls'] = ExpressTrackService::officialUrls($num);
|
||||
$payload['tracking_number'] = $num;
|
||||
$payload['express_company_used'] = $ec;
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $params
|
||||
* @return array<string,mixed>|false
|
||||
*/
|
||||
public static function edit(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
$id = (int) $params['id'];
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$order) {
|
||||
self::$error = '订单不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!self::canAccessOrder($order, $adminId, $adminInfo)) {
|
||||
self::$error = '无权限编辑';
|
||||
|
||||
return false;
|
||||
}
|
||||
$fs = (int) $order->fulfillment_status;
|
||||
if ($fs === 3 || $fs === 4) {
|
||||
self::$error = '已完成或已取消的订单不可编辑';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$medDays = $params['medication_days'] ?? null;
|
||||
$medDays = $medDays === '' || $medDays === null ? null : (int) $medDays;
|
||||
|
||||
$order->recipient_name = (string) $params['recipient_name'];
|
||||
$order->recipient_phone = (string) $params['recipient_phone'];
|
||||
$order->shipping_address = (string) $params['shipping_address'];
|
||||
$order->is_follow_up = (int) ($params['is_follow_up'] ?? 0) === 1 ? 1 : 0;
|
||||
$order->medication_days = $medDays > 0 ? $medDays : null;
|
||||
$order->prev_staff = (string) ($params['prev_staff'] ?? '');
|
||||
$order->service_channel = (string) ($params['service_channel'] ?? '');
|
||||
$order->service_package = (string) ($params['service_package'] ?? '');
|
||||
$order->tracking_number = (string) ($params['tracking_number'] ?? '');
|
||||
if (array_key_exists('express_company', $params)) {
|
||||
$order->express_company = self::normalizeExpressCompany($params['express_company']);
|
||||
}
|
||||
$order->fee_type = (int) $params['fee_type'];
|
||||
$order->amount = round((float) $params['amount'], 2);
|
||||
$order->remark_extra = (string) ($params['remark_extra'] ?? '');
|
||||
|
||||
$diagId = (int) $order->diagnosis_id;
|
||||
|
||||
if (array_key_exists('pay_order_ids', $params)) {
|
||||
$payOrderIds = self::normalizePayOrderIds($params['pay_order_ids']);
|
||||
$linkErr = OrderLogic::assertPayOrdersLinkable($payOrderIds, $diagId, $adminId, $adminInfo);
|
||||
if ($linkErr !== null) {
|
||||
self::$error = $linkErr;
|
||||
|
||||
return false;
|
||||
}
|
||||
$exErr = self::assertPayOrdersExclusive($payOrderIds, (int) $order->id);
|
||||
if ($exErr !== null) {
|
||||
self::$error = $exErr;
|
||||
|
||||
return false;
|
||||
}
|
||||
self::replacePayOrderLinks((int) $order->id, $payOrderIds);
|
||||
$order->linked_pay_order_id = $payOrderIds !== [] ? $payOrderIds[0] : null;
|
||||
} elseif (array_key_exists('linked_pay_order_id', $params)) {
|
||||
$lp = $params['linked_pay_order_id'];
|
||||
if ($lp === '' || $lp === null || (int) $lp <= 0) {
|
||||
self::replacePayOrderLinks((int) $order->id, []);
|
||||
$order->linked_pay_order_id = null;
|
||||
} else {
|
||||
$single = [(int) $lp];
|
||||
$linkErr = OrderLogic::assertPayOrdersLinkable($single, $diagId, $adminId, $adminInfo);
|
||||
if ($linkErr !== null) {
|
||||
self::$error = $linkErr;
|
||||
|
||||
return false;
|
||||
}
|
||||
$exErr = self::assertPayOrdersExclusive($single, (int) $order->id);
|
||||
if ($exErr !== null) {
|
||||
self::$error = $exErr;
|
||||
|
||||
return false;
|
||||
}
|
||||
self::replacePayOrderLinks((int) $order->id, $single);
|
||||
$order->linked_pay_order_id = $single[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('internal_cost', $params) && self::canViewInternalCost($adminInfo)) {
|
||||
$raw = $params['internal_cost'];
|
||||
if ($raw === '' || $raw === null) {
|
||||
$order->internal_cost = null;
|
||||
} else {
|
||||
$order->internal_cost = round((float) $raw, 2);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$order->save();
|
||||
} catch (\Throwable $e) {
|
||||
self::$error = $e->getMessage();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$out = $order->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>|false
|
||||
*/
|
||||
public static function withdraw(int $id, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$order) {
|
||||
self::$error = '订单不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!self::canWithdrawOrder($order, $adminId, $adminInfo)) {
|
||||
self::$error = '无权限撤回';
|
||||
|
||||
return false;
|
||||
}
|
||||
if ((int) $order->fulfillment_status !== 1) {
|
||||
self::$error = '仅「待双审通过」状态可撤回;双审通过后请走履约/完成流程';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$order->fulfillment_status = 4;
|
||||
self::clearPayOrderLinks($order);
|
||||
|
||||
try {
|
||||
$order->save();
|
||||
} catch (\Throwable $e) {
|
||||
self::$error = $e->getMessage();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$out = $order->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>|false
|
||||
*/
|
||||
public static function auditPrescription(int $id, string $action, string $remark, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$order) {
|
||||
self::$error = '订单不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!self::canAuditPrescriptionOrder($adminInfo)) {
|
||||
self::$error = '无处方审核权限';
|
||||
|
||||
return false;
|
||||
}
|
||||
if ((int) $order->prescription_audit_status !== 0) {
|
||||
self::$error = '当前无需处方审核';
|
||||
|
||||
return false;
|
||||
}
|
||||
$fs = (int) $order->fulfillment_status;
|
||||
if ($fs === 3 || $fs === 4) {
|
||||
self::$error = '订单已结束';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($action === 'reject' && trim($remark) === '') {
|
||||
self::$error = '驳回时请填写审核意见';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($action === 'approve') {
|
||||
$order->prescription_audit_status = 1;
|
||||
$order->prescription_audit_remark = mb_substr(trim($remark), 0, 500);
|
||||
} else {
|
||||
$order->prescription_audit_status = 2;
|
||||
$order->prescription_audit_remark = mb_substr(trim($remark), 0, 500);
|
||||
$order->payment_slip_audit_status = 0;
|
||||
$order->payment_slip_audit_remark = '';
|
||||
}
|
||||
self::syncFulfillmentStatus($order);
|
||||
if ($action === 'reject') {
|
||||
self::clearPayOrderLinks($order);
|
||||
}
|
||||
|
||||
try {
|
||||
$order->save();
|
||||
} catch (\Throwable $e) {
|
||||
self::$error = $e->getMessage();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$out = $order->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>|false
|
||||
*/
|
||||
public static function auditPaymentSlip(int $id, string $action, string $remark, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$order) {
|
||||
self::$error = '订单不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!self::canAuditPaymentSlipOrder($adminInfo)) {
|
||||
self::$error = '无支付单审核权限';
|
||||
|
||||
return false;
|
||||
}
|
||||
if ((int) $order->prescription_audit_status !== 1) {
|
||||
self::$error = '请先通过处方审核';
|
||||
|
||||
return false;
|
||||
}
|
||||
if ((int) $order->payment_slip_audit_status !== 0) {
|
||||
self::$error = '当前无需支付单审核';
|
||||
|
||||
return false;
|
||||
}
|
||||
$fs = (int) $order->fulfillment_status;
|
||||
if ($fs === 3 || $fs === 4) {
|
||||
self::$error = '订单已结束';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($action === 'reject' && trim($remark) === '') {
|
||||
self::$error = '驳回时请填写审核意见';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($action === 'approve') {
|
||||
$order->payment_slip_audit_status = 1;
|
||||
$order->payment_slip_audit_remark = mb_substr(trim($remark), 0, 500);
|
||||
} else {
|
||||
$order->payment_slip_audit_status = 2;
|
||||
$order->payment_slip_audit_remark = mb_substr(trim($remark), 0, 500);
|
||||
}
|
||||
self::syncFulfillmentStatus($order);
|
||||
if ($action === 'reject') {
|
||||
self::clearPayOrderLinks($order);
|
||||
}
|
||||
|
||||
try {
|
||||
$order->save();
|
||||
} catch (\Throwable $e) {
|
||||
self::$error = $e->getMessage();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$out = $order->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ class DiagnosisValidate extends BaseValidate
|
||||
'current_medications' => 'max:2000',
|
||||
'tongue_images' => 'array',
|
||||
'report_files' => 'array',
|
||||
'diabetes_discovery_year' => 'max:50',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
@@ -53,6 +54,7 @@ class DiagnosisValidate extends BaseValidate
|
||||
'diagnosis_type.require' => '请选择诊断类型',
|
||||
'status.in' => '状态参数错误',
|
||||
'current_medications.max' => '在用药物最多2000个字符',
|
||||
'diabetes_discovery_year.max' => '发现糖尿病患病史最多50个字符',
|
||||
];
|
||||
|
||||
public function sceneAdd()
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\validate\tcm;
|
||||
|
||||
use app\common\validate\BaseValidate;
|
||||
|
||||
class PrescriptionOrderValidate extends BaseValidate
|
||||
{
|
||||
protected $rule = [
|
||||
'id' => 'require|integer',
|
||||
'diagnosis_id' => 'require|integer|gt:0',
|
||||
'prescription_id' => 'require|integer',
|
||||
'pay_order_ids' => 'array',
|
||||
'recipient_name' => 'require|max:50',
|
||||
'recipient_phone' => 'require|max:20',
|
||||
'shipping_address' => 'require|max:500',
|
||||
'is_follow_up' => 'in:0,1',
|
||||
'prev_staff' => 'max:100',
|
||||
'service_channel' => 'max:100',
|
||||
'service_package' => 'max:100',
|
||||
'tracking_number' => 'max:80',
|
||||
'express_company' => 'max:20',
|
||||
'fee_type' => 'require|in:1,2,3,4,5,6,7',
|
||||
'amount' => 'require|float',
|
||||
'remark_extra' => 'max:500',
|
||||
'action' => 'require|in:approve,reject',
|
||||
'remark' => 'max:500',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'prescription_id.require' => '请选择处方',
|
||||
'diagnosis_id.require' => '请选择诊单',
|
||||
'recipient_name.require' => '请输入收货人',
|
||||
'recipient_phone.require' => '请输入收货手机',
|
||||
'shipping_address.require' => '请输入收货地址',
|
||||
'fee_type.require' => '请选择费用类别',
|
||||
'amount.require' => '请输入订单金额',
|
||||
'action.require' => '请选择审核操作',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'create' => [
|
||||
'prescription_id', 'diagnosis_id', 'recipient_name', 'recipient_phone', 'shipping_address',
|
||||
'is_follow_up', 'prev_staff', 'service_channel', 'service_package',
|
||||
'tracking_number', 'express_company', 'fee_type', 'amount', 'remark_extra', 'pay_order_ids',
|
||||
],
|
||||
'detail' => ['id'],
|
||||
'edit' => [
|
||||
'id', 'recipient_name', 'recipient_phone', 'shipping_address',
|
||||
'is_follow_up', 'prev_staff', 'service_channel', 'service_package',
|
||||
'tracking_number', 'express_company', 'fee_type', 'amount', 'remark_extra', 'pay_order_ids',
|
||||
],
|
||||
'logisticsTrace' => ['id'],
|
||||
'auditPrescription' => ['id', 'action', 'remark'],
|
||||
'auditPayment' => ['id', 'action', 'remark'],
|
||||
'withdraw' => ['id'],
|
||||
'paidPayOrders' => ['diagnosis_id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use app\common\service\ExpressTrackingService;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
/**
|
||||
* 物流自动更新定时任务
|
||||
*
|
||||
* 使用方法:
|
||||
* php think express:auto-update
|
||||
*
|
||||
* 配置crontab(每10分钟执行一次):
|
||||
* 0,10,20,30,40,50 * * * * cd /path/to/server && php think express:auto-update >> /dev/null 2>&1
|
||||
*/
|
||||
class ExpressAutoUpdate extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('express:auto-update')
|
||||
->setDescription('自动更新物流追踪信息');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln('开始自动更新物流信息...');
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
try {
|
||||
$result = ExpressTrackingService::autoUpdateBatch(50);
|
||||
|
||||
$duration = round(microtime(true) - $startTime, 2);
|
||||
|
||||
$output->writeln("更新完成!");
|
||||
$output->writeln("总数: {$result['total']}");
|
||||
$output->writeln("成功: {$result['success']}");
|
||||
$output->writeln("失败: {$result['failed']}");
|
||||
$output->writeln("耗时: {$duration}秒");
|
||||
|
||||
return 0;
|
||||
} catch (\Throwable $e) {
|
||||
$output->error("更新失败: " . $e->getMessage());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use app\common\service\ExpressTrackingService;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 同步现有订单快递单号到物流追踪表
|
||||
*
|
||||
* 使用方法:
|
||||
* php think express:sync
|
||||
*/
|
||||
class SyncTrackingNumbers extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('express:sync')
|
||||
->setDescription('同步现有订单快递单号到物流追踪表');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln('开始同步现有订单快递单号...');
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
try {
|
||||
// 查询所有有快递单号的订单
|
||||
$orders = Db::name('tcm_prescription_order')
|
||||
->where('tracking_number', '<>', '')
|
||||
->whereNull('delete_time')
|
||||
->field([
|
||||
'id',
|
||||
'tracking_number',
|
||||
'express_company',
|
||||
'recipient_name',
|
||||
'recipient_phone',
|
||||
'shipping_address',
|
||||
])
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$total = count($orders);
|
||||
$success = 0;
|
||||
$skipped = 0;
|
||||
$failed = 0;
|
||||
|
||||
$output->writeln("找到 {$total} 个有快递单号的订单");
|
||||
|
||||
foreach ($orders as $order) {
|
||||
try {
|
||||
// 检查是否已存在
|
||||
$exists = Db::name('express_tracking')
|
||||
->where('tracking_number', $order['tracking_number'])
|
||||
->whereNull('delete_time')
|
||||
->count();
|
||||
|
||||
if ($exists > 0) {
|
||||
$skipped++;
|
||||
$output->writeln("跳过: {$order['tracking_number']} (已存在)");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建追踪记录
|
||||
$result = ExpressTrackingService::createOrUpdate([
|
||||
'order_id' => $order['id'],
|
||||
'order_type' => 'prescription',
|
||||
'tracking_number' => $order['tracking_number'],
|
||||
'express_company' => $order['express_company'] ?: 'auto',
|
||||
'recipient_phone' => $order['recipient_phone'],
|
||||
'recipient_name' => $order['recipient_name'],
|
||||
'recipient_address' => $order['shipping_address'],
|
||||
]);
|
||||
|
||||
if ($result) {
|
||||
$success++;
|
||||
$output->writeln("成功: {$order['tracking_number']}");
|
||||
} else {
|
||||
$failed++;
|
||||
$output->writeln("失败: {$order['tracking_number']}");
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$failed++;
|
||||
$output->error("错误: {$order['tracking_number']} - {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$duration = round(microtime(true) - $startTime, 2);
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln('========================================');
|
||||
$output->writeln('同步完成!');
|
||||
$output->writeln('========================================');
|
||||
$output->writeln("总数: {$total}");
|
||||
$output->writeln("成功: {$success}");
|
||||
$output->writeln("跳过: {$skipped}");
|
||||
$output->writeln("失败: {$failed}");
|
||||
$output->writeln("耗时: {$duration}秒");
|
||||
$output->writeln('');
|
||||
$output->writeln('现在可以运行定时任务测试:');
|
||||
$output->writeln(' php think express:auto-update');
|
||||
|
||||
return 0;
|
||||
} catch (\Throwable $e) {
|
||||
$output->error("同步失败: " . $e->getMessage());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\command;
|
||||
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
/**
|
||||
* 定时:补全订单 creator_id(逻辑在 SyncWechatWorkBills::fillOrderCreatorsFromPayee)
|
||||
*/
|
||||
class FillOrderCreatorFromPayee extends SyncWechatWorkBills
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('fill_order_creator_from_payee')
|
||||
->setDescription('补全订单创建人:creator_id 为空时按 payee_userid 匹配 zyt_admin.work_wechat_userid');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$fixed = $this->fillOrderCreatorsFromPayee();
|
||||
$output->writeln("补全创建人完成,共更新 {$fixed} 条订单");
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,10 @@ declare(strict_types=1);
|
||||
namespace app\common\command;
|
||||
|
||||
use app\adminapi\logic\order\OrderLogic;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\Order;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Log;
|
||||
@@ -23,11 +24,24 @@ class SyncWechatWorkBills extends Command
|
||||
$this->setName('sync_wechat_work_bills')
|
||||
->setDescription('同步企业微信对外收款到订单(按天拉取)')
|
||||
->addOption('date', 'd', Option::VALUE_OPTIONAL, '指定日期 Y-m-d,默认今天', '')
|
||||
->addOption('days', null, Option::VALUE_OPTIONAL, '拉取最近N天,每天单独请求', '1');
|
||||
->addOption('days', null, Option::VALUE_OPTIONAL, '拉取最近N天,每天单独请求', '1')
|
||||
->addOption(
|
||||
'fill-order-creators-only',
|
||||
null,
|
||||
Option::VALUE_NONE,
|
||||
'仅补全订单创建人:creator_id 为空时用 payee_userid 匹配 admin.work_wechat_userid(可单独做定时任务)'
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
if ($input->getOption('fill-order-creators-only')) {
|
||||
$fixed = $this->fillOrderCreatorsFromPayee();
|
||||
$output->writeln("补全创建人完成,共更新 {$fixed} 条订单");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$dateStr = $input->getOption('date');
|
||||
$days = (int)$input->getOption('days');
|
||||
$days = $days > 0 ? min($days, 31) : 1;
|
||||
@@ -68,4 +82,32 @@ class SyncWechatWorkBills extends Command
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* creator_id 为空的订单,用 payee_userid 匹配管理员 work_wechat_userid 写入 creator_id
|
||||
*/
|
||||
protected function fillOrderCreatorsFromPayee(): int
|
||||
{
|
||||
$fixed = 0;
|
||||
Order::whereRaw('(creator_id IS NULL OR creator_id = 0)')
|
||||
->whereNotNull('payee_userid')
|
||||
->where('payee_userid', '<>', '')
|
||||
->chunk(200, function ($orders) use (&$fixed) {
|
||||
foreach ($orders as $order) {
|
||||
$payee = trim((string) $order->getAttr('payee_userid'));
|
||||
if ($payee === '') {
|
||||
continue;
|
||||
}
|
||||
$admin = Admin::where('work_wechat_userid', $payee)->whereNull('delete_time')->find();
|
||||
if (!$admin) {
|
||||
continue;
|
||||
}
|
||||
$order->creator_id = (int) $admin->getAttr('id');
|
||||
$order->save();
|
||||
$fixed++;
|
||||
}
|
||||
});
|
||||
|
||||
return $fixed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,16 +14,16 @@ use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 挂号单状态自动更新
|
||||
* - 预约时间已过超过 35 分钟(且未满 8 小时):status -> 4(已过号)
|
||||
* - 预约时间已过超过 8 小时:status -> 2(已取消)
|
||||
* - 不处理:status=3(已完成)、未到时间、刚过号未满 35 分钟的单子
|
||||
* - 已预约(status=1) 且预约时间已过超过 35 分钟 → status=4(已过号)
|
||||
* - 已过号(status=4) 且预约时间已过超过 8 小时 → status=2(已取消)
|
||||
* - 不处理:status=3(已完成)、未到预约时间、距预约未满 35 分钟的单子
|
||||
*/
|
||||
class UpdateAppointmentStatus extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('update_appointment_status')
|
||||
->setDescription('自动更新挂号单状态:过号超35分钟->4,超8小时->2(已取消)')
|
||||
->setDescription('挂号单:已预约过号35分钟→已过号;已过号超8小时→已取消')
|
||||
->addOption('dry', null, Option::VALUE_NONE, '仅预览不执行');
|
||||
}
|
||||
|
||||
@@ -33,26 +33,30 @@ class UpdateAppointmentStatus extends Command
|
||||
$now = time();
|
||||
$table = (new Appointment())->getTable();
|
||||
|
||||
// 1. 超过8小时 -> 已取消(status=2)
|
||||
$cancelWhere = "status = 1 AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) <= DATE_SUB(NOW(), INTERVAL 8 HOUR)";
|
||||
$cancelSql = "UPDATE {$table} SET status = 2, update_time = ? WHERE {$cancelWhere}";
|
||||
$cancelCount = $dryRun ? 0 : Db::execute($cancelSql, [$now]);
|
||||
$dtExpr = "CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00'))";
|
||||
|
||||
// 2. 已过预约时间超过 35 分钟且未满 8 小时 -> 已过号(status=4)
|
||||
$missedWhere = "status = 1 AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) < DATE_SUB(NOW(), INTERVAL 35 MINUTE) AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) > DATE_SUB(NOW(), INTERVAL 8 HOUR)";
|
||||
// 1. 已预约 → 已过号:预约时间早于「当前 − 35 分钟」
|
||||
$missedWhere = "status = 1 AND {$dtExpr} < DATE_SUB(NOW(), INTERVAL 35 MINUTE)";
|
||||
$missedSql = "UPDATE {$table} SET status = 4, update_time = ? WHERE {$missedWhere}";
|
||||
$missedCount = $dryRun ? 0 : Db::execute($missedSql, [$now]);
|
||||
|
||||
// 2. 已过号 → 已取消:预约时间早于或等于「当前 − 8 小时」
|
||||
$cancelWhere = "status = 4 AND {$dtExpr} <= DATE_SUB(NOW(), INTERVAL 8 HOUR)";
|
||||
$cancelSql = "UPDATE {$table} SET status = 2, update_time = ? WHERE {$cancelWhere}";
|
||||
|
||||
if ($dryRun) {
|
||||
$cancelPreview = Db::query("SELECT id FROM {$table} WHERE {$cancelWhere}");
|
||||
$missedPreview = Db::query("SELECT id FROM {$table} WHERE {$missedWhere}");
|
||||
$output->writeln('[预览] 将改为已取消: ' . count($cancelPreview) . ' 条');
|
||||
$output->writeln('[预览] 将改为已过号: ' . count($missedPreview) . ' 条');
|
||||
$cancelPreview = Db::query("SELECT id FROM {$table} WHERE {$cancelWhere}");
|
||||
$output->writeln('[预览] 将改为已过号(1→4): ' . count($missedPreview) . ' 条');
|
||||
$output->writeln('[预览] 将改为已取消(4→2,过号超8小时): ' . count($cancelPreview) . ' 条');
|
||||
$output->writeln('[说明] 真实执行时先执行 1→4,再执行 4→2;同一次内刚由 1 变 4 且已超 8 小时的会再被改为 2。');
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln("已取消(超8小时): {$cancelCount} 条");
|
||||
$output->writeln("已过号: {$missedCount} 条");
|
||||
Log::info("update_appointment_status: 已取消 {$cancelCount}, 已过号 {$missedCount}");
|
||||
$missedCount = Db::execute($missedSql, [$now]);
|
||||
$cancelCount = Db::execute($cancelSql, [$now]);
|
||||
|
||||
$output->writeln("已过号(1→4): {$missedCount} 条");
|
||||
$output->writeln("已取消(4→2,过号超8小时): {$cancelCount} 条");
|
||||
Log::info("update_appointment_status: 已过号 {$missedCount}, 已取消 {$cancelCount}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
/**
|
||||
* 物流查询日志模型
|
||||
*/
|
||||
class ExpressQueryLog extends BaseModel
|
||||
{
|
||||
protected $name = 'express_query_log';
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
/**
|
||||
* 物流状态变更记录模型
|
||||
*/
|
||||
class ExpressStateLog extends BaseModel
|
||||
{
|
||||
protected $name = 'express_state_log';
|
||||
|
||||
/**
|
||||
* 关联主表
|
||||
*/
|
||||
public function tracking()
|
||||
{
|
||||
return $this->belongsTo(ExpressTracking::class, 'tracking_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
/**
|
||||
* 物流轨迹明细模型
|
||||
*/
|
||||
class ExpressTrace extends BaseModel
|
||||
{
|
||||
protected $name = 'express_trace';
|
||||
|
||||
/**
|
||||
* 关联主表
|
||||
*/
|
||||
public function tracking()
|
||||
{
|
||||
return $this->belongsTo(ExpressTracking::class, 'tracking_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\model\concern\SoftDelete;
|
||||
|
||||
/**
|
||||
* 物流追踪模型
|
||||
*/
|
||||
class ExpressTracking extends BaseModel
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'express_tracking';
|
||||
protected $deleteTime = 'delete_time';
|
||||
|
||||
// 物流状态常量
|
||||
public const STATE_IN_TRANSIT = '0'; // 在途
|
||||
public const STATE_COLLECTED = '1'; // 揽收
|
||||
public const STATE_PROBLEM = '2'; // 疑难
|
||||
public const STATE_SIGNED = '3'; // 签收
|
||||
public const STATE_RETURN_SIGNED = '4'; // 退签
|
||||
public const STATE_DELIVERING = '5'; // 派件
|
||||
public const STATE_RETURNING = '6'; // 退回
|
||||
public const STATE_FORWARDING = '7'; // 转投
|
||||
public const STATE_CUSTOMS = '8'; // 清关
|
||||
public const STATE_WAIT_CUSTOMS = '10'; // 待清关
|
||||
public const STATE_IN_CUSTOMS = '11'; // 清关中
|
||||
public const STATE_CUSTOMS_DONE = '12'; // 已清关
|
||||
public const STATE_CUSTOMS_ERROR = '13'; // 清关异常
|
||||
public const STATE_REJECTED = '14'; // 拒签
|
||||
|
||||
/**
|
||||
* 获取状态文本
|
||||
*/
|
||||
public static function getStateText(string $state): string
|
||||
{
|
||||
$map = [
|
||||
self::STATE_IN_TRANSIT => '在途',
|
||||
self::STATE_COLLECTED => '揽收',
|
||||
self::STATE_PROBLEM => '疑难',
|
||||
self::STATE_SIGNED => '已签收',
|
||||
self::STATE_RETURN_SIGNED => '退签',
|
||||
self::STATE_DELIVERING => '派件中',
|
||||
self::STATE_RETURNING => '退回',
|
||||
self::STATE_FORWARDING => '转投',
|
||||
self::STATE_CUSTOMS => '清关',
|
||||
self::STATE_WAIT_CUSTOMS => '待清关',
|
||||
self::STATE_IN_CUSTOMS => '清关中',
|
||||
self::STATE_CUSTOMS_DONE => '已清关',
|
||||
self::STATE_CUSTOMS_ERROR => '清关异常',
|
||||
self::STATE_REJECTED => '拒签',
|
||||
];
|
||||
|
||||
return $map[$state] ?? '未知';
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为终态(不再需要更新)
|
||||
*/
|
||||
public static function isFinalState(string $state): bool
|
||||
{
|
||||
return in_array($state, [
|
||||
self::STATE_SIGNED,
|
||||
self::STATE_RETURN_SIGNED,
|
||||
self::STATE_REJECTED,
|
||||
], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为异常状态
|
||||
*/
|
||||
public static function isProblemState(string $state): bool
|
||||
{
|
||||
return in_array($state, [
|
||||
self::STATE_PROBLEM,
|
||||
self::STATE_CUSTOMS_ERROR,
|
||||
self::STATE_REJECTED,
|
||||
], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联轨迹明细
|
||||
*/
|
||||
public function traces()
|
||||
{
|
||||
return $this->hasMany(ExpressTrace::class, 'tracking_id', 'id')
|
||||
->order('trace_time_stamp', 'desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联状态变更记录
|
||||
*/
|
||||
public function stateLogs()
|
||||
{
|
||||
return $this->hasMany(ExpressStateLog::class, 'tracking_id', 'id')
|
||||
->order('change_time', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model\tcm;
|
||||
|
||||
use app\common\model\BaseModel;
|
||||
use think\model\concern\SoftDelete;
|
||||
|
||||
/**
|
||||
* 消费者处方业务订单(非支付单 zyt_order)
|
||||
*/
|
||||
class PrescriptionOrder extends BaseModel
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'tcm_prescription_order';
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
protected $createTime = 'create_time';
|
||||
|
||||
protected $updateTime = 'update_time';
|
||||
|
||||
protected $dateFormat = false;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model\tcm;
|
||||
|
||||
use app\common\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 处方业务订单与支付单(zyt_order)关联
|
||||
*/
|
||||
class PrescriptionOrderPayOrder extends BaseModel
|
||||
{
|
||||
protected $name = 'tcm_prescription_order_pay_order';
|
||||
|
||||
protected $autoWriteTimestamp = false;
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use think\facade\Config;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 快递轨迹:顺丰(shunfeng)、京东(jd),优先走快递100;未配置时返回官网查询链接
|
||||
*/
|
||||
class ExpressTrackService
|
||||
{
|
||||
private const KUAIDI_COM_SF = 'shunfeng';
|
||||
|
||||
private const KUAIDI_COM_JD = 'jingdong'; // 京东快递(快递100编码)
|
||||
|
||||
private const KUAIDI_COM_JT = 'jtexpress'; // 极兔速递
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* carrier: string,
|
||||
* carrier_label: string,
|
||||
* kuaidi_com: string,
|
||||
* traces: list<array{time:string,context:string}>,
|
||||
* state: string,
|
||||
* state_text: string,
|
||||
* source: string,
|
||||
* hint: string,
|
||||
* official_url: string
|
||||
* }
|
||||
*/
|
||||
public static function query(string $expressCompany, string $trackingNumber, string $recipientPhone = ''): array
|
||||
{
|
||||
$num = trim($trackingNumber);
|
||||
$phoneDigits = preg_replace('/\D/', '', $recipientPhone) ?? '';
|
||||
$phoneLast4 = strlen($phoneDigits) >= 4 ? substr($phoneDigits, -4) : '';
|
||||
|
||||
$resolved = self::resolveCarrier($expressCompany, $num);
|
||||
$carrier = $resolved['carrier'];
|
||||
$kuaidiCom = $resolved['kuaidi_com'];
|
||||
$label = $resolved['label'];
|
||||
|
||||
$officialUrl = self::buildOfficialUrl($carrier, $num);
|
||||
|
||||
$out = [
|
||||
'carrier' => $carrier,
|
||||
'carrier_label' => $label,
|
||||
'kuaidi_com' => $kuaidiCom,
|
||||
'traces' => [],
|
||||
'state' => '',
|
||||
'state_text' => '',
|
||||
'source' => 'official_only',
|
||||
'hint' => '',
|
||||
'official_url' => $officialUrl,
|
||||
];
|
||||
|
||||
$cfg = Config::get('logistics.kuaidi100', []);
|
||||
$enable = !empty($cfg['enable']);
|
||||
if (! $enable) {
|
||||
$out['hint'] = '未配置快递100查询密钥或已关闭(LOGISTICS_KUAIDI100_DISABLE),仅可打开官网查件。请在 .env 中配置 LOGISTICS_KUAIDI100_CUSTOMER、LOGISTICS_KUAIDI100_KEY';
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
$paramArr = [
|
||||
'com' => $kuaidiCom,
|
||||
'num' => $num,
|
||||
'resultv2' => '1',
|
||||
];
|
||||
if ($phoneLast4 !== '') {
|
||||
$paramArr['phone'] = $phoneLast4;
|
||||
}
|
||||
|
||||
$paramJson = json_encode($paramArr, JSON_UNESCAPED_UNICODE);
|
||||
$customer = (string) $cfg['customer'];
|
||||
$key = (string) $cfg['key'];
|
||||
$sign = strtoupper(md5($paramJson . $key . $customer));
|
||||
$postBody = http_build_query([
|
||||
'customer' => $customer,
|
||||
'param' => $paramJson,
|
||||
'sign' => $sign,
|
||||
]);
|
||||
|
||||
$url = (string) ($cfg['query_url'] ?? 'https://poll.kuaidi100.com/poll/query.do');
|
||||
$raw = self::httpPostForm($url, $postBody);
|
||||
if ($raw === null || $raw === '') {
|
||||
$out['hint'] = '快递100接口无响应,请稍后重试或使用官网查询';
|
||||
Log::warning('ExpressTrackService kuaidi100 empty response', ['num' => $num]);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
$json = json_decode($raw, true);
|
||||
if (!is_array($json)) {
|
||||
$out['hint'] = '快递100返回异常,请使用官网查询';
|
||||
Log::warning('ExpressTrackService kuaidi100 invalid json', ['raw' => mb_substr($raw, 0, 500)]);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
if (isset($json['result']) && $json['result'] === false) {
|
||||
$msg = (string) ($json['message'] ?? '查询失败');
|
||||
$returnCode = (string) ($json['returnCode'] ?? '');
|
||||
|
||||
// 特殊处理"找不到对应公司"错误
|
||||
if ($msg === '找不到对应公司' || $returnCode === '400') {
|
||||
$out['hint'] = '快递100暂不支持该快递公司或编码错误,请使用下方官网链接查询';
|
||||
} else {
|
||||
$out['hint'] = $msg;
|
||||
}
|
||||
|
||||
Log::info('ExpressTrackService kuaidi100 business fail', [
|
||||
'message' => $msg,
|
||||
'returnCode' => $returnCode,
|
||||
'num' => $num,
|
||||
'com' => $kuaidiCom
|
||||
]);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
$data = $json['data'] ?? null;
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
if (($json['message'] ?? '') !== 'ok' && $data === []) {
|
||||
$out['hint'] = (string) ($json['message'] ?? '未查到轨迹');
|
||||
Log::info('ExpressTrackService kuaidi100 no data', ['json' => $json]);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
$traces = [];
|
||||
foreach ($data as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$t = (string) ($row['ftime'] ?? $row['time'] ?? '');
|
||||
$c = (string) ($row['context'] ?? '');
|
||||
if ($t === '' && $c === '') {
|
||||
continue;
|
||||
}
|
||||
$traces[] = ['time' => $t, 'context' => $c];
|
||||
}
|
||||
|
||||
$out['traces'] = $traces;
|
||||
$out['state'] = (string) ($json['state'] ?? '');
|
||||
$out['state_text'] = self::stateText($out['state']);
|
||||
$out['source'] = 'kuaidi100';
|
||||
$out['hint'] = $traces === [] ? '暂无轨迹节点,单号可能尚未揽收' : '';
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{carrier: string, kuaidi_com: string, label: string}
|
||||
*/
|
||||
private static function resolveCarrier(string $expressCompany, string $num): array
|
||||
{
|
||||
$ec = strtolower(trim($expressCompany));
|
||||
if ($ec === 'sf') {
|
||||
return ['carrier' => 'sf', 'kuaidi_com' => self::KUAIDI_COM_SF, 'label' => '顺丰速运'];
|
||||
}
|
||||
if ($ec === 'jd') {
|
||||
return ['carrier' => 'jd', 'kuaidi_com' => self::KUAIDI_COM_JD, 'label' => '京东快递'];
|
||||
}
|
||||
if ($ec === 'jt' || $ec === 'jtexpress') {
|
||||
return ['carrier' => 'jt', 'kuaidi_com' => self::KUAIDI_COM_JT, 'label' => '极兔速递'];
|
||||
}
|
||||
|
||||
$u = strtoupper($num);
|
||||
if (preg_match('/^SF\d/i', $num)) {
|
||||
return ['carrier' => 'sf', 'kuaidi_com' => self::KUAIDI_COM_SF, 'label' => '顺丰速运(单号识别)'];
|
||||
}
|
||||
if (preg_match('/^(JD|JDV|JDK|JDEX|JD[A-Z0-9])/i', $u)) {
|
||||
return ['carrier' => 'jd', 'kuaidi_com' => self::KUAIDI_COM_JD, 'label' => '京东快递(单号识别)'];
|
||||
}
|
||||
if (preg_match('/^JT\d{13}$/i', $num)) {
|
||||
return ['carrier' => 'jt', 'kuaidi_com' => self::KUAIDI_COM_JT, 'label' => '极兔速递(单号识别)'];
|
||||
}
|
||||
|
||||
return ['carrier' => 'auto', 'kuaidi_com' => 'auto', 'label' => '自动识别'];
|
||||
}
|
||||
|
||||
private static function stateText(string $state): string
|
||||
{
|
||||
$m = [
|
||||
'0' => '在途',
|
||||
'1' => '揽收',
|
||||
'2' => '疑难',
|
||||
'3' => '已签收',
|
||||
'4' => '退签',
|
||||
'5' => '派件中',
|
||||
'6' => '退回',
|
||||
'7' => '转投',
|
||||
'10' => '待清关',
|
||||
'11' => '清关中',
|
||||
'12' => '已清关',
|
||||
'13' => '清关异常',
|
||||
'14' => '收件人拒签',
|
||||
];
|
||||
|
||||
return $m[$state] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{sf: string, jd: string, jt: string}
|
||||
*/
|
||||
public static function officialUrls(string $trackingNumber): array
|
||||
{
|
||||
$n = trim($trackingNumber);
|
||||
$enc = rawurlencode($n);
|
||||
|
||||
return [
|
||||
// 顺丰速运官网查询(新版)
|
||||
'sf' => 'https://www.sf-express.com/cn/sc/dynamic_function/waybill/#search/bill-number/' . $enc,
|
||||
// 京东物流官网查询
|
||||
'jd' => 'https://www.jdl.com/#/trackQuery?waybillCode=' . $enc,
|
||||
// 极兔速递官网查询
|
||||
'jt' => 'https://www.jtexpress.com.cn/index/query/gzquery.html?bills=' . $enc,
|
||||
];
|
||||
}
|
||||
|
||||
private static function buildOfficialUrl(string $carrier, string $num): string
|
||||
{
|
||||
$urls = self::officialUrls($num);
|
||||
if ($carrier === 'sf') {
|
||||
return $urls['sf'];
|
||||
}
|
||||
if ($carrier === 'jd') {
|
||||
return $urls['jd'];
|
||||
}
|
||||
if ($carrier === 'jt') {
|
||||
return $urls['jt'];
|
||||
}
|
||||
|
||||
return $urls['jt']; // 默认返回极兔
|
||||
}
|
||||
|
||||
private static function httpPostForm(string $url, string $body): ?string
|
||||
{
|
||||
if (!function_exists('curl_init')) {
|
||||
return null;
|
||||
}
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
$resp = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $resp === false ? null : (string) $resp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\model\ExpressTracking;
|
||||
use app\common\model\ExpressTrace;
|
||||
use app\common\model\ExpressStateLog;
|
||||
use app\common\model\ExpressQueryLog;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 物流追踪服务(存储和自动更新)
|
||||
*/
|
||||
class ExpressTrackingService
|
||||
{
|
||||
/**
|
||||
* 创建或更新物流追踪记录
|
||||
*
|
||||
* @param array $params [
|
||||
* 'order_id' => 订单ID,
|
||||
* 'order_type' => 订单类型,
|
||||
* 'tracking_number' => 快递单号,
|
||||
* 'express_company' => 快递公司,
|
||||
* 'recipient_phone' => 收件人手机,
|
||||
* 'recipient_name' => 收件人姓名,
|
||||
* 'recipient_address' => 收件地址,
|
||||
* ]
|
||||
* @return ExpressTracking|null
|
||||
*/
|
||||
public static function createOrUpdate(array $params): ?ExpressTracking
|
||||
{
|
||||
$trackingNumber = trim($params['tracking_number'] ?? '');
|
||||
if ($trackingNumber === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$tracking = ExpressTracking::where('tracking_number', $trackingNumber)
|
||||
->whereNull('delete_time')
|
||||
->find();
|
||||
|
||||
$now = time();
|
||||
|
||||
if (!$tracking) {
|
||||
$tracking = new ExpressTracking();
|
||||
$tracking->tracking_number = $trackingNumber;
|
||||
$tracking->create_time = $now;
|
||||
}
|
||||
|
||||
$tracking->order_id = (int) ($params['order_id'] ?? 0);
|
||||
$tracking->order_type = (string) ($params['order_type'] ?? 'prescription');
|
||||
$tracking->express_company = (string) ($params['express_company'] ?? 'auto');
|
||||
$tracking->recipient_phone = (string) ($params['recipient_phone'] ?? '');
|
||||
$tracking->recipient_name = (string) ($params['recipient_name'] ?? '');
|
||||
$tracking->recipient_address = (string) ($params['recipient_address'] ?? '');
|
||||
$tracking->update_time = $now;
|
||||
|
||||
// 设置下次更新时间(立即查询)
|
||||
if ($tracking->next_update_time === 0) {
|
||||
$tracking->next_update_time = $now;
|
||||
}
|
||||
|
||||
$tracking->save();
|
||||
|
||||
// 立即查询一次物流信息
|
||||
self::queryAndUpdate($tracking->id);
|
||||
|
||||
return $tracking;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询并更新物流信息
|
||||
*
|
||||
* @param int $trackingId
|
||||
* @param bool $isAuto 是否自动查询
|
||||
* @return array|null
|
||||
*/
|
||||
public static function queryAndUpdate(int $trackingId, bool $isAuto = false): ?array
|
||||
{
|
||||
$tracking = ExpressTracking::where('id', $trackingId)
|
||||
->whereNull('delete_time')
|
||||
->find();
|
||||
|
||||
if (!$tracking) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
// 调用快递100查询
|
||||
$result = ExpressTrackService::query(
|
||||
$tracking->express_company,
|
||||
$tracking->tracking_number,
|
||||
$tracking->recipient_phone
|
||||
);
|
||||
|
||||
$responseTime = (int) ((microtime(true) - $startTime) * 1000);
|
||||
|
||||
// 记录查询日志
|
||||
self::logQuery(
|
||||
$tracking->tracking_number,
|
||||
$tracking->express_company,
|
||||
$isAuto ? 'auto' : 'manual',
|
||||
$result,
|
||||
$responseTime
|
||||
);
|
||||
|
||||
// 更新追踪记录
|
||||
$now = time();
|
||||
$oldState = $tracking->current_state;
|
||||
|
||||
$tracking->express_company_name = $result['carrier_label'] ?? '';
|
||||
$tracking->current_state = $result['state'] ?? '0';
|
||||
$tracking->current_state_text = $result['state_text'] ?? '';
|
||||
$tracking->data_source = $result['source'] ?? '';
|
||||
$tracking->last_query_time = $now;
|
||||
$tracking->query_count = $tracking->query_count + 1;
|
||||
|
||||
// 更新预计信息
|
||||
if (!empty($result['arrivalTime'])) {
|
||||
$tracking->estimated_arrival_time = $result['arrivalTime'];
|
||||
}
|
||||
if (!empty($result['totalTime'])) {
|
||||
$tracking->total_time = $result['totalTime'];
|
||||
}
|
||||
if (!empty($result['remainTime'])) {
|
||||
$tracking->remain_time = $result['remainTime'];
|
||||
}
|
||||
|
||||
// 更新路由信息
|
||||
if (!empty($result['routeInfo'])) {
|
||||
$tracking->route_info = json_encode($result['routeInfo'], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
// 更新最新轨迹
|
||||
if (!empty($result['traces']) && is_array($result['traces'])) {
|
||||
$latestTrace = $result['traces'][0];
|
||||
$tracking->latest_trace_time = $latestTrace['time'] ?? '';
|
||||
$tracking->latest_trace_context = $latestTrace['context'] ?? '';
|
||||
$tracking->latest_location = $latestTrace['location'] ?? '';
|
||||
|
||||
// 保存轨迹明细
|
||||
self::saveTraces($tracking->id, $tracking->tracking_number, $result['traces']);
|
||||
}
|
||||
|
||||
// 检查是否签收
|
||||
if (ExpressTracking::isFinalState($tracking->current_state)) {
|
||||
$tracking->is_signed = 1;
|
||||
$tracking->sign_time = $now;
|
||||
$tracking->auto_update = 0; // 停止自动更新
|
||||
}
|
||||
|
||||
// 计算下次更新时间
|
||||
if ($tracking->auto_update == 1 && !ExpressTracking::isFinalState($tracking->current_state)) {
|
||||
$tracking->next_update_time = $now + $tracking->update_interval;
|
||||
}
|
||||
|
||||
$tracking->update_time = $now;
|
||||
$tracking->save();
|
||||
|
||||
// 记录状态变更
|
||||
if ($oldState !== $tracking->current_state) {
|
||||
self::logStateChange($tracking, $oldState);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存轨迹明细
|
||||
*/
|
||||
private static function saveTraces(int $trackingId, string $trackingNumber, array $traces): void
|
||||
{
|
||||
foreach ($traces as $trace) {
|
||||
$traceTime = $trace['time'] ?? $trace['ftime'] ?? '';
|
||||
if ($traceTime === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查是否已存在
|
||||
$exists = ExpressTrace::where('tracking_id', $trackingId)
|
||||
->where('trace_time', $traceTime)
|
||||
->where('trace_context', $trace['context'] ?? '')
|
||||
->count();
|
||||
|
||||
if ($exists > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$model = new ExpressTrace();
|
||||
$model->tracking_id = $trackingId;
|
||||
$model->tracking_number = $trackingNumber;
|
||||
$model->trace_time = $traceTime;
|
||||
$model->trace_time_stamp = strtotime($traceTime) ?: time();
|
||||
$model->trace_context = $trace['context'] ?? '';
|
||||
$model->status = $trace['status'] ?? '';
|
||||
$model->status_code = $trace['statusCode'] ?? '';
|
||||
$model->location = $trace['location'] ?? '';
|
||||
$model->area_code = $trace['areaCode'] ?? '';
|
||||
$model->area_name = $trace['areaName'] ?? '';
|
||||
$model->area_center = $trace['areaCenter'] ?? '';
|
||||
$model->extra_data = json_encode($trace, JSON_UNESCAPED_UNICODE);
|
||||
$model->create_time = time();
|
||||
$model->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录状态变更
|
||||
*/
|
||||
private static function logStateChange(ExpressTracking $tracking, string $oldState): void
|
||||
{
|
||||
$log = new ExpressStateLog();
|
||||
$log->tracking_id = $tracking->id;
|
||||
$log->tracking_number = $tracking->tracking_number;
|
||||
$log->old_state = $oldState;
|
||||
$log->old_state_text = ExpressTracking::getStateText($oldState);
|
||||
$log->new_state = $tracking->current_state;
|
||||
$log->new_state_text = $tracking->current_state_text;
|
||||
$log->change_time = time();
|
||||
$log->change_reason = $tracking->latest_trace_context;
|
||||
$log->create_time = time();
|
||||
$log->save();
|
||||
|
||||
// 检查是否需要通知
|
||||
$shouldNotify = false;
|
||||
|
||||
// 签收通知
|
||||
if ($tracking->notify_on_sign == 1 && ExpressTracking::isFinalState($tracking->current_state)) {
|
||||
$shouldNotify = true;
|
||||
}
|
||||
|
||||
// 异常通知
|
||||
if ($tracking->notify_on_problem == 1 && ExpressTracking::isProblemState($tracking->current_state)) {
|
||||
$shouldNotify = true;
|
||||
}
|
||||
|
||||
if ($shouldNotify) {
|
||||
self::sendNotification($tracking, $log);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送通知(可扩展对接企业微信、短信等)
|
||||
*/
|
||||
private static function sendNotification(ExpressTracking $tracking, ExpressStateLog $log): void
|
||||
{
|
||||
// TODO: 对接通知渠道
|
||||
// 1. 企业微信消息
|
||||
// 2. 短信通知
|
||||
// 3. 系统内通知
|
||||
|
||||
Log::info('Express state changed notification', [
|
||||
'tracking_number' => $tracking->tracking_number,
|
||||
'old_state' => $log->old_state_text,
|
||||
'new_state' => $log->new_state_text,
|
||||
'context' => $log->change_reason,
|
||||
]);
|
||||
|
||||
$log->is_notified = 1;
|
||||
$log->notify_time = time();
|
||||
$log->notify_result = 'logged';
|
||||
$log->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录查询日志
|
||||
*/
|
||||
private static function logQuery(
|
||||
string $trackingNumber,
|
||||
string $expressCompany,
|
||||
string $queryType,
|
||||
array $result,
|
||||
int $responseTime
|
||||
): void {
|
||||
$log = new ExpressQueryLog();
|
||||
$log->tracking_number = $trackingNumber;
|
||||
$log->express_company = $expressCompany;
|
||||
$log->query_type = $queryType;
|
||||
$log->query_source = $result['source'] ?? '';
|
||||
$log->query_time = time();
|
||||
$log->is_success = !empty($result['traces']) ? 1 : 0;
|
||||
$log->error_code = $result['hint'] ? '400' : '';
|
||||
$log->error_message = $result['hint'] ?? '';
|
||||
$log->response_time = $responseTime;
|
||||
$log->trace_count = count($result['traces'] ?? []);
|
||||
$log->create_time = time();
|
||||
$log->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量自动更新(定时任务调用)
|
||||
*
|
||||
* @param int $limit 每次处理数量
|
||||
* @return array
|
||||
*/
|
||||
public static function autoUpdateBatch(int $limit = 50): array
|
||||
{
|
||||
$now = time();
|
||||
|
||||
// 查询需要更新的记录
|
||||
// 条件:
|
||||
// 1. auto_update = 1(启用自动更新)
|
||||
// 2. next_update_time <= now(到达更新时间)
|
||||
// 3. is_signed = 0(未签收)
|
||||
// 4. current_state 不是终态(排除已签收、退签、拒签)
|
||||
$list = ExpressTracking::where('auto_update', 1)
|
||||
->where('next_update_time', '<=', $now)
|
||||
->where('is_signed', 0)
|
||||
->whereNotIn('current_state', [
|
||||
ExpressTracking::STATE_SIGNED,
|
||||
ExpressTracking::STATE_RETURN_SIGNED,
|
||||
ExpressTracking::STATE_REJECTED,
|
||||
])
|
||||
->whereNull('delete_time')
|
||||
->limit($limit)
|
||||
->select();
|
||||
|
||||
$success = 0;
|
||||
$failed = 0;
|
||||
|
||||
foreach ($list as $tracking) {
|
||||
try {
|
||||
self::queryAndUpdate($tracking->id, true);
|
||||
$success++;
|
||||
} catch (\Throwable $e) {
|
||||
$failed++;
|
||||
Log::error('Auto update express tracking failed', [
|
||||
'tracking_id' => $tracking->id,
|
||||
'tracking_number' => $tracking->tracking_number,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'total' => count($list),
|
||||
'success' => $success,
|
||||
'failed' => $failed,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取追踪详情(包含轨迹)
|
||||
*/
|
||||
public static function getDetail(int $trackingId): ?array
|
||||
{
|
||||
$tracking = ExpressTracking::with(['traces', 'stateLogs'])
|
||||
->where('id', $trackingId)
|
||||
->whereNull('delete_time')
|
||||
->find();
|
||||
|
||||
if (!$tracking) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $tracking->toArray();
|
||||
$data['traces'] = $tracking->traces ? $tracking->traces->toArray() : [];
|
||||
$data['state_logs'] = $tracking->stateLogs ? $tracking->stateLogs->toArray() : [];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据快递单号获取追踪详情(包含轨迹)
|
||||
*/
|
||||
public static function getDetailByTrackingNumber(string $trackingNumber): ?array
|
||||
{
|
||||
$tracking = ExpressTracking::with(['traces' => function($query) {
|
||||
// 按时间倒序排列(最新的在前)
|
||||
$query->order('trace_time_stamp', 'desc');
|
||||
}])
|
||||
->where('tracking_number', $trackingNumber)
|
||||
->whereNull('delete_time')
|
||||
->find();
|
||||
|
||||
if (!$tracking) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $tracking->toArray();
|
||||
$data['traces'] = $tracking->traces ? $tracking->traces->toArray() : [];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* 快速检查快递100配置
|
||||
*/
|
||||
|
||||
// 简单读取 .env 文件
|
||||
$envFile = __DIR__ . '/.env';
|
||||
if (!file_exists($envFile)) {
|
||||
die("错误:.env 文件不存在\n");
|
||||
}
|
||||
|
||||
$envContent = file_get_contents($envFile);
|
||||
$lines = explode("\n", $envContent);
|
||||
|
||||
$config = [];
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if (empty($line) || $line[0] === '#' || $line[0] === ';' || $line[0] === '[') {
|
||||
continue;
|
||||
}
|
||||
if (strpos($line, '=') !== false) {
|
||||
list($key, $value) = explode('=', $line, 2);
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
// 去除引号
|
||||
$value = trim($value, '"\'');
|
||||
$config[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
echo "===========================================\n";
|
||||
echo "快递100配置检查\n";
|
||||
echo "===========================================\n\n";
|
||||
|
||||
$customer = $config['LOGISTICS_KUAIDI100_CUSTOMER'] ?? '';
|
||||
$key = $config['LOGISTICS_KUAIDI100_KEY'] ?? '';
|
||||
$disable = $config['LOGISTICS_KUAIDI100_DISABLE'] ?? 'false';
|
||||
|
||||
echo "CUSTOMER: " . ($customer ? substr($customer, 0, 8) . '****' : '未配置') . "\n";
|
||||
echo "KEY: " . ($key ? substr($key, 0, 4) . '****' : '未配置') . "\n";
|
||||
echo "DISABLE: " . $disable . "\n\n";
|
||||
|
||||
if (empty($customer) || empty($key)) {
|
||||
echo "❌ 错误:CUSTOMER 或 KEY 未配置\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strtolower($disable) === 'true' || $disable === '1') {
|
||||
echo "❌ 错误:快递100已被禁用 (DISABLE = true)\n";
|
||||
echo "解决方案:将 LOGISTICS_KUAIDI100_DISABLE 改为 false\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✅ 配置正确!快递100应该可以正常使用\n\n";
|
||||
|
||||
echo "测试查询(需要真实运单号):\n";
|
||||
echo "-------------------------------------------\n";
|
||||
|
||||
// 测试快递100 API
|
||||
$testNumber = 'SF1234567890'; // 替换为真实运单号
|
||||
$phone = '1234'; // 收件人手机后4位
|
||||
|
||||
$paramArr = [
|
||||
'com' => 'shunfeng',
|
||||
'num' => $testNumber,
|
||||
'phone' => $phone,
|
||||
'resultv2' => '1',
|
||||
];
|
||||
|
||||
$paramJson = json_encode($paramArr, JSON_UNESCAPED_UNICODE);
|
||||
$sign = strtoupper(md5($paramJson . $key . $customer));
|
||||
|
||||
$postData = http_build_query([
|
||||
'customer' => $customer,
|
||||
'param' => $paramJson,
|
||||
'sign' => $sign,
|
||||
]);
|
||||
|
||||
echo "请求参数已生成\n";
|
||||
echo "Customer: " . substr($customer, 0, 8) . "****\n";
|
||||
echo "Sign: " . substr($sign, 0, 8) . "****\n\n";
|
||||
|
||||
echo "如需测试实际查询,请:\n";
|
||||
echo "1. 将上面的 testNumber 替换为真实运单号\n";
|
||||
echo "2. 将 phone 替换为收件人手机后4位\n";
|
||||
echo "3. 在浏览器或前端系统中测试查询功能\n\n";
|
||||
|
||||
echo "===========================================\n";
|
||||
echo "检查完成\n";
|
||||
echo "===========================================\n";
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* 检查物流追踪记录状态
|
||||
*/
|
||||
|
||||
// 数据库配置
|
||||
$host = '39.97.232.35';
|
||||
$port = '3306';
|
||||
$database = 'cs_zyt';
|
||||
$username = 'root';
|
||||
$password = '749b460091647766';
|
||||
$charset = 'utf8mb4';
|
||||
|
||||
// 连接数据库
|
||||
$dsn = "mysql:host={$host};port={$port};charset={$charset}";
|
||||
$pdo = new PDO($dsn, $username, $password);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->exec("USE `{$database}`");
|
||||
|
||||
echo "========================================\n";
|
||||
echo "物流追踪记录状态检查\n";
|
||||
echo "========================================\n\n";
|
||||
|
||||
// 查询所有记录
|
||||
$stmt = $pdo->query("
|
||||
SELECT
|
||||
id,
|
||||
tracking_number,
|
||||
express_company,
|
||||
current_state,
|
||||
current_state_text,
|
||||
is_signed,
|
||||
auto_update,
|
||||
next_update_time,
|
||||
FROM_UNIXTIME(next_update_time) as next_update_datetime,
|
||||
UNIX_TIMESTAMP() as now_timestamp,
|
||||
FROM_UNIXTIME(UNIX_TIMESTAMP()) as now_datetime
|
||||
FROM zyt_express_tracking
|
||||
WHERE delete_time IS NULL
|
||||
");
|
||||
|
||||
$records = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (empty($records)) {
|
||||
echo "没有找到任何物流追踪记录\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
echo "找到 " . count($records) . " 条记录:\n\n";
|
||||
|
||||
foreach ($records as $record) {
|
||||
echo "快递单号: {$record['tracking_number']}\n";
|
||||
echo "快递公司: {$record['express_company']}\n";
|
||||
echo "当前状态: {$record['current_state']} - {$record['current_state_text']}\n";
|
||||
echo "是否签收: " . ($record['is_signed'] ? '是' : '否') . "\n";
|
||||
echo "自动更新: " . ($record['auto_update'] ? '启用' : '禁用') . "\n";
|
||||
echo "下次更新时间: {$record['next_update_datetime']} ({$record['next_update_time']})\n";
|
||||
echo "当前时间: {$record['now_datetime']} ({$record['now_timestamp']})\n";
|
||||
|
||||
$shouldUpdate = $record['auto_update'] == 1
|
||||
&& $record['next_update_time'] <= $record['now_timestamp']
|
||||
&& $record['is_signed'] == 0
|
||||
&& !in_array($record['current_state'], ['3', '4', '5']);
|
||||
|
||||
echo "是否应该更新: " . ($shouldUpdate ? '是' : '否') . "\n";
|
||||
|
||||
if (!$shouldUpdate) {
|
||||
echo "不更新原因: ";
|
||||
if ($record['auto_update'] != 1) echo "自动更新未启用 ";
|
||||
if ($record['next_update_time'] > $record['now_timestamp']) echo "未到更新时间 ";
|
||||
if ($record['is_signed'] == 1) echo "已签收 ";
|
||||
if (in_array($record['current_state'], ['3', '4', '5'])) echo "状态为终态 ";
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
echo "\n" . str_repeat('-', 60) . "\n\n";
|
||||
}
|
||||
|
||||
// 查询符合更新条件的记录数
|
||||
$stmt = $pdo->query("
|
||||
SELECT COUNT(*) as count
|
||||
FROM zyt_express_tracking
|
||||
WHERE auto_update = 1
|
||||
AND next_update_time <= UNIX_TIMESTAMP()
|
||||
AND is_signed = 0
|
||||
AND current_state NOT IN ('3', '4', '5')
|
||||
AND delete_time IS NULL
|
||||
");
|
||||
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
echo "符合自动更新条件的记录数: {$result['count']}\n";
|
||||
@@ -11,11 +11,16 @@ return [
|
||||
'query_refund' => 'app\common\command\QueryRefund',
|
||||
// 同步企业微信对外收款
|
||||
'sync_wechat_work_bills' => 'app\common\command\SyncWechatWorkBills',
|
||||
'fill_order_creator_from_payee' => 'app\common\command\FillOrderCreatorFromPayee',
|
||||
// 挂号单状态自动更新(过号->4,超8小时->2)
|
||||
'update_appointment_status' => 'app\common\command\UpdateAppointmentStatus',
|
||||
// 诊单腾讯云 IM 聊天记录入库归档
|
||||
'sync_im_chat_archive' => 'app\common\command\SyncImChatArchive',
|
||||
// 药材库拼音首字母回填(name_pinyin_abbr)
|
||||
'sync_medicine_pinyin_abbr' => 'app\common\command\SyncMedicinePinyinAbbr',
|
||||
// 物流自动更新
|
||||
'express:auto-update' => 'app\\command\\ExpressAutoUpdate',
|
||||
// 同步现有订单快递单号
|
||||
'express:sync' => 'app\\command\\SyncTrackingNumbers',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* 物流轨迹(顺丰 / 京东等)
|
||||
* 对接快递100「实时查询」: https://api.kuaidi100.com
|
||||
*
|
||||
* 规则:同时配置好 CUSTOMER、KEY 即自动走快递100(不必再设 ENABLE=true)。
|
||||
* 若需临时关闭(保留密钥):LOGISTICS_KUAIDI100_DISABLE = true
|
||||
*/
|
||||
$stripQuotes = static function (string $v): string {
|
||||
$v = trim($v);
|
||||
if (strlen($v) >= 2 && (($v[0] === '"' && $v[strlen($v) - 1] === '"') || ($v[0] === "'" && $v[strlen($v) - 1] === "'"))) {
|
||||
return substr($v, 1, -1);
|
||||
}
|
||||
|
||||
return $v;
|
||||
};
|
||||
|
||||
// .env 为 INI 格式:写在某个 [section](如 [trtc])下面的键会变成 trtc.xxx,读不到顶层 LOGISTICS_*
|
||||
$envKuaidi = static function (string $suffix, $default = '') use ($stripQuotes) {
|
||||
$top = 'LOGISTICS_KUAIDI100_' . $suffix;
|
||||
$v = env($top, null);
|
||||
if ($v !== null && $v !== '') {
|
||||
return $stripQuotes((string) $v);
|
||||
}
|
||||
$nested = env('trtc.' . $top, $default);
|
||||
|
||||
return $stripQuotes((string) $nested);
|
||||
};
|
||||
|
||||
$customer = $envKuaidi('CUSTOMER', '');
|
||||
$key = $envKuaidi('KEY', '');
|
||||
$hasCreds = $customer !== '' && $key !== '';
|
||||
$forceDisableRaw = env('LOGISTICS_KUAIDI100_DISABLE', null);
|
||||
if ($forceDisableRaw === null || $forceDisableRaw === '') {
|
||||
$forceDisableRaw = env('trtc.LOGISTICS_KUAIDI100_DISABLE', false);
|
||||
}
|
||||
$forceDisable = filter_var($forceDisableRaw, FILTER_VALIDATE_BOOLEAN);
|
||||
// 已填 CUSTOMER+KEY 即启用;需临时关闭时设 LOGISTICS_KUAIDI100_DISABLE=true(LOGISTICS_KUAIDI100_ENABLE 已废弃,可删)
|
||||
$kuaidiEnabled = ! $forceDisable && $hasCreds;
|
||||
|
||||
return [
|
||||
'kuaidi100' => [
|
||||
'enable' => $kuaidiEnabled,
|
||||
'customer' => $customer,
|
||||
'key' => $key,
|
||||
'query_url' => $envKuaidi('QUERY_URL', 'https://poll.kuaidi100.com/poll/query.do'),
|
||||
],
|
||||
];
|
||||
@@ -111,6 +111,12 @@ return [
|
||||
// 消费者处方单:以下角色 + root 可对「待审核」处方进行通过/驳回(驳回即作废处方)
|
||||
'prescription_audit_roles' => [0, 3,6],
|
||||
|
||||
// 处方业务订单 internal_cost 等财务字段:以下角色 ID + root 可见
|
||||
'prescription_order_finance_roles' => [0, 3],
|
||||
|
||||
// 业务订单「关联支付单」审核:以下角色 ID + root 可操作(可与财务角色一致)
|
||||
'prescription_order_payment_audit_roles' => [0, 3],
|
||||
|
||||
// 腾讯云实时音视频(TRTC)配置
|
||||
'trtc' => [
|
||||
'sdkAppId' => (int)env('trtc.sdk_app_id', 1600127710),
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- 发现糖尿病患病史:支持文字描述(如半年、1年)或纯数字
|
||||
ALTER TABLE `zyt_tcm_diagnosis`
|
||||
MODIFY COLUMN `diabetes_discovery_year` varchar(50) DEFAULT NULL COMMENT '发现糖尿病患病史(如:半年、1年、或纯数字年数)';
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 处方表:关联诊单所属医助(admin.id),便于统计「这张处方对应哪位医助的患者」
|
||||
ALTER TABLE `zyt_tcm_prescription`
|
||||
ADD COLUMN `assistant_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '诊单医助(admin id),0=无' AFTER `creator_id`,
|
||||
ADD KEY `idx_assistant` (`assistant_id`);
|
||||
@@ -0,0 +1,35 @@
|
||||
-- 处方业务订单(履约/双审流程),与支付单表 zyt_order 分离
|
||||
CREATE TABLE IF NOT EXISTS `zyt_tcm_prescription_order` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`order_no` varchar(50) NOT NULL COMMENT '业务订单号',
|
||||
`prescription_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '消费者处方ID',
|
||||
`diagnosis_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '诊单ID',
|
||||
`creator_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建人管理员ID',
|
||||
`recipient_name` varchar(50) NOT NULL DEFAULT '' COMMENT '收货人',
|
||||
`recipient_phone` varchar(20) NOT NULL DEFAULT '' COMMENT '收货手机',
|
||||
`shipping_address` varchar(500) NOT NULL DEFAULT '' COMMENT '收货地址',
|
||||
`is_follow_up` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '是否复诊 0否1是',
|
||||
`medication_days` int(11) DEFAULT NULL COMMENT '用药疗程(天)',
|
||||
`prev_staff` varchar(100) NOT NULL DEFAULT '' COMMENT '上次医生/医助',
|
||||
`service_channel` varchar(100) NOT NULL DEFAULT '' COMMENT '服务渠道',
|
||||
`service_package` varchar(100) NOT NULL DEFAULT '' COMMENT '服务套餐',
|
||||
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
|
||||
`fee_type` tinyint(2) unsigned NOT NULL DEFAULT 3 COMMENT '费用类别 1挂号2问诊3药品4首付5尾款6其他7全部',
|
||||
`amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '业务订单金额',
|
||||
`internal_cost` decimal(10,2) DEFAULT NULL COMMENT '内部成本(财务可见)',
|
||||
`remark_extra` varchar(500) NOT NULL DEFAULT '' COMMENT '备注补充',
|
||||
`linked_pay_order_id` int(11) unsigned DEFAULT NULL COMMENT '关联支付单 zyt_order.id',
|
||||
`prescription_audit_status` tinyint(2) unsigned NOT NULL DEFAULT 0 COMMENT '处方审核 0待审1通过2驳回',
|
||||
`prescription_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '处方审核意见',
|
||||
`payment_slip_audit_status` tinyint(2) unsigned NOT NULL DEFAULT 0 COMMENT '支付单审核 0待审1通过2驳回',
|
||||
`payment_slip_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '支付单审核意见',
|
||||
`fulfillment_status` tinyint(2) unsigned NOT NULL DEFAULT 1 COMMENT '1待双审通过 2履约中 3已完成 4已取消',
|
||||
`create_time` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
`update_time` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
`delete_time` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_order_no` (`order_no`),
|
||||
KEY `idx_prescription_id` (`prescription_id`),
|
||||
KEY `idx_diagnosis_id` (`diagnosis_id`),
|
||||
KEY `idx_creator_id` (`creator_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='处方业务订单(非支付单)';
|
||||
@@ -0,0 +1,82 @@
|
||||
-- 处方业务订单:后台菜单与接口权限(zyt_system_menu)
|
||||
-- 执行前请确认表前缀为 zyt_;若库中已有相同 perms 的行请跳过或删除重复项。
|
||||
-- 菜单挂在「消费者处方」同级目录下(与 consumer/prescription/index 共用父级 pid)
|
||||
|
||||
SET @rx_pid := (
|
||||
SELECT pid FROM zyt_system_menu
|
||||
WHERE type = 'C'
|
||||
AND (
|
||||
component = 'consumer/prescription/index'
|
||||
OR component LIKE '%consumer/prescription/index%'
|
||||
)
|
||||
LIMIT 1
|
||||
);
|
||||
SET @rx_pid := IFNULL(@rx_pid, 0);
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@rx_pid, 'C', '处方业务订单', 'local-icon-dingdan', 48,
|
||||
'tcm.prescriptionOrder/lists', 'consumer/prescription_order', 'consumer/prescription/order_list',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/lists');
|
||||
|
||||
SET @po_menu_id := (SELECT id FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/lists' LIMIT 1);
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '详情', '', 1, 'tcm.prescriptionOrder/detail', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/detail');
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '创建', '', 2, 'tcm.prescriptionOrder/create', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/create');
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '编辑', '', 3, 'tcm.prescriptionOrder/edit', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/edit');
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '处方审核', '', 4, 'tcm.prescriptionOrder/auditPrescription', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/auditPrescription');
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '支付单审核', '', 5, 'tcm.prescriptionOrder/auditPayment', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/auditPayment');
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 业务订单审核意见(已建表可执行;若列已存在会报错,可忽略或手动删重跑)
|
||||
ALTER TABLE `zyt_tcm_prescription_order`
|
||||
ADD COLUMN `prescription_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '处方审核意见' AFTER `prescription_audit_status`,
|
||||
ADD COLUMN `payment_slip_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '支付单审核意见' AFTER `payment_slip_audit_status`;
|
||||
@@ -0,0 +1,24 @@
|
||||
-- 处方业务订单:撤回、拉取可关联已支付单(权限节点)
|
||||
SET @po_menu_id := (SELECT id FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/lists' LIMIT 1);
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '撤回订单', '', 6, 'tcm.prescriptionOrder/withdraw', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/withdraw');
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '可关联支付单', '', 7, 'tcm.prescriptionOrder/paidPayOrders', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/paidPayOrders');
|
||||
@@ -0,0 +1,16 @@
|
||||
-- 处方业务订单 ↔ 支付单(zyt_order) 多对多关联
|
||||
CREATE TABLE IF NOT EXISTS `zyt_tcm_prescription_order_pay_order` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`prescription_order_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '业务订单ID',
|
||||
`pay_order_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT 'zyt_order.id,已支付',
|
||||
`create_time` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_po_pay` (`prescription_order_id`,`pay_order_id`),
|
||||
KEY `idx_pay_order` (`pay_order_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='业务订单关联支付单';
|
||||
|
||||
-- 历史单条关联字段迁入关联表(幂等:忽略重复)
|
||||
INSERT IGNORE INTO `zyt_tcm_prescription_order_pay_order` (`prescription_order_id`, `pay_order_id`, `create_time`)
|
||||
SELECT `id`, `linked_pay_order_id`, UNIX_TIMESTAMP()
|
||||
FROM `zyt_tcm_prescription_order`
|
||||
WHERE `linked_pay_order_id` IS NOT NULL AND `linked_pay_order_id` > 0 AND `delete_time` IS NULL;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- 业务订单:快递公司(顺丰/京东/自动),用于物流轨迹查询
|
||||
ALTER TABLE `zyt_tcm_prescription_order`
|
||||
ADD COLUMN `express_company` varchar(20) NOT NULL DEFAULT '' COMMENT '快递公司 sf=顺丰 jd=京东 auto=自动' AFTER `tracking_number`;
|
||||
@@ -0,0 +1,13 @@
|
||||
-- 处方业务订单:物流轨迹查询权限
|
||||
SET @po_menu_id := (SELECT id FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/lists' LIMIT 1);
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '物流轨迹', '', 8, 'tcm.prescriptionOrder/logisticsTrace', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/logisticsTrace');
|
||||
@@ -0,0 +1,154 @@
|
||||
-- ============================================
|
||||
-- 物流追踪系统数据库表
|
||||
-- ============================================
|
||||
|
||||
-- 1. 物流订单表(主表)
|
||||
CREATE TABLE IF NOT EXISTS `zyt_express_tracking` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`order_id` int(11) NOT NULL DEFAULT '0' COMMENT '关联订单ID(prescription_order表)',
|
||||
`order_type` varchar(50) NOT NULL DEFAULT 'prescription' COMMENT '订单类型',
|
||||
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
|
||||
`express_company` varchar(50) NOT NULL DEFAULT 'auto' COMMENT '快递公司编码',
|
||||
`express_company_name` varchar(100) NOT NULL DEFAULT '' COMMENT '快递公司名称',
|
||||
`recipient_phone` varchar(20) NOT NULL DEFAULT '' COMMENT '收件人手机号',
|
||||
`recipient_name` varchar(100) NOT NULL DEFAULT '' COMMENT '收件人姓名',
|
||||
`recipient_address` varchar(500) NOT NULL DEFAULT '' COMMENT '收件地址',
|
||||
|
||||
-- 物流状态
|
||||
`current_state` varchar(10) NOT NULL DEFAULT '0' COMMENT '当前物流状态:0在途,1揽收,2疑难,3签收,4退签,5派件,6退回,7转投,8清关,10待清关,11清关中,12已清关,13清关异常,14拒签',
|
||||
`current_state_text` varchar(50) NOT NULL DEFAULT '' COMMENT '当前状态文本',
|
||||
`is_signed` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已签收:0否,1是',
|
||||
`sign_time` int(11) NOT NULL DEFAULT '0' COMMENT '签收时间',
|
||||
|
||||
-- 最新轨迹
|
||||
`latest_trace_time` varchar(50) NOT NULL DEFAULT '' COMMENT '最新轨迹时间',
|
||||
`latest_trace_context` varchar(500) NOT NULL DEFAULT '' COMMENT '最新轨迹内容',
|
||||
`latest_location` varchar(200) NOT NULL DEFAULT '' COMMENT '最新位置',
|
||||
|
||||
-- 查询信息
|
||||
`last_query_time` int(11) NOT NULL DEFAULT '0' COMMENT '最后查询时间',
|
||||
`query_count` int(11) NOT NULL DEFAULT '0' COMMENT '查询次数',
|
||||
`data_source` varchar(50) NOT NULL DEFAULT '' COMMENT '数据来源:kuaidi100/official',
|
||||
|
||||
-- 预计信息
|
||||
`estimated_arrival_time` varchar(50) NOT NULL DEFAULT '' COMMENT '预计到达时间',
|
||||
`total_time` varchar(50) NOT NULL DEFAULT '' COMMENT '总耗时',
|
||||
`remain_time` varchar(50) NOT NULL DEFAULT '' COMMENT '剩余时间',
|
||||
|
||||
-- 自动更新控制
|
||||
`auto_update` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否自动更新:0否,1是',
|
||||
`update_interval` int(11) NOT NULL DEFAULT '1800' COMMENT '更新间隔(秒),默认30分钟',
|
||||
`next_update_time` int(11) NOT NULL DEFAULT '0' COMMENT '下次更新时间',
|
||||
|
||||
-- 通知设置
|
||||
`notify_on_sign` tinyint(1) NOT NULL DEFAULT '1' COMMENT '签收时通知:0否,1是',
|
||||
`notify_on_problem` tinyint(1) NOT NULL DEFAULT '1' COMMENT '异常时通知:0否,1是',
|
||||
`notified_states` varchar(500) NOT NULL DEFAULT '' COMMENT '已通知的状态(JSON数组)',
|
||||
|
||||
-- 扩展信息
|
||||
`route_info` text COMMENT '路由信息(JSON)',
|
||||
`extra_data` text COMMENT '扩展数据(JSON)',
|
||||
|
||||
-- 时间戳
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int(11) DEFAULT NULL COMMENT '删除时间',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_tracking_number` (`tracking_number`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_state` (`current_state`),
|
||||
KEY `idx_auto_update` (`auto_update`, `next_update_time`),
|
||||
KEY `idx_create_time` (`create_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流追踪主表';
|
||||
|
||||
-- 2. 物流轨迹明细表
|
||||
CREATE TABLE IF NOT EXISTS `zyt_express_trace` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`tracking_id` int(11) NOT NULL DEFAULT '0' COMMENT '关联tracking表ID',
|
||||
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号(冗余,便于查询)',
|
||||
|
||||
-- 轨迹信息
|
||||
`trace_time` varchar(50) NOT NULL DEFAULT '' COMMENT '轨迹时间',
|
||||
`trace_time_stamp` int(11) NOT NULL DEFAULT '0' COMMENT '轨迹时间戳',
|
||||
`trace_context` varchar(1000) NOT NULL DEFAULT '' COMMENT '轨迹内容',
|
||||
|
||||
-- 状态信息
|
||||
`status` varchar(50) NOT NULL DEFAULT '' COMMENT '物流状态名称',
|
||||
`status_code` varchar(10) NOT NULL DEFAULT '' COMMENT '物流状态码',
|
||||
|
||||
-- 位置信息
|
||||
`location` varchar(200) NOT NULL DEFAULT '' COMMENT '当前位置',
|
||||
`area_code` varchar(50) NOT NULL DEFAULT '' COMMENT '行政区域编码',
|
||||
`area_name` varchar(200) NOT NULL DEFAULT '' COMMENT '行政区域名称',
|
||||
`area_center` varchar(100) NOT NULL DEFAULT '' COMMENT '区域中心坐标',
|
||||
|
||||
-- 扩展信息
|
||||
`extra_data` text COMMENT '扩展数据(JSON)',
|
||||
|
||||
-- 时间戳
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_tracking_id` (`tracking_id`),
|
||||
KEY `idx_tracking_number` (`tracking_number`),
|
||||
KEY `idx_trace_time_stamp` (`trace_time_stamp`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流轨迹明细表';
|
||||
|
||||
-- 3. 物流状态变更记录表
|
||||
CREATE TABLE IF NOT EXISTS `zyt_express_state_log` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`tracking_id` int(11) NOT NULL DEFAULT '0' COMMENT '关联tracking表ID',
|
||||
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
|
||||
|
||||
-- 状态变更
|
||||
`old_state` varchar(10) NOT NULL DEFAULT '' COMMENT '旧状态',
|
||||
`old_state_text` varchar(50) NOT NULL DEFAULT '' COMMENT '旧状态文本',
|
||||
`new_state` varchar(10) NOT NULL DEFAULT '' COMMENT '新状态',
|
||||
`new_state_text` varchar(50) NOT NULL DEFAULT '' COMMENT '新状态文本',
|
||||
|
||||
-- 变更信息
|
||||
`change_time` int(11) NOT NULL DEFAULT '0' COMMENT '变更时间',
|
||||
`change_reason` varchar(500) NOT NULL DEFAULT '' COMMENT '变更原因(最新轨迹内容)',
|
||||
|
||||
-- 通知信息
|
||||
`is_notified` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已通知:0否,1是',
|
||||
`notify_time` int(11) NOT NULL DEFAULT '0' COMMENT '通知时间',
|
||||
`notify_result` varchar(500) NOT NULL DEFAULT '' COMMENT '通知结果',
|
||||
|
||||
-- 时间戳
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_tracking_id` (`tracking_id`),
|
||||
KEY `idx_tracking_number` (`tracking_number`),
|
||||
KEY `idx_change_time` (`change_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流状态变更记录表';
|
||||
|
||||
-- 4. 物流查询日志表
|
||||
CREATE TABLE IF NOT EXISTS `zyt_express_query_log` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
|
||||
`express_company` varchar(50) NOT NULL DEFAULT '' COMMENT '快递公司编码',
|
||||
|
||||
-- 查询信息
|
||||
`query_type` varchar(50) NOT NULL DEFAULT 'manual' COMMENT '查询类型:manual手动,auto自动',
|
||||
`query_source` varchar(50) NOT NULL DEFAULT '' COMMENT '查询来源:kuaidi100/official',
|
||||
`query_time` int(11) NOT NULL DEFAULT '0' COMMENT '查询时间',
|
||||
|
||||
-- 查询结果
|
||||
`is_success` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否成功:0否,1是',
|
||||
`error_code` varchar(50) NOT NULL DEFAULT '' COMMENT '错误码',
|
||||
`error_message` varchar(500) NOT NULL DEFAULT '' COMMENT '错误信息',
|
||||
|
||||
-- 响应信息
|
||||
`response_time` int(11) NOT NULL DEFAULT '0' COMMENT '响应时间(毫秒)',
|
||||
`trace_count` int(11) NOT NULL DEFAULT '0' COMMENT '轨迹数量',
|
||||
|
||||
-- 时间戳
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_tracking_number` (`tracking_number`),
|
||||
KEY `idx_query_time` (`query_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流查询日志表';
|
||||
@@ -0,0 +1,62 @@
|
||||
-- =====================================================
|
||||
-- 同步现有订单的快递单号到物流追踪表
|
||||
-- =====================================================
|
||||
-- 执行时间:2026-04-07
|
||||
-- 说明:将 zyt_tcm_prescription_order 表中已有的快递单号同步到 zyt_express_tracking 表
|
||||
-- =====================================================
|
||||
|
||||
-- 插入现有订单的快递单号到物流追踪表
|
||||
-- 只插入有快递单号且不为空的订单
|
||||
INSERT INTO `zyt_express_tracking` (
|
||||
`order_id`,
|
||||
`order_type`,
|
||||
`tracking_number`,
|
||||
`express_company`,
|
||||
`recipient_phone`,
|
||||
`recipient_name`,
|
||||
`recipient_address`,
|
||||
`auto_update`,
|
||||
`update_interval`,
|
||||
`next_update_time`,
|
||||
`create_time`,
|
||||
`update_time`
|
||||
)
|
||||
SELECT
|
||||
o.`id` AS `order_id`,
|
||||
'prescription' AS `order_type`,
|
||||
o.`tracking_number`,
|
||||
CASE
|
||||
WHEN o.`express_company` = '' OR o.`express_company` IS NULL THEN 'auto'
|
||||
ELSE o.`express_company`
|
||||
END AS `express_company`,
|
||||
o.`recipient_phone`,
|
||||
o.`recipient_name`,
|
||||
o.`shipping_address` AS `recipient_address`,
|
||||
1 AS `auto_update`,
|
||||
600 AS `update_interval`,
|
||||
UNIX_TIMESTAMP() AS `next_update_time`,
|
||||
UNIX_TIMESTAMP() AS `create_time`,
|
||||
UNIX_TIMESTAMP() AS `update_time`
|
||||
FROM `zyt_tcm_prescription_order` o
|
||||
WHERE o.`tracking_number` IS NOT NULL
|
||||
AND o.`tracking_number` != ''
|
||||
AND o.`delete_time` IS NULL
|
||||
AND NOT EXISTS (
|
||||
-- 避免重复插入
|
||||
SELECT 1 FROM `zyt_express_tracking` t
|
||||
WHERE t.`tracking_number` = o.`tracking_number`
|
||||
);
|
||||
|
||||
-- 显示同步结果
|
||||
SELECT
|
||||
COUNT(*) AS '已同步的快递单号数量'
|
||||
FROM `zyt_express_tracking`
|
||||
WHERE `delete_time` IS NULL;
|
||||
|
||||
-- 显示待更新的快递单号(未签收的)
|
||||
SELECT
|
||||
COUNT(*) AS '待自动更新的快递单号数量'
|
||||
FROM `zyt_express_tracking`
|
||||
WHERE `auto_update` = 1
|
||||
AND `is_signed` = 0
|
||||
AND `delete_time` IS NULL;
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* 调试快递100 API响应
|
||||
*/
|
||||
|
||||
// 从 .env 读取配置
|
||||
$envFile = __DIR__ . '/.env';
|
||||
$envContent = file_get_contents($envFile);
|
||||
$lines = explode("\n", $envContent);
|
||||
|
||||
$config = [];
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if (empty($line) || $line[0] === '#' || $line[0] === ';' || $line[0] === '[') {
|
||||
continue;
|
||||
}
|
||||
if (strpos($line, '=') !== false) {
|
||||
list($key, $value) = explode('=', $line, 2);
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
$value = trim($value, '"\'');
|
||||
$config[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$customer = $config['LOGISTICS_KUAIDI100_CUSTOMER'] ?? '';
|
||||
$key = $config['LOGISTICS_KUAIDI100_KEY'] ?? '';
|
||||
|
||||
if (empty($customer) || empty($key)) {
|
||||
die("错误:未配置快递100 CUSTOMER 或 KEY\n");
|
||||
}
|
||||
|
||||
echo "===========================================\n";
|
||||
echo "快递100 API 调试\n";
|
||||
echo "===========================================\n\n";
|
||||
|
||||
// 测试用例
|
||||
$testCases = [
|
||||
[
|
||||
'name' => '京东快递',
|
||||
'com' => 'jingdong', // 修正为正确的编码
|
||||
'num' => 'JD0230761381812',
|
||||
'phone' => ''
|
||||
],
|
||||
[
|
||||
'name' => '极兔速递',
|
||||
'com' => 'jtexpress',
|
||||
'num' => 'JT5472795424064',
|
||||
'phone' => ''
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($testCases as $test) {
|
||||
echo "测试: {$test['name']}\n";
|
||||
echo "-------------------------------------------\n";
|
||||
echo "快递公司编码: {$test['com']}\n";
|
||||
echo "运单号: {$test['num']}\n\n";
|
||||
|
||||
$paramArr = [
|
||||
'com' => $test['com'],
|
||||
'num' => $test['num'],
|
||||
'resultv2' => '1',
|
||||
];
|
||||
|
||||
if ($test['phone'] !== '') {
|
||||
$paramArr['phone'] = $test['phone'];
|
||||
}
|
||||
|
||||
$paramJson = json_encode($paramArr, JSON_UNESCAPED_UNICODE);
|
||||
$sign = strtoupper(md5($paramJson . $key . $customer));
|
||||
|
||||
$postBody = http_build_query([
|
||||
'customer' => $customer,
|
||||
'param' => $paramJson,
|
||||
'sign' => $sign,
|
||||
]);
|
||||
|
||||
echo "请求参数:\n";
|
||||
echo " customer: " . substr($customer, 0, 8) . "****\n";
|
||||
echo " param: {$paramJson}\n";
|
||||
echo " sign: " . substr($sign, 0, 16) . "****\n\n";
|
||||
|
||||
// 发送请求
|
||||
$url = 'https://poll.kuaidi100.com/poll/query.do';
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
echo "HTTP状态码: {$httpCode}\n";
|
||||
|
||||
if ($error) {
|
||||
echo "CURL错误: {$error}\n\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($response === false || $response === '') {
|
||||
echo "错误: 无响应\n\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "原始响应:\n";
|
||||
echo $response . "\n\n";
|
||||
|
||||
$json = json_decode($response, true);
|
||||
if (!is_array($json)) {
|
||||
echo "错误: 无法解析JSON\n\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "解析后的响应:\n";
|
||||
echo " result: " . var_export($json['result'] ?? null, true) . "\n";
|
||||
echo " message: " . ($json['message'] ?? 'N/A') . "\n";
|
||||
echo " returnCode: " . ($json['returnCode'] ?? 'N/A') . "\n";
|
||||
|
||||
if (isset($json['data']) && is_array($json['data'])) {
|
||||
echo " data: " . count($json['data']) . " 条轨迹记录\n";
|
||||
if (count($json['data']) > 0) {
|
||||
echo "\n 最新轨迹:\n";
|
||||
$latest = $json['data'][0];
|
||||
echo " 时间: " . ($latest['ftime'] ?? $latest['time'] ?? 'N/A') . "\n";
|
||||
echo " 内容: " . ($latest['context'] ?? 'N/A') . "\n";
|
||||
}
|
||||
} else {
|
||||
echo " data: 无数据\n";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
echo "===========================================\n";
|
||||
echo "调试完成\n";
|
||||
echo "===========================================\n\n";
|
||||
|
||||
echo "常见错误码说明:\n";
|
||||
echo "-------------------------------------------\n";
|
||||
echo "200: 查询成功\n";
|
||||
echo "500: 服务器错误\n";
|
||||
echo "501: 重复提交\n";
|
||||
echo "600: 您不是合法的订阅者\n";
|
||||
echo "601: SIGN签名错误\n";
|
||||
echo "700: 订阅方的订阅数据已达到上限\n";
|
||||
echo "701: 快递公司参数异常\n";
|
||||
echo "702: 快递单号参数异常\n";
|
||||
echo "703: 查询无结果\n";
|
||||
echo "704: 快递公司识别失败\n\n";
|
||||
|
||||
echo "如果返回 '找不到对应公司',可能原因:\n";
|
||||
echo "1. 快递公司编码错误(如:jd 应该是 jingdong)\n";
|
||||
echo "2. 快递100不支持该快递公司\n";
|
||||
echo "3. 需要使用快递100的自动识别功能\n\n";
|
||||
Binary file not shown.
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* 安装物流追踪表
|
||||
*/
|
||||
|
||||
// 数据库配置
|
||||
$host = '39.97.232.35';
|
||||
$port = '3306';
|
||||
$database = 'cs_zyt';
|
||||
$username = 'root';
|
||||
$password = '749b460091647766';
|
||||
$charset = 'utf8mb4';
|
||||
|
||||
// 连接数据库
|
||||
$dsn = "mysql:host={$host};port={$port};charset={$charset}";
|
||||
$pdo = new PDO($dsn, $username, $password);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
// 选择数据库
|
||||
$pdo->exec("USE `{$database}`");
|
||||
|
||||
echo "开始创建物流追踪表...\n\n";
|
||||
|
||||
// 读取SQL文件
|
||||
$sql = file_get_contents(__DIR__ . '/database/migrations/create_express_tracking_tables.sql');
|
||||
|
||||
// 分割SQL语句
|
||||
$statements = array_filter(
|
||||
array_map('trim', explode(';', $sql)),
|
||||
function($stmt) {
|
||||
return !empty($stmt) &&
|
||||
!preg_match('/^--/', $stmt) &&
|
||||
!preg_match('/^\/\*/', $stmt);
|
||||
}
|
||||
);
|
||||
|
||||
$success = 0;
|
||||
$failed = 0;
|
||||
|
||||
foreach ($statements as $statement) {
|
||||
try {
|
||||
$pdo->exec($statement);
|
||||
|
||||
// 提取表名
|
||||
if (preg_match('/CREATE TABLE.*?`(\w+)`/i', $statement, $matches)) {
|
||||
echo "✓ 创建表: {$matches[1]}\n";
|
||||
$success++;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
if (strpos($e->getMessage(), 'already exists') !== false) {
|
||||
if (preg_match('/CREATE TABLE.*?`(\w+)`/i', $statement, $matches)) {
|
||||
echo "- 表已存在: {$matches[1]}\n";
|
||||
}
|
||||
} else {
|
||||
echo "✗ 错误: {$e->getMessage()}\n";
|
||||
$failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n========================================\n";
|
||||
echo "安装完成!\n";
|
||||
echo "========================================\n";
|
||||
echo "成功: {$success}\n";
|
||||
echo "失败: {$failed}\n";
|
||||
echo "\n";
|
||||
echo "下一步:\n";
|
||||
echo " php think express:sync # 同步现有快递单号\n";
|
||||
echo " php think express:auto-update # 测试自动更新\n";
|
||||
echo "\n";
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import r from"./error-BgLNs39O.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-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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-DTOfRDY0.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-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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-BgLNs39O.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C0pg79pw.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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-DTOfRDY0.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C0pg79pw.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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
@@ -0,0 +1 @@
|
||||
.cell-stack[data-v-05090333]{display:flex;flex-direction:column;gap:2px;line-height:1.35}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{_ as o}from"./AssignLogPanel.vue_vue_type_script_setup_true_lang-BocBQBMI.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-CgwtzlaG.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";export{o as default};
|
||||
+1
@@ -0,0 +1 @@
|
||||
import{L as _,N as f,M as u}from"./element-plus-D_tJqBgC.js";import{u as w}from"./tcm-CgwtzlaG.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
+1
-1
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{K as E,L,N,M as P,a0 as T}from"./element-plus-8nG574Ul.js";import{z as B}from"./tcm-DsWVWJMK.js";import{f as R,w as V,ak as o,I as i,a,aP as D,G as u,aN as s,O as l,F,ap as z}from"./@vue/runtime-core-C0pg79pw.js";import{Q as n}from"./@vue/shared-mAAVTE9n.js";import{o as g}from"./@vue/reactivity-BIbyPIZJ.js";import{a as A}from"./index-C2ep5Cm2.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const G={class:"call-record-panel"},K={key:0,class:"recording-list"},M=["src"],O={key:1,class:"text-gray-400"},Q=R({__name:"CallRecordPanel",props:{diagnosisId:{}},setup(h,{expose:b}){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(t){console.error(t),c.value=[]}finally{m.value=!1}}};V(()=>p.diagnosisId,()=>{_()},{immediate:!0}),b({refresh:_});function y(t){return{1:"进行中",2:"已结束",3:"未接听",4:"已取消"}[t]??"—"}function v(t){return!t||typeof t!="string"?!1:/\.(mp4|webm|ogg)(\?|$)/i.test(t)}return(t,w)=>{const k=E,r=N,x=T,C=P,I=L;return o(),i("div",G,[a(k,{type:"info","show-icon":"",closable:!1,class:"mb-4",title:"视频通话与录制回放"}),D((o(),u(C,{data:c.value,border:"",stripe:"","empty-text":"暂无通话记录"},{default:s(()=>[a(r,{label:"开始时间",width:"170",prop:"start_time_text"}),a(r,{label:"结束时间",width:"170",prop:"end_time_text"}),a(r,{label:"通话类型",width:"100"},{default:s(({row:e})=>[l(n(e.call_type===1?"语音":"视频"),1)]),_:1}),a(r,{label:"时长",width:"110",prop:"duration_text"}),a(r,{label:"状态",width:"90"},{default:s(({row:e})=>[l(n(y(e.status)),1)]),_:1}),a(r,{label:"录制",width:"100"},{default:s(({row:e})=>[l(n(e.recording_status_text||"—"),1)]),_:1}),a(r,{label:"录制回放","min-width":"280"},{default:s(({row:e})=>[(e.recording_urls_list||[]).length?(o(),i("div",K,[(o(!0),i(F,null,z(e.recording_urls_list,(d,f)=>(o(),i("div",{key:f,class:"recording-item"},[v(d)?(o(),i("video",{key:0,src:d,controls:"",preload:"metadata",class:"recording-video"},null,8,M)):(o(),u(x,{key:1,href:d,target:"_blank",type:"primary"},{default:s(()=>[l(" 打开链接 "+n(f+1),1)]),_:2},1032,["href"]))]))),128))])):(o(),i("span",O,"暂无"))]),_:1})]),_:1},8,["data"])),[[I,m.value]])])}}}),Lt=A(Q,[["__scopeId","data-v-6e14a232"]]);export{Lt as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{K as E,L,N,M as P,a0 as T}from"./element-plus-D_tJqBgC.js";import{A as B}from"./tcm-CgwtzlaG.js";import{f as R,w as V,ak as o,I as i,a,aP as A,G as u,aN as s,O as l,F as D,ap as F}from"./@vue/runtime-core-C0pg79pw.js";import{Q as n}from"./@vue/shared-mAAVTE9n.js";import{o as g}from"./@vue/reactivity-BIbyPIZJ.js";import{_ as G}from"./index-CLJhkNLF.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-CmwKjXis.js";import"./lodash-es-BADexyn7.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";const K={class:"call-record-panel"},M={key:0,class:"recording-list"},O=["src"],Q={key:1,class:"text-gray-400"},S=R({__name:"CallRecordPanel",props:{diagnosisId:{}},setup(h,{expose:b}){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(t){console.error(t),c.value=[]}finally{m.value=!1}}};V(()=>p.diagnosisId,()=>{_()},{immediate:!0}),b({refresh:_});function y(t){return{1:"进行中",2:"已结束",3:"未接听",4:"已取消"}[t]??"—"}function v(t){return!t||typeof t!="string"?!1:/\.(mp4|webm|ogg)(\?|$)/i.test(t)}return(t,w)=>{const k=E,r=N,x=T,C=P,I=L;return o(),i("div",K,[a(k,{type:"info","show-icon":"",closable:!1,class:"mb-4",title:"视频通话与录制回放"}),A((o(),u(C,{data:c.value,border:"",stripe:"","empty-text":"暂无通话记录"},{default:s(()=>[a(r,{label:"开始时间",width:"170",prop:"start_time_text"}),a(r,{label:"结束时间",width:"170",prop:"end_time_text"}),a(r,{label:"通话类型",width:"100"},{default:s(({row:e})=>[l(n(e.call_type===1?"语音":"视频"),1)]),_:1}),a(r,{label:"时长",width:"110",prop:"duration_text"}),a(r,{label:"状态",width:"90"},{default:s(({row:e})=>[l(n(y(e.status)),1)]),_:1}),a(r,{label:"录制",width:"100"},{default:s(({row:e})=>[l(n(e.recording_status_text||"—"),1)]),_:1}),a(r,{label:"录制回放","min-width":"280"},{default:s(({row:e})=>[(e.recording_urls_list||[]).length?(o(),i("div",M,[(o(!0),i(D,null,F(e.recording_urls_list,(d,f)=>(o(),i("div",{key:f,class:"recording-item"},[v(d)?(o(),i("video",{key:0,src:d,controls:"",preload:"metadata",class:"recording-video"},null,8,O)):(o(),u(x,{key:1,href:d,target:"_blank",type:"primary"},{default:s(()=>[l(" 打开链接 "+n(f+1),1)]),_:2},1032,["href"]))]))),128))])):(o(),i("span",Q,"暂无"))]),_:1})]),_:1},8,["data"])),[[I,m.value]])])}}}),Lt=G(S,[["__scopeId","data-v-6e14a232"]]);export{Lt 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-8nG574Ul.js";import{A as P}from"./tcm-DsWVWJMK.js";import{f as A,b as F,w as j,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{a as G}from"./index-C2ep5Cm2.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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=A({__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 F(()=>{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})]),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",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(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=G(K,[["__scopeId","data-v-de802464"]]);export{zt as default};
|
||||
import{i as L,L as T,N as V,U as D,M as z,T as M}from"./element-plus-D_tJqBgC.js";import{B as P}from"./tcm-CgwtzlaG.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 G}from"./index-CLJhkNLF.js";import"./@vue/runtime-dom-iFk_KP8y.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-CmwKjXis.js";import"./lodash-es-BADexyn7.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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)},B=()=>{y("openPrescription")};return j(()=>{u()}),A(()=>_.diagnosisId,()=>{u()}),x({refresh:u}),(e,t)=>{const h=L,a=V,b=D,E=z,N=M,I=T;return r(),l("div",J,[v("div",Q,[i(h,{type:"primary",size:"small",onClick:B},{default:s(()=>[...t[0]||(t[0]=[m("开方",-1)])]),_:1})]),H((r(),g(E,{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(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(N,{key:0,description:"暂无病历记录,开方后会自动显示",class:"mt-4"})):R("",!0)])}}}),zt=G(K,[["__scopeId","data-v-de802464"]]);export{zt as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-G1VH3QkR.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-D0lFf8Hm.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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-DtjEjIXx.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-B5YfXeiX.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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-8nG574Ul.js";import{P as F}from"./index-D0lFf8Hm.js";import{h as b}from"./index-C2ep5Cm2.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-D_tJqBgC.js";import{P as F}from"./index-B5YfXeiX.js";import{i as b}from"./index-CLJhkNLF.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 _};
|
||||
@@ -0,0 +1 @@
|
||||
.p-4{padding:0}[data-v-b7bad7d9]{box-sizing:border-box}html[data-v-b7bad7d9],body[data-v-b7bad7d9]{margin:0;padding:0}.diagnosis-page[data-v-b7bad7d9]{display:flex;flex-direction:column;min-height:100vh;width:100%;background-color:#f5f7fa;margin:0;padding:0}.page-header[data-v-b7bad7d9]{display:flex;align-items:center;gap:12px;padding:16px;background-color:#fff;border-bottom:1px solid #ebeef5;position:sticky;top:0;z-index:100;width:100%}.page-header .back-btn[data-v-b7bad7d9]{padding:0;font-size:16px;color:#606266;flex-shrink:0}.page-header .back-btn[data-v-b7bad7d9]:hover{color:#409eff}.page-header .page-title[data-v-b7bad7d9]{margin:0;font-size:18px;font-weight:600;color:#303133;flex:1}.page-content[data-v-b7bad7d9]{flex:1;width:100%;overflow-y:auto;padding:16px}@media(min-width:768px){.page-content[data-v-b7bad7d9]{padding:24px}}.diagnosis-form[data-v-b7bad7d9]{width:100%}.diagnosis-form[data-v-b7bad7d9] .el-form-item{margin-bottom:16px}.diagnosis-form[data-v-b7bad7d9] .el-form-item__label{font-weight:500;color:#606266}.diagnosis-form[data-v-b7bad7d9] .el-input,.diagnosis-form[data-v-b7bad7d9] .el-input-number,.diagnosis-form[data-v-b7bad7d9] .el-select,.diagnosis-form[data-v-b7bad7d9] .el-date-editor{width:100%}.form-section[data-v-b7bad7d9]{background-color:#fff;border-radius:4px;padding:16px;margin-bottom:16px;width:100%}.form-section .section-title[data-v-b7bad7d9]{font-size:16px;font-weight:600;color:#303133;margin-bottom:16px;padding-bottom:12px;border-bottom:2px solid #409eff}.radio-group[data-v-b7bad7d9]{display:flex;flex-wrap:wrap;gap:8px;width:100%}.radio-group[data-v-b7bad7d9] .el-radio-button{flex:0 1 auto;min-width:60px}.checkbox-group[data-v-b7bad7d9]{display:flex;flex-wrap:wrap;gap:8px;width:100%}.checkbox-group[data-v-b7bad7d9] .el-checkbox-button{flex:0 1 auto;min-width:60px}.form-tips[data-v-b7bad7d9]{font-size:12px;color:#909399;margin-top:4px;line-height:1.5}.page-footer[data-v-b7bad7d9]{display:flex;gap:12px;padding:16px;background-color:#fff;border-top:1px solid #ebeef5;position:sticky;bottom:0;z-index:100;width:100%}@media(max-width:767px){.page-footer[data-v-b7bad7d9]{flex-direction:column}}.page-footer .btn-cancel[data-v-b7bad7d9],.page-footer .btn-submit[data-v-b7bad7d9]{flex:1;height:40px;font-size:16px;font-weight:500}@media(min-width:768px){.page-footer .btn-cancel[data-v-b7bad7d9],.page-footer .btn-submit[data-v-b7bad7d9]{flex:0 1 auto;min-width:120px}}@media(max-width:767px){.page-footer .btn-cancel[data-v-b7bad7d9]{order:2}.page-footer .btn-submit[data-v-b7bad7d9]{order:1}.page-header[data-v-b7bad7d9]{padding:12px}.page-header .page-title[data-v-b7bad7d9]{font-size:16px}.page-content[data-v-b7bad7d9]{padding:12px}.form-section[data-v-b7bad7d9]{padding:12px;margin-bottom:12px}.form-section .section-title[data-v-b7bad7d9]{font-size:14px;margin-bottom:12px;padding-bottom:8px}.radio-group[data-v-b7bad7d9],.checkbox-group[data-v-b7bad7d9]{gap:6px}.radio-group[data-v-b7bad7d9] .el-radio-button,.radio-group[data-v-b7bad7d9] .el-checkbox-button,.checkbox-group[data-v-b7bad7d9] .el-radio-button,.checkbox-group[data-v-b7bad7d9] .el-checkbox-button{min-width:50px;font-size:12px}[data-v-b7bad7d9] .el-form-item__label,[data-v-b7bad7d9] .el-input__inner,[data-v-b7bad7d9] .el-textarea__inner{font-size:14px}}@media(prefers-color-scheme:dark){.diagnosis-page[data-v-b7bad7d9]{background-color:#1a1a1a}.page-header[data-v-b7bad7d9],.page-footer[data-v-b7bad7d9],.form-section[data-v-b7bad7d9]{background-color:#2a2a2a;border-color:#444}.page-title[data-v-b7bad7d9],.section-title[data-v-b7bad7d9]{color:#e0e0e0}}
|
||||
@@ -1 +0,0 @@
|
||||
.p-4{padding:0}[data-v-d419a795]{box-sizing:border-box}html[data-v-d419a795],body[data-v-d419a795]{margin:0;padding:0}.diagnosis-page[data-v-d419a795]{display:flex;flex-direction:column;min-height:100vh;width:100%;background-color:#f5f7fa;margin:0;padding:0}.page-header[data-v-d419a795]{display:flex;align-items:center;gap:12px;padding:16px;background-color:#fff;border-bottom:1px solid #ebeef5;position:sticky;top:0;z-index:100;width:100%}.page-header .back-btn[data-v-d419a795]{padding:0;font-size:16px;color:#606266;flex-shrink:0}.page-header .back-btn[data-v-d419a795]:hover{color:#409eff}.page-header .page-title[data-v-d419a795]{margin:0;font-size:18px;font-weight:600;color:#303133;flex:1}.page-content[data-v-d419a795]{flex:1;width:100%;overflow-y:auto;padding:16px}@media(min-width:768px){.page-content[data-v-d419a795]{padding:24px}}.diagnosis-form[data-v-d419a795]{width:100%}.diagnosis-form[data-v-d419a795] .el-form-item{margin-bottom:16px}.diagnosis-form[data-v-d419a795] .el-form-item__label{font-weight:500;color:#606266}.diagnosis-form[data-v-d419a795] .el-input,.diagnosis-form[data-v-d419a795] .el-input-number,.diagnosis-form[data-v-d419a795] .el-select,.diagnosis-form[data-v-d419a795] .el-date-editor{width:100%}.form-section[data-v-d419a795]{background-color:#fff;border-radius:4px;padding:16px;margin-bottom:16px;width:100%}.form-section .section-title[data-v-d419a795]{font-size:16px;font-weight:600;color:#303133;margin-bottom:16px;padding-bottom:12px;border-bottom:2px solid #409eff}.radio-group[data-v-d419a795]{display:flex;flex-wrap:wrap;gap:8px;width:100%}.radio-group[data-v-d419a795] .el-radio-button{flex:0 1 auto;min-width:60px}.checkbox-group[data-v-d419a795]{display:flex;flex-wrap:wrap;gap:8px;width:100%}.checkbox-group[data-v-d419a795] .el-checkbox-button{flex:0 1 auto;min-width:60px}.form-tips[data-v-d419a795]{font-size:12px;color:#909399;margin-top:4px;line-height:1.5}.page-footer[data-v-d419a795]{display:flex;gap:12px;padding:16px;background-color:#fff;border-top:1px solid #ebeef5;position:sticky;bottom:0;z-index:100;width:100%}@media(max-width:767px){.page-footer[data-v-d419a795]{flex-direction:column}}.page-footer .btn-cancel[data-v-d419a795],.page-footer .btn-submit[data-v-d419a795]{flex:1;height:40px;font-size:16px;font-weight:500}@media(min-width:768px){.page-footer .btn-cancel[data-v-d419a795],.page-footer .btn-submit[data-v-d419a795]{flex:0 1 auto;min-width:120px}}@media(max-width:767px){.page-footer .btn-cancel[data-v-d419a795]{order:2}.page-footer .btn-submit[data-v-d419a795]{order:1}.page-header[data-v-d419a795]{padding:12px}.page-header .page-title[data-v-d419a795]{font-size:16px}.page-content[data-v-d419a795]{padding:12px}.form-section[data-v-d419a795]{padding:12px;margin-bottom:12px}.form-section .section-title[data-v-d419a795]{font-size:14px;margin-bottom:12px;padding-bottom:8px}.radio-group[data-v-d419a795],.checkbox-group[data-v-d419a795]{gap:6px}.radio-group[data-v-d419a795] .el-radio-button,.radio-group[data-v-d419a795] .el-checkbox-button,.checkbox-group[data-v-d419a795] .el-radio-button,.checkbox-group[data-v-d419a795] .el-checkbox-button{min-width:50px;font-size:12px}[data-v-d419a795] .el-form-item__label,[data-v-d419a795] .el-input__inner,[data-v-d419a795] .el-textarea__inner{font-size:14px}}@media(prefers-color-scheme:dark){.diagnosis-page[data-v-d419a795]{background-color:#1a1a1a}.page-header[data-v-d419a795],.page-footer[data-v-d419a795],.form-section[data-v-d419a795]{background-color:#2a2a2a;border-color:#444}.page-title[data-v-d419a795],.section-title[data-v-d419a795]{color:#e0e0e0}}
|
||||
File diff suppressed because one or more lines are too long
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-CEl0QgUO.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-Clj0RWzm.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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-8nG574Ul.js";import{_ as $}from"./index-DL2R2dPV.js";import{_ as z}from"./picker-DDyyE4Hw.js";import{_ as A}from"./picker-anRkbqwm.js";import{_ as D,h as r}from"./index-C2ep5Cm2.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 _,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(c,{emit:f}){const t=c,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(_(I),{class:"draggable",modelValue:_(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-D_tJqBgC.js";import{_ as $}from"./index-fYTl8bPL.js";import{_ as z}from"./picker-C8lFmPfc.js";import{_ as A}from"./picker-Dd64qXUf.js";import{c as D,i as r}from"./index-CLJhkNLF.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 _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{r as n}from"./index-C2ep5Cm2.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-CLJhkNLF.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-C2ep5Cm2.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-CLJhkNLF.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-DtXa6ZoY.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-BnjXGEKw.js";export{o as default};
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BQH83vDf.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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-oQIsvp3z.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-pALzINLE.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-CI94iDCk.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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-8nG574Ul.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-D5n7wiBc.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-D_tJqBgC.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-DmGNkHc9.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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
@@ -1 +1 @@
|
||||
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-UygRyGe-.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-anRkbqwm.js";import"./index-D0lFf8Hm.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-D4E_KNst.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./index-DL2R2dPV.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-DCUgal-n.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-Dd64qXUf.js";import"./index-B5YfXeiX.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-DBOpb5OQ.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./index-fYTl8bPL.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BqhkmADK.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-CEl0QgUO.js";import"./index-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-CIwerCM7.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-Clj0RWzm.js";import"./index-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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-imdF5haE.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-DGq0Bw05.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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-Ch07OD9M.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-CEl0QgUO.js";import"./index-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-DZmBI0zi.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-Clj0RWzm.js";import"./index-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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-UvTgYZBe.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-BnjXGEKw.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./picker-anRkbqwm.js";import"./index-D0lFf8Hm.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-D4E_KNst.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./index-DL2R2dPV.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-BGlorjx9.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-oQIsvp3z.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./picker-Dd64qXUf.js";import"./index-B5YfXeiX.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./index-DBOpb5OQ.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./index-fYTl8bPL.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-hSwyPtds.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DwBN4Vy9.js";import"./attr-DwTlXGpB.js";import"./index-DL2R2dPV.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-DDyyE4Hw.js";import"./index-D0lFf8Hm.js";import"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import"./article-DrP7QuTz.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-anRkbqwm.js";import"./index-D4E_KNst.js";import"./index-BM19PjE0.js";import"./index.vue_vue_type_script_setup_true_lang-Bm3qXg2y.js";import"./file-CL1V_Cod.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-BlED0m-a.js";import"./decoration-img-DsnbJJ7z.js";import"./attr.vue_vue_type_script_setup_true_lang-UygRyGe-.js";import"./content-Cd32gWWA.js";import"./attr.vue_vue_type_script_setup_true_lang-imdF5haE.js";import"./content.vue_vue_type_script_setup_true_lang-BVOpODOj.js";import"./attr.vue_vue_type_script_setup_true_lang-Ch07OD9M.js";import"./add-nav.vue_vue_type_script_setup_true_lang-CEl0QgUO.js";import"./content-CvNsHrtD.js";import"./attr.vue_vue_type_script_setup_true_lang-BqhkmADK.js";import"./content.vue_vue_type_script_setup_true_lang-DjmvG7sA.js";import"./attr.vue_vue_type_script_setup_true_lang-CfPY9LZg.js";import"./content-CkfJ8oP7.js";import"./decoration-CoS5u1Kg.js";import"./attr.vue_vue_type_script_setup_true_lang-UvTgYZBe.js";import"./index.vue_vue_type_script_setup_true_lang-BnjXGEKw.js";import"./content-DZpzFmih.js";import"./content.vue_vue_type_script_setup_true_lang-CsCo8K9F.js";import"./attr.vue_vue_type_script_setup_true_lang-eatfXr14.js";import"./content-CqPqyOfD.js";import"./attr.vue_vue_type_script_setup_true_lang-pALzINLE.js";import"./content.vue_vue_type_script_setup_true_lang-BHrCuz_g.js";import"./attr.vue_vue_type_script_setup_true_lang-11IwTsyi.js";import"./content-CflfDnDy.js";export{o as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-rBfblQSf.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-B9vchYqI.js";import"./attr-fL60dHSY.js";import"./index-fYTl8bPL.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./picker-C8lFmPfc.js";import"./index-B5YfXeiX.js";import"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import"./article-Bv_mVWDC.js";import"./usePaging-B_C_SZ2Z.js";import"./picker-Dd64qXUf.js";import"./index-DBOpb5OQ.js";import"./index-BMxItfrv.js";import"./index.vue_vue_type_script_setup_true_lang-DFNL-1hU.js";import"./file-CCsyMC54.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-CFUjbrbQ.js";import"./decoration-img-BfhW5Pfn.js";import"./attr.vue_vue_type_script_setup_true_lang-DCUgal-n.js";import"./content-DQBRTRo-.js";import"./attr.vue_vue_type_script_setup_true_lang-DGq0Bw05.js";import"./content.vue_vue_type_script_setup_true_lang-DmXwhNrJ.js";import"./attr.vue_vue_type_script_setup_true_lang-CIwerCM7.js";import"./add-nav.vue_vue_type_script_setup_true_lang-Clj0RWzm.js";import"./content-DoSkp8Rl.js";import"./attr.vue_vue_type_script_setup_true_lang-DZmBI0zi.js";import"./content.vue_vue_type_script_setup_true_lang-DEKh7b2S.js";import"./attr.vue_vue_type_script_setup_true_lang-CfPY9LZg.js";import"./content-W2lzHLKG.js";import"./decoration-DM5uWpUh.js";import"./attr.vue_vue_type_script_setup_true_lang-BGlorjx9.js";import"./index.vue_vue_type_script_setup_true_lang-oQIsvp3z.js";import"./content-EVcCkwrA.js";import"./content.vue_vue_type_script_setup_true_lang-BfxH3-y0.js";import"./attr.vue_vue_type_script_setup_true_lang-eatfXr14.js";import"./content-BllhP0mX.js";import"./attr.vue_vue_type_script_setup_true_lang-CI94iDCk.js";import"./content.vue_vue_type_script_setup_true_lang-B8njkPyY.js";import"./attr.vue_vue_type_script_setup_true_lang-11IwTsyi.js";import"./content-CHnmxWDT.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{J as y,s as g}from"./element-plus-8nG574Ul.js";import{e as b}from"./index-DwBN4Vy9.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-D_tJqBgC.js";import{e as b}from"./index-B9vchYqI.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 E,B as C,G as F,I as N,C as B,D as z}from"./element-plus-8nG574Ul.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-BnjXGEKw.js";import{_ as I}from"./picker-anRkbqwm.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-D_tJqBgC.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-oQIsvp3z.js";import{_ as I}from"./picker-Dd64qXUf.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 I,B as O,C as j,g as A,i as F,D as J}from"./element-plus-8nG574Ul.js";import{_ as z}from"./index-DL2R2dPV.js";import{_ as G,h as g}from"./index-C2ep5Cm2.js";import{_ as H}from"./picker-DDyyE4Hw.js";import{_ as R}from"./picker-anRkbqwm.js";import{D as S}from"./vuedraggable-C3E4D3Yv.js";import{l as h}from"./lodash-es-BADexyn7.js";import{f as T,ak as _,I as v,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,de=T({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:b}){const c=b,m=u,f=M({get:()=>m.content,set:l=>{c("update:content",l)}}),k=()=>{var l;if(((l=m.content.data)==null?void 0:l.length)<r){const e=h(m.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),c("update:content",e)}else g.msgError(`最多添加${r}张图片`)},w=l=>{var d;if(((d=m.content.data)==null?void 0:d.length)<=1)return g.msgError("最少保留一张图片");const e=h(m.content);e.data.splice(l,1),c("update:content",e)};return(l,e)=>{const d=R,y=j,i=O,E=H,U=A,C=G,B=z,D=F,N=I,$=J;return _(),v("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(d,{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?(_(),v("div",Y,[t(D,{class:"w-full",type:"primary",onClick:k},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{de as _};
|
||||
import{J as I,B as O,C as j,g as A,i as F,D as J}from"./element-plus-D_tJqBgC.js";import{_ as z}from"./index-fYTl8bPL.js";import{c as G,i as g}from"./index-CLJhkNLF.js";import{_ as H}from"./picker-C8lFmPfc.js";import{_ as R}from"./picker-Dd64qXUf.js";import{D as S}from"./vuedraggable-C3E4D3Yv.js";import{l as v}from"./lodash-es-BADexyn7.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:b}){const d=b,m=u,f=M({get:()=>m.content,set:l=>{d("update:content",l)}}),k=()=>{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:k},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{ce 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-8nG574Ul.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-CEl0QgUO.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-D_tJqBgC.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-Clj0RWzm.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 V,B as w,C as x,D as b}from"./element-plus-8nG574Ul.js";import{_ as g}from"./picker-anRkbqwm.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-D_tJqBgC.js";import{_ as g}from"./picker-Dd64qXUf.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{J as j,B as A,C as F,g as J,i as S,D as z}from"./element-plus-8nG574Ul.js";import{_ as G}from"./index-DL2R2dPV.js";import{_ as H,h as k}from"./index-C2ep5Cm2.js";import{_ as R}from"./picker-DDyyE4Hw.js";import{_ as T}from"./picker-anRkbqwm.js";import{D as q}from"./vuedraggable-C3E4D3Yv.js";import{l as v}from"./lodash-es-BADexyn7.js";import{f as K,ak as c,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,d=m,g=M({get:()=>d.content,set:a=>{p("update:content",a)}}),w=()=>{var a;if(((a=d.content.data)==null?void 0:a.length)<f){const e=v(d.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),p("update:content",e)}else k.msgError(`最多添加${f}张图片`)},E=a=>{var i;if(((i=d.content.data)==null?void 0:i.length)<=1)return k.msgError("最少保留一张图片");const e=v(d.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 c(),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})=>[(c(),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"?(c(),u(U,{key:0,modelValue:t.link,"onUpdate:modelValue":l=>t.link=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0),m.type=="pc"?(c(),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?(c(),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-D_tJqBgC.js";import{_ as G}from"./index-fYTl8bPL.js";import{c as H,i as k}from"./index-CLJhkNLF.js";import{_ as R}from"./picker-C8lFmPfc.js";import{_ as T}from"./picker-Dd64qXUf.js";import{D as q}from"./vuedraggable-C3E4D3Yv.js";import{l as v}from"./lodash-es-BADexyn7.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,G as F,I as N,B as O,P as U,Q as g,D as C}from"./element-plus-8nG574Ul.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-CEl0QgUO.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-D_tJqBgC.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-Clj0RWzm.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{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-in0U3QZ2.js";import"./element-plus-8nG574Ul.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DjZJwqFA.js";import"./index-C2ep5Cm2.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./role-BmH2pKEX.js";import"./index-D0lFf8Hm.js";export{o as default};
|
||||
import{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-BnGNjPtr.js";import"./element-plus-D_tJqBgC.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-BTLLBcs4.js";import"./index-CLJhkNLF.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./role-CxO4EoT5.js";import"./index-B5YfXeiX.js";export{o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{D as I,s as q,B as G,H as J,$ as M,L as O}from"./element-plus-8nG574Ul.js";import{m as U}from"./menu-DjZJwqFA.js";import{a as $}from"./role-BmH2pKEX.js";import{P as j}from"./index-D0lFf8Hm.js";import{v as z}from"./index-C2ep5Cm2.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 Z,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 $(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=>Z(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 _};
|
||||
import{D as I,s as q,B as G,H as J,$ as M,L as O}from"./element-plus-D_tJqBgC.js";import{m as U}from"./menu-BTLLBcs4.js";import{a as $}from"./role-CxO4EoT5.js";import{P as j}from"./index-B5YfXeiX.js";import{w as z}from"./index-CLJhkNLF.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 Z,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 $(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=>Z(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-8nG574Ul.js";import{_ as j}from"./index.vue_vue_type_script_setup_true_lang-DaV3Y2dz.js";import{f as q}from"./index-C2ep5Cm2.js";import{_ as A}from"./index.vue_vue_type_script_setup_true_lang-DoXxnlIX.js";import{w as G}from"./@vue/runtime-dom-iFk_KP8y.js";import{a as M,g as H}from"./finance-ChtrSqTA.js";import{u as W}from"./useDictOptions-ilx0zkz5.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-DLqm99Vy.js";import"./lodash-es-BADexyn7.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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-D_tJqBgC.js";import{_ as j}from"./index.vue_vue_type_script_setup_true_lang-B2L9Hbb9.js";import{h as q}from"./index-CLJhkNLF.js";import{_ as A}from"./index.vue_vue_type_script_setup_true_lang-Bn4hGFEd.js";import{w as G}from"./@vue/runtime-dom-iFk_KP8y.js";import{a as M,g as H}from"./finance-D2z713BN.js";import{u as W}from"./useDictOptions-K1FBl8D4.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-CmwKjXis.js";import"./lodash-es-BADexyn7.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-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.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};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user