mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-28 13:31:04 +00:00
feat(订单核销): 恢复移动端核销页与 order_verific 接口,核销后进入待评价
仅开放给核销员/配送员,并补齐 page_link 与个人中心菜单契约路径。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
38c398c109
commit
2444d60cc4
@ -103,7 +103,8 @@ CRMEB 开源版(KY)移动端,基于 **uni-app(Vue 3 + `<script setup>`
|
||||
|
||||
## v8 相对 v6 的移除项
|
||||
|
||||
- `pages/admin/`(移动端商家管理)已整体移除,`api/admin.js` 一并删除,勿再引用。
|
||||
- `pages/admin/` 商家管理整包已移除(订单/商品/用户/统计等),`api/admin.js` 一并删除,勿再引用。
|
||||
- 例外:仅恢复核销页 `pages/admin/order_cancellation/index` + `api/writeoff.js`(接口 `order/order_verific`),路径为 DIY/`page_link`/个人中心菜单硬契约,勿改名。
|
||||
- Vue2 遗留的 `mixins/`(color/SendVerifyCode/sharePoster/skuSelect/debounce)已被 composables 取代或内联,勿再引用。
|
||||
|
||||
## Vue3 迁移注记
|
||||
|
||||
@ -171,6 +171,10 @@ class PublicController
|
||||
$auth['/pages/users/user_invoice_list/index'] = $invoiceStatus;
|
||||
$auth['/pages/annex/vip_paid/index'] = $svipOpen;
|
||||
$auth['/kefu/mobile_list'] = $userService;
|
||||
// 移动端核销页仅对核销员/配送员开放;已删除的商家管理页强制隐藏
|
||||
$auth['/pages/admin/order_cancellation/index'] = $userVerifyStatus || $deliveryUser;
|
||||
$auth['/pages/admin/order/index'] = false;
|
||||
$auth['/pages/admin/manage/index'] = false;
|
||||
foreach ($menusInfo as $key => &$value) {
|
||||
if (isset($value['is_show']) && $value['is_show'] == 0) {
|
||||
unset($menusInfo[$key]);
|
||||
@ -971,6 +975,10 @@ class PublicController
|
||||
$auth['/pages/users/user_invoice_list/index'] = $invoiceOpen;
|
||||
$auth['/pages/annex/vip_paid/index'] = $sVipOpen;
|
||||
$auth['/kefu/mobile_list'] = $userIsService;
|
||||
// 移动端核销页仅对核销员/配送员开放;已删除的商家管理页强制隐藏
|
||||
$auth['/pages/admin/order_cancellation/index'] = $userIsVerify || $userIsDelivery;
|
||||
$auth['/pages/admin/order/index'] = false;
|
||||
$auth['/pages/admin/manage/index'] = false;
|
||||
|
||||
// 处理主题菜单配置
|
||||
if ($themeInfo) {
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\api\controller\v1\order;
|
||||
|
||||
use app\Request;
|
||||
use app\services\order\OrderWriteOffServices;
|
||||
|
||||
/**
|
||||
* 移动端订单核销(店员/配送员)
|
||||
*/
|
||||
class OrderWriteOffController
|
||||
{
|
||||
/**
|
||||
* 查询或执行核销
|
||||
* is_confirm=0 返回订单确认信息;=1 执行核销
|
||||
* @param Request $request
|
||||
* @param OrderWriteOffServices $services
|
||||
* @return mixed
|
||||
*/
|
||||
public function orderVerific(Request $request, OrderWriteOffServices $services)
|
||||
{
|
||||
[$verifyCode, $isConfirm] = $request->postMore([
|
||||
['verify_code', ''],
|
||||
['is_confirm', 0],
|
||||
], true);
|
||||
|
||||
$verifyCode = trim((string)$verifyCode);
|
||||
if ($verifyCode === '') {
|
||||
return app('json')->fail('请输入核销码或者扫描核销二维码');
|
||||
}
|
||||
|
||||
$uid = (int)$request->uid();
|
||||
// 不允许客户端跳过权限校验(auth 固定 0)
|
||||
$orderInfo = $services->writeOffOrder($verifyCode, (int)$isConfirm, $uid, 0);
|
||||
|
||||
if ((int)$isConfirm === 0) {
|
||||
return app('json')->success([
|
||||
'order_id' => (string)($orderInfo['order_id'] ?? $orderInfo['order_no'] ?? ''),
|
||||
'order_no' => (string)($orderInfo['order_no'] ?? ''),
|
||||
'image' => (string)($orderInfo['image'] ?? ''),
|
||||
'title' => (string)($orderInfo['title'] ?? ''),
|
||||
'nickname' => (string)($orderInfo['nickname'] ?? ''),
|
||||
'verify_code' => (string)($orderInfo['verify_code'] ?? $verifyCode),
|
||||
'shipping_type' => (int)($orderInfo['shipping_type'] ?? 0),
|
||||
'pay_price' => $orderInfo['pay_price'] ?? 0,
|
||||
'total_num' => (int)($orderInfo['total_num'] ?? 0),
|
||||
]);
|
||||
}
|
||||
|
||||
return app('json')->success('核销成功');
|
||||
}
|
||||
}
|
||||
44
backend/app/api/middleware/WriteOffAuthMiddleware.php
Normal file
44
backend/app/api/middleware/WriteOffAuthMiddleware.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\api\middleware;
|
||||
|
||||
use app\services\personnel\ServicePersonnelServices;
|
||||
use app\services\system\store\SystemStoreStaffServices;
|
||||
use crmeb\interfaces\MiddlewareInterface;
|
||||
use think\Request;
|
||||
|
||||
/**
|
||||
* 移动端核销权限:核销员或配送员其一即可
|
||||
*/
|
||||
class WriteOffAuthMiddleware implements MiddlewareInterface
|
||||
{
|
||||
public function handle(Request $request, \Closure $next)
|
||||
{
|
||||
$uid = (int)$request->uid();
|
||||
if ($uid <= 0) {
|
||||
return app('json')->fail('请先登录');
|
||||
}
|
||||
|
||||
/** @var SystemStoreStaffServices $storeStaffServices */
|
||||
$storeStaffServices = app()->make(SystemStoreStaffServices::class);
|
||||
if ($storeStaffServices->verifyStatus($uid)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/** @var ServicePersonnelServices $deliveryServices */
|
||||
$deliveryServices = app()->make(ServicePersonnelServices::class);
|
||||
if ($deliveryServices->checkoutIsService($uid)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return app('json')->fail('您无核销权限,请联系管理员');
|
||||
}
|
||||
}
|
||||
@ -262,12 +262,20 @@ Route::group(function () {
|
||||
|
||||
// 代理商相关路由已迁移至 modules/distribution/route/user.php
|
||||
|
||||
/** 移动端订单核销(核销员/配送员,商城用户登录态) */
|
||||
Route::group(function () {
|
||||
Route::post('order/order_verific', [\app\api\controller\v1\order\OrderWriteOffController::class, 'orderVerific'])
|
||||
->name('orderVerific')
|
||||
->middleware(\app\api\middleware\WriteOffAuthMiddleware::class)
|
||||
->option(['real_name' => '订单核销']);
|
||||
})->option(['mark' => 'order_verific', 'mark_name' => '移动端订单核销']);
|
||||
|
||||
Route::group(function () {
|
||||
/** 佣金相关 */
|
||||
Route::get('commission', [\app\api\controller\v1\user\UserBrokerageController::class, 'commission'])->name('commission')->option(['real_name' => '推广数据']);//推广数据 昨天的佣金 累计提现金额 当前佣金
|
||||
Route::get('brokerage_rank', [\app\api\controller\v1\user\UserBrokerageController::class, 'brokerageRank'])->name('brokerageRank')->option(['real_name' => '佣金排行']);//佣金排行
|
||||
/** 用户注销 */
|
||||
Route::get('user_cancel', [\app\api\controller\v1\user\UserController::class, 'SetUserCancel'])->name('SetUserCancel')->option(['real_name' => '用户注销']);//用户注销
|
||||
Route::get('user_cancel', [\app\api\controller\v1\user\UserController::class, 'SetUserCancel'])->name('SetUserCancel')->option(['real_name' => '用户注销']);
|
||||
/** 用户浏览记录 */
|
||||
Route::get('user/visit_list', [\app\api\controller\v1\user\UserController::class, 'visitList'])->name('visitList')->option(['real_name' => '商品浏览列表']);//商品浏览列表
|
||||
Route::delete('user/visit', [\app\api\controller\v1\user\UserController::class, 'visitDelete'])->name('visitDelete')->option(['real_name' => '商品浏览记录删除']);//商品浏览记录删除
|
||||
|
||||
@ -83,7 +83,11 @@ class OrderWriteOffServices extends BaseService
|
||||
}
|
||||
|
||||
$statusCode = (string)($orderInfo['status_code'] ?? '');
|
||||
if ($statusCode === OrderCenter::STATUS_COMPLETED) {
|
||||
// 核销后进入待评价,待评价/已完成均视为已核销
|
||||
if (in_array($statusCode, [
|
||||
OrderCenter::STATUS_PENDING_REVIEW,
|
||||
OrderCenter::STATUS_COMPLETED,
|
||||
], true)) {
|
||||
throw new ApiException('该订单已被核销');
|
||||
}
|
||||
if (in_array($statusCode, [
|
||||
@ -159,50 +163,43 @@ class OrderWriteOffServices extends BaseService
|
||||
|
||||
$orderInfo['order_id'] = $orderInfo['order_no'] ?? ($orderInfo['order_id'] ?? '');
|
||||
|
||||
// 8. 执行核销:到店自提直接进入完成态,并补齐核销时间
|
||||
// 8. 执行核销:与确认收货一致,进入待评价(评价后才到已完成)
|
||||
$now = time();
|
||||
if ((int)($orderInfo['shipping_type'] ?? 0) === 2) {
|
||||
$orderPayload = is_object($orderInfo) ? $orderInfo->toArray() : (array)$orderInfo;
|
||||
$orderPayload['delivery_time'] = $now;
|
||||
$orderPayload['take_time'] = $now;
|
||||
$targetStatus = OrderCenter::STATUS_PENDING_REVIEW;
|
||||
$orderPayload = is_object($orderInfo) ? $orderInfo->toArray() : (array)$orderInfo;
|
||||
$orderPayload['delivery_time'] = $now;
|
||||
$orderPayload['take_time'] = $now;
|
||||
|
||||
/** @var OrderLifecycleServices $lifecycleServices */
|
||||
$lifecycleServices = app()->make(OrderLifecycleServices::class);
|
||||
$lifecycleServices->handleTake(
|
||||
$orderPayload,
|
||||
OrderCenter::STATUS_COMPLETED,
|
||||
'到店核销',
|
||||
'admin',
|
||||
$uid > 0 ? $uid : 0
|
||||
);
|
||||
/** @var OrderLifecycleServices $lifecycleServices */
|
||||
$lifecycleServices = app()->make(OrderLifecycleServices::class);
|
||||
$lifecycleServices->handleTake(
|
||||
$orderPayload,
|
||||
$targetStatus,
|
||||
'到店核销',
|
||||
'admin',
|
||||
$uid > 0 ? $uid : 0
|
||||
);
|
||||
|
||||
try {
|
||||
OrderTypeRegistry::getAdapter((string)($orderInfo['source_type'] ?? ''))
|
||||
->advance((string)($orderInfo['order_no'] ?? ''), OrderCenter::STATUS_COMPLETED);
|
||||
} catch (\Throwable $e) {
|
||||
$this->dao->update($orderInfo['id'], [
|
||||
'status_code' => OrderCenter::STATUS_COMPLETED,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @var OrderCenterServices $centerServices */
|
||||
$centerServices = app()->make(OrderCenterServices::class);
|
||||
$centerServices->updateRecord((string)($orderInfo['order_no'] ?? ''), [
|
||||
'delivery_time' => $now,
|
||||
'take_time' => $now,
|
||||
]);
|
||||
|
||||
$orderInfo['status_code'] = OrderCenter::STATUS_COMPLETED;
|
||||
$orderInfo['delivery_time'] = $now;
|
||||
$orderInfo['take_time'] = $now;
|
||||
} else {
|
||||
// 其他核销码订单:保持原有完成逻辑
|
||||
try {
|
||||
OrderTypeRegistry::getAdapter((string)($orderInfo['source_type'] ?? ''))
|
||||
->advance((string)($orderInfo['order_no'] ?? ''), $targetStatus);
|
||||
} catch (\Throwable $e) {
|
||||
$this->dao->update($orderInfo['id'], [
|
||||
'status_code' => OrderCenter::STATUS_COMPLETED,
|
||||
'status_code' => $targetStatus,
|
||||
]);
|
||||
$orderInfo['status_code'] = OrderCenter::STATUS_COMPLETED;
|
||||
}
|
||||
|
||||
/** @var OrderCenterServices $centerServices */
|
||||
$centerServices = app()->make(OrderCenterServices::class);
|
||||
$centerServices->updateRecord((string)($orderInfo['order_no'] ?? ''), [
|
||||
'delivery_time' => $now,
|
||||
'take_time' => $now,
|
||||
]);
|
||||
|
||||
$orderInfo['status_code'] = $targetStatus;
|
||||
$orderInfo['delivery_time'] = $now;
|
||||
$orderInfo['take_time'] = $now;
|
||||
|
||||
// 9. 核销后续处理(赠送积分、发放佣金等)
|
||||
/** @var OrderTakeServices $storeOrderTask */
|
||||
$storeOrderTask = app()->make(OrderTakeServices::class);
|
||||
|
||||
@ -917,7 +917,7 @@ CREATE TABLE IF NOT EXISTS `eb_page_link` (
|
||||
`sort` smallint NOT NULL DEFAULT '0' COMMENT '排序',
|
||||
`add_time` int NOT NULL DEFAULT '0' COMMENT '添加时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='页面链接';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=55 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='页面链接';
|
||||
|
||||
-- eb_pay_channel:支付方式字典表
|
||||
CREATE TABLE IF NOT EXISTS `eb_pay_channel` (
|
||||
|
||||
@ -28,4 +28,5 @@ INSERT INTO `eb_page_link` (`id`, `cate_id`, `type`, `name`, `url`, `param`, `ex
|
||||
(39, 20, 1, '我的收藏', '/pages/users/user_goods_collection/index', '', '', 1, 0, 1772520919),
|
||||
(40, 20, 1, '发票管理', '/pages/users/user_invoice_list/index', '', '', 1, 0, 1772520919),
|
||||
(41, 20, 1, '每日签到', '/pages/users/user_sgin/index', '', '', 1, 0, 1772520919),
|
||||
(42, 20, 1, '客服接待', '/kefu/mobile_list', '', '', 1, 0, 1772520919);
|
||||
(42, 20, 1, '客服接待', '/kefu/mobile_list', '', '', 1, 0, 1772520919),
|
||||
(54, 20, 1, '订单核销', '/pages/admin/order_cancellation/index', '', '', 1, 0, 1772520919);
|
||||
23
frontend/uni-app/src/api/writeoff.js
Normal file
23
frontend/uni-app/src/api/writeoff.js
Normal file
@ -0,0 +1,23 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
/**
|
||||
* 订单核销(店员/配送员)
|
||||
* @param {string} verify_code 核销码
|
||||
* @param {number} is_confirm 0=查询确认信息 1=执行核销
|
||||
*/
|
||||
export function orderVerific(verify_code, is_confirm = 0) {
|
||||
return request.post("order/order_verific", {
|
||||
verify_code,
|
||||
is_confirm,
|
||||
});
|
||||
}
|
||||
@ -1549,7 +1549,24 @@
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"root": "pages/admin",
|
||||
"name": "adminWriteOff",
|
||||
"pages": [{
|
||||
"path": "order_cancellation/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "订单核销",
|
||||
"app-plus": {
|
||||
// #ifdef APP-PLUS
|
||||
"titleNView": {
|
||||
"type": "default"
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
],
|
||||
"tabBar": { // 底部菜单
|
||||
|
||||
340
frontend/uni-app/src/pages/admin/order_cancellation/index.vue
Normal file
340
frontend/uni-app/src/pages/admin/order_cancellation/index.vue
Normal file
@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<view :style="colorStyle">
|
||||
<view class="OrderCancellation">
|
||||
<view class="header">
|
||||
<view class="header-title">{{ $t(`订单核销`) }}</view>
|
||||
</view>
|
||||
<view class="whiteBg">
|
||||
<view class="input">
|
||||
<input
|
||||
type="number"
|
||||
:placeholder="$t(`请输入核销码`)"
|
||||
v-model="verify_code"
|
||||
/>
|
||||
</view>
|
||||
<view class="bnt" @click="codeChange">{{ $t(`立即核销`) }}</view>
|
||||
</view>
|
||||
<!-- #ifdef MP || APP-PLUS -->
|
||||
<view class="scan" @click="scanCode">
|
||||
<image src="../static/scan.gif"></image>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<view v-if="isWeixin" class="scan" @click="scanCode">
|
||||
<image src="../static/scan.gif"></image>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view v-if="iShidden">
|
||||
<view class="WriteOff">
|
||||
<view class="pictrue">
|
||||
<image :src="orderInfo.image" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="num acea-row row-center-wrapper">
|
||||
<text>{{ orderInfo.order_id || orderInfo.order_no }}</text>
|
||||
</view>
|
||||
<view v-if="orderInfo.title" class="title line1">{{ orderInfo.title }}</view>
|
||||
<view class="tip">{{ $t(`确定要核销此订单吗`) }}</view>
|
||||
<view class="btn sure" @click="confirm">{{ $t(`确定核销`) }}</view>
|
||||
<view class="btn cancel" @click="cancel">{{ $t(`取消`) }}</view>
|
||||
</view>
|
||||
<view class="mask"></view>
|
||||
</view>
|
||||
<!-- #ifndef MP -->
|
||||
<home></home>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { orderVerific } from '@/api/writeoff.js';
|
||||
import home from '@/components/home/index.vue';
|
||||
import { toLogin } from '@/libs/login.js';
|
||||
import util from '@/utils/util.js';
|
||||
import i18n from '@/utils/lang.js';
|
||||
import { useColorTheme } from '@/composables/useColorTheme';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
// #ifdef H5
|
||||
import wechat from '@/libs/wechat.js';
|
||||
// #endif
|
||||
|
||||
const { colorStyle } = useColorTheme();
|
||||
const appStore = useAppStore();
|
||||
const { isLogin } = storeToRefs(appStore);
|
||||
|
||||
const iShidden = ref(false);
|
||||
const verify_code = ref('');
|
||||
const isWeixin = ref(false);
|
||||
const orderInfo = ref({});
|
||||
const submitting = ref(false);
|
||||
|
||||
/**
|
||||
* 从扫码结果解析核销码(兼容纯数字码 / URL 参数)
|
||||
*/
|
||||
function parseVerifyCode(raw) {
|
||||
const s = decodeURIComponent(String(raw || '')).trim();
|
||||
if (/^\d{8,12}$/.test(s)) return s;
|
||||
const byParam = s.match(/(?:verify_code|code)=(\d{8,12})/i);
|
||||
if (byParam) return byParam[1];
|
||||
const digits = s.match(/\d{8,12}/);
|
||||
return digits ? digits[0] : '';
|
||||
}
|
||||
|
||||
onLoad((options = {}) => {
|
||||
if (!isLogin.value) {
|
||||
toLogin();
|
||||
return;
|
||||
}
|
||||
// #ifdef H5
|
||||
isWeixin.value = wechat.isWeixin();
|
||||
// #endif
|
||||
if (options.verify_code) {
|
||||
verify_code.value = String(options.verify_code);
|
||||
}
|
||||
// #ifdef MP
|
||||
if (options.scene) {
|
||||
const value = util.getUrlParams(decodeURIComponent(options.scene));
|
||||
verify_code.value = value.verify_code || verify_code.value;
|
||||
}
|
||||
// #endif
|
||||
});
|
||||
|
||||
function codeChange() {
|
||||
if (submitting.value) return;
|
||||
const code = String(verify_code.value || '').trim();
|
||||
if (!code) {
|
||||
return util.Tips({ title: i18n.t(`请输入核销码`) });
|
||||
}
|
||||
if (!/^\d{8,12}$/.test(code)) {
|
||||
return util.Tips({ title: i18n.t(`请输入正确的核销码`) });
|
||||
}
|
||||
submitting.value = true;
|
||||
util.Tips({ title: i18n.t(`查询中`) });
|
||||
orderVerific(code, 0)
|
||||
.then((res) => {
|
||||
orderInfo.value = res.data || {};
|
||||
iShidden.value = true;
|
||||
})
|
||||
.catch((err) => {
|
||||
verify_code.value = '';
|
||||
util.Tips({ title: err });
|
||||
})
|
||||
.finally(() => {
|
||||
submitting.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function scanCode() {
|
||||
// #ifdef MP || APP-PLUS
|
||||
uni.scanCode({
|
||||
success(res) {
|
||||
const code = parseVerifyCode(res.path || res.result);
|
||||
if (!code) {
|
||||
return util.Tips({ title: i18n.t(`请输入正确的核销码`) });
|
||||
}
|
||||
verify_code.value = code;
|
||||
codeChange();
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
wechat
|
||||
.wechatEvevt('scanQRCode', {
|
||||
needResult: 1,
|
||||
scanType: ['qrCode', 'barCode'],
|
||||
})
|
||||
.then((res) => {
|
||||
let raw = '';
|
||||
if (res.scanType == 'WX_CODE') {
|
||||
raw = res.path || '';
|
||||
} else {
|
||||
raw = res.resultStr || res.result || '';
|
||||
}
|
||||
const code = parseVerifyCode(raw);
|
||||
if (!code) {
|
||||
return util.Tips({ title: i18n.t(`请输入正确的核销码`) });
|
||||
}
|
||||
verify_code.value = code;
|
||||
codeChange();
|
||||
})
|
||||
.catch(() => {});
|
||||
// #endif
|
||||
}
|
||||
|
||||
function confirm() {
|
||||
if (submitting.value) return;
|
||||
const code = String(verify_code.value || '').trim();
|
||||
if (!code) return;
|
||||
submitting.value = true;
|
||||
orderVerific(code, 1)
|
||||
.then((res) => {
|
||||
verify_code.value = '';
|
||||
iShidden.value = false;
|
||||
orderInfo.value = {};
|
||||
util.Tips({ title: res.msg || i18n.t(`核销成功`) });
|
||||
})
|
||||
.catch((err) => {
|
||||
util.Tips({ title: err });
|
||||
})
|
||||
.finally(() => {
|
||||
submitting.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
iShidden.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.OrderCancellation {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
background-color: var(--view-theme);
|
||||
background-image: linear-gradient(180deg, var(--view-theme) 0%, #fff 100%);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding: 72rpx 48rpx 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
.header-title {
|
||||
font-size: 56rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
letter-spacing: 4rpx;
|
||||
line-height: 1.2;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.whiteBg {
|
||||
width: 690rpx;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin: -120rpx auto 0;
|
||||
padding: 50rpx 40rpx;
|
||||
box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.06);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.input {
|
||||
background: #f5f5f5;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx 28rpx;
|
||||
|
||||
input {
|
||||
font-size: 30rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.bnt {
|
||||
margin-top: 40rpx;
|
||||
height: 86rpx;
|
||||
line-height: 86rpx;
|
||||
text-align: center;
|
||||
border-radius: 43rpx;
|
||||
background: var(--view-theme);
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.scan {
|
||||
margin: 80rpx auto 0;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.WriteOff {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 560rpx;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
z-index: 100;
|
||||
padding: 40rpx 36rpx 48rpx;
|
||||
text-align: center;
|
||||
|
||||
.pictrue {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
margin: 0 auto 24rpx;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 12rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.tip {
|
||||
margin: 36rpx 0 28rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn {
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
&.sure {
|
||||
background: var(--view-theme);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.cancel {
|
||||
margin-top: 20rpx;
|
||||
background: #f5f5f5;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 99;
|
||||
}
|
||||
</style>
|
||||
BIN
frontend/uni-app/src/pages/admin/static/scan.gif
Normal file
BIN
frontend/uni-app/src/pages/admin/static/scan.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 191 KiB |
@ -524,7 +524,10 @@ function getMyMenus() {
|
||||
let myMenu = [];
|
||||
res.data.routine_my_menus.forEach((el, index, arr) => {
|
||||
// el.name 为后端下发的菜单名,保持中文原文比较,不可包 $t
|
||||
if (el.name == "客服接待") {
|
||||
if (
|
||||
el.name == "客服接待" ||
|
||||
el.url == "/pages/admin/order_cancellation/index"
|
||||
) {
|
||||
storeMenuLocal.push(el);
|
||||
} else {
|
||||
myMenu.push(el);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user