This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
// 工单统计
|
||||
function ticketStatistic(params) {
|
||||
return Axios.get(`/ticket/statistic`, { params });
|
||||
}
|
||||
// 工单列表
|
||||
function ticketList(params) {
|
||||
return Axios.get(`/ticket`, { params });
|
||||
}
|
||||
|
||||
// 工单类型
|
||||
function ticketType(params) {
|
||||
return Axios.get(`/ticket/type`, { params });
|
||||
}
|
||||
// 获取产品列表
|
||||
function hostAll(params) {
|
||||
return Axios.get(`/host`, { params });
|
||||
}
|
||||
|
||||
// 创建工单
|
||||
function createTicket(params) {
|
||||
return Axios.post(`/ticket`, params);
|
||||
}
|
||||
|
||||
// 关闭工单
|
||||
function closeTicket(params) {
|
||||
return Axios.put(`/ticket/${params.id}/close`, params);
|
||||
}
|
||||
// 催单
|
||||
function urgeTicket(params) {
|
||||
return Axios.put(`/ticket/${params.id}/urge`, params);
|
||||
}
|
||||
// 查看工单
|
||||
function ticketDetail(params) {
|
||||
return Axios.get(`/ticket/${params.id}`, { params });
|
||||
}
|
||||
|
||||
// 回复工单
|
||||
function replyTicket(params) {
|
||||
return Axios.post(`/ticket/${params.id}/reply`, params);
|
||||
}
|
||||
// 文件下载
|
||||
function downloadFile(params) {
|
||||
return Axios.post(`ticket/download`, params);
|
||||
}
|
||||
|
||||
// 工单状态
|
||||
function ticketStatus(params) {
|
||||
return Axios.get(`/ticket/status`, { params });
|
||||
}
|
||||
// 工单部门
|
||||
function department(params) {
|
||||
return Axios.get(`/ticket/department`, { params });
|
||||
}
|
||||
// 工单通知设置
|
||||
function getOrderConfig() {
|
||||
return Axios.get(`/ticket/config`);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
.ticket-box {
|
||||
background: #F3F3F3;
|
||||
padding: 10px;
|
||||
}
|
||||
.ticket-box .ticket-item {
|
||||
padding: 0.32rem 0.4267rem;
|
||||
margin-bottom: 0.2667rem;
|
||||
border-radius: 3px;
|
||||
background: #FFF;
|
||||
/* vant/Shadow-2 */
|
||||
box-shadow: 0px 2px 12px 0px rgba(100, 101, 102, 0.12);
|
||||
font-size: 0.3733rem;
|
||||
}
|
||||
.ticket-box .ticket-item .ticket-title {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
font-size: 0.4267rem;
|
||||
line-height: 0.64rem;
|
||||
column-gap: 0.2667rem;
|
||||
margin-bottom: 0.2667rem;
|
||||
}
|
||||
.ticket-box .ticket-item .ticket-title .title-box {
|
||||
display: flex;
|
||||
column-gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.ticket-box .ticket-item .op-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 0.2667rem;
|
||||
font-size: 0.3733rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ticket-box .ticket-item .op-box .op-text {
|
||||
cursor: pointer;
|
||||
color: var(--base-color-primary);
|
||||
}
|
||||
.ticket-box .ticket-item .op-box .op-text.danger {
|
||||
color: var(--base-color-danger);
|
||||
}
|
||||
.ticket-box .ticket-item .status-text {
|
||||
font-size: 0.3733rem;
|
||||
line-height: 0.5867rem;
|
||||
padding: 0.08rem 0.2667rem;
|
||||
border-radius: 0.08rem;
|
||||
}
|
||||
.ticket-box .ticket-item .ticket-des {
|
||||
font-size: 0.3733rem;
|
||||
line-height: 0.5867rem;
|
||||
}
|
||||
.ticket-box .ticket-item .ticket-lebal {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.all-btn-box {
|
||||
padding: 0.5333rem 0.4267rem;
|
||||
background-color: #fff;
|
||||
}
|
||||
.all-btn-box .van-button {
|
||||
border-radius: 0.16rem;
|
||||
}
|
||||
.form-select {
|
||||
padding: 0;
|
||||
margin-bottom: 0.5333rem;
|
||||
}
|
||||
.form-select .van-field__body {
|
||||
border: 1px solid #CED4DA;
|
||||
border-radius: 3px;
|
||||
padding: 0.2667rem 0.4rem;
|
||||
}
|
||||
.form-select::after {
|
||||
display: none;
|
||||
}
|
||||
.dis-item {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.renew {
|
||||
margin-left: 0.08rem;
|
||||
color: var(--base-color-primary);
|
||||
}
|
||||
.wai-filed {
|
||||
padding: 0;
|
||||
}
|
||||
.wai-filed .code-select {
|
||||
padding: 0.6933rem;
|
||||
background-color: #F3F3F3;
|
||||
font-size: 28px;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.wai-filed::after {
|
||||
display: none;
|
||||
}
|
||||
.file-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0.2667rem;
|
||||
column-gap: 0.2667rem;
|
||||
row-gap: 0.1333rem;
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
.ticket-box {
|
||||
background: #F3F3F3;
|
||||
padding: 10px;
|
||||
|
||||
.ticket-item {
|
||||
padding: .32rem .4267rem;
|
||||
margin-bottom: .2667rem;
|
||||
border-radius: 3px;
|
||||
background: #FFF;
|
||||
/* vant/Shadow-2 */
|
||||
box-shadow: 0px 2px 12px 0px rgba(100, 101, 102, 0.12);
|
||||
font-size: .3733rem;
|
||||
|
||||
.ticket-title {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
font-size: .4267rem;
|
||||
line-height: .64rem;
|
||||
column-gap: .2667rem;
|
||||
margin-bottom: .2667rem;
|
||||
|
||||
.title-box {
|
||||
display: flex;
|
||||
column-gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.op-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: .2667rem;
|
||||
font-size: .3733rem;
|
||||
flex-shrink: 0;
|
||||
|
||||
.op-text {
|
||||
cursor: pointer;
|
||||
color: var(--base-color-primary);
|
||||
|
||||
&.danger {
|
||||
color: var(--base-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.status-text {
|
||||
font-size: .3733rem;
|
||||
line-height: .5867rem;
|
||||
padding: .08rem .2667rem;
|
||||
border-radius: .08rem;
|
||||
}
|
||||
|
||||
.ticket-des {
|
||||
font-size: .3733rem;
|
||||
line-height: .5867rem;
|
||||
}
|
||||
|
||||
.ticket-lebal {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.all-btn-box {
|
||||
padding: .5333rem .4267rem;
|
||||
background-color: #fff;
|
||||
|
||||
.van-button {
|
||||
border-radius: .16rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.form-select {
|
||||
padding: 0;
|
||||
margin-bottom: .5333rem;
|
||||
|
||||
.van-field__body {
|
||||
border: 1px solid #CED4DA;
|
||||
border-radius: 3px;
|
||||
padding: 0.2667rem 0.4rem;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.dis-item {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
|
||||
}
|
||||
|
||||
.renew {
|
||||
margin-left: .08rem;
|
||||
color: var(--base-color-primary);
|
||||
}
|
||||
|
||||
|
||||
.wai-filed {
|
||||
padding: 0;
|
||||
|
||||
|
||||
.code-select {
|
||||
padding: .6933rem;
|
||||
background-color: #F3F3F3;
|
||||
font-size: 28px;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.file-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: .2667rem;
|
||||
column-gap: .2667rem;
|
||||
row-gap: .1333rem;
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
.tick-detail-page {
|
||||
background: #F6F8FB;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.top-nav {
|
||||
position: relative;
|
||||
border-bottom: 0.5px solid #E7E7E7;
|
||||
}
|
||||
.top-nav .nav-title {
|
||||
font-size: 0.48rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 0.1067rem;
|
||||
}
|
||||
.top-nav .nav-title .van-icon {
|
||||
font-size: 0.3733rem;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.top-nav .detail-box {
|
||||
z-index: 2;
|
||||
padding: 0.5333rem 0.4267rem;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
/* vant/Shadow-1 */
|
||||
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
font-size: 0.3733rem;
|
||||
}
|
||||
.top-nav .detail-box .info-item {
|
||||
margin-bottom: 0.2133rem;
|
||||
display: flex;
|
||||
column-gap: 0.5333rem;
|
||||
}
|
||||
.top-nav .detail-box .info-item .info-item-label {
|
||||
color: #878A99;
|
||||
min-width: 2rem;
|
||||
}
|
||||
.top-nav .detail-box .info-item .info-item-text {
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
color: #212529;
|
||||
}
|
||||
.top-nav .detail-box .info-item .status-tag {
|
||||
padding: 0.0533rem 0.1067rem;
|
||||
border-radius: 0.0267rem;
|
||||
}
|
||||
.ticket-content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 10px 16px;
|
||||
}
|
||||
.ticket-content .reply-item {
|
||||
margin-bottom: 0.7467rem;
|
||||
}
|
||||
.ticket-content .reply-item .reply-head {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 0.1067rem;
|
||||
}
|
||||
.ticket-content .reply-item .reply-head .reply-name {
|
||||
font-size: 0.4267rem;
|
||||
}
|
||||
.ticket-content .reply-item .reply-head .reply-time {
|
||||
font-size: 0.32rem;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg {
|
||||
margin-top: 0.2133rem;
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg .reply-item-content {
|
||||
max-width: 80%;
|
||||
font-size: 0.3733rem;
|
||||
display: inline-block;
|
||||
padding: 10px 12px;
|
||||
border-radius: 3px;
|
||||
background: #EEF4FF;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
font-size: 14px;
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg .reply-item-content a {
|
||||
color: var(--base-color-primary);
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg .reply-item-content img {
|
||||
max-width: 150px;
|
||||
max-height: 150px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg .reply-item-attachment {
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg .reply-item-attachment .reply-item-attachment-item {
|
||||
font-size: 0.32rem;
|
||||
color: var(--base-color-primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg .reply-item-attachment .reply-item-attachment-item:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.ticket-content .reply-item .reply-msg .reply-time {
|
||||
font-size: 0.32rem;
|
||||
color: #878A99;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
.ticket-content .reply-item.is-user {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.ticket-content .reply-item.is-user .reply-msg {
|
||||
text-align: right;
|
||||
}
|
||||
.ticket-content .reply-item.is-user .reply-item-content {
|
||||
background: #E3FBFA;
|
||||
text-align: left;
|
||||
}
|
||||
.ticket-content .reply-item.is-user .reply-head {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.ticket-bottom {
|
||||
background-color: #fff;
|
||||
padding: 12px;
|
||||
}
|
||||
.ticket-bottom .bottom-top {
|
||||
display: flex;
|
||||
column-gap: 0.32rem;
|
||||
justify-content: space-between;
|
||||
font-size: 0.3733rem;
|
||||
}
|
||||
.ticket-bottom .bottom-top .van-field {
|
||||
width: calc(100% - 0.8rem - 0.9867rem - 1rem);
|
||||
padding: 0;
|
||||
}
|
||||
.ticket-bottom .bottom-top .van-field .van-field__body {
|
||||
padding: 0.2133rem 0.32rem;
|
||||
border-radius: 99px;
|
||||
background: #F3F3F3;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
.ticket-bottom .bottom-top .van-field::after {
|
||||
display: none;
|
||||
}
|
||||
.ticket-bottom .bottom-top .send-btn {
|
||||
border-radius: 100px;
|
||||
}
|
||||
.ticket-bottom .file-box {
|
||||
margin-top: 0.2rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 0.2667rem;
|
||||
}
|
||||
.close-btn {
|
||||
padding: 0.2667rem 0.4267rem;
|
||||
font-size: 0.4267rem;
|
||||
line-height: 0.64rem;
|
||||
color: var(--base-color-danger);
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
.tick-detail-page {
|
||||
background: #F6F8FB;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.top-nav {
|
||||
position: relative;
|
||||
border-bottom: 0.5px solid #E7E7E7;
|
||||
|
||||
.nav-title {
|
||||
font-size: .48rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: .1067rem;
|
||||
|
||||
.van-icon {
|
||||
font-size: .3733rem;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.detail-box {
|
||||
z-index: 2;
|
||||
padding: .5333rem .4267rem;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
/* vant/Shadow-1 */
|
||||
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.10);
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
font-size: .3733rem;
|
||||
|
||||
.info-item {
|
||||
margin-bottom: .2133rem;
|
||||
display: flex;
|
||||
column-gap: .5333rem;
|
||||
|
||||
.info-item-label {
|
||||
color: #878A99;
|
||||
min-width: 2rem;
|
||||
}
|
||||
|
||||
.info-item-text {
|
||||
// 换行
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
padding: .0533rem .1067rem;
|
||||
border-radius: .0267rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ticket-content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 10px 16px;
|
||||
|
||||
.reply-item {
|
||||
margin-bottom: .7467rem;
|
||||
|
||||
|
||||
|
||||
.reply-head {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: .1067rem;
|
||||
|
||||
.reply-name {
|
||||
font-size: .4267rem;
|
||||
|
||||
}
|
||||
|
||||
.reply-time {
|
||||
font-size: .32rem;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.reply-msg {
|
||||
margin-top: .2133rem;
|
||||
|
||||
.reply-item-content {
|
||||
max-width: 80%;
|
||||
font-size: .3733rem;
|
||||
display: inline-block;
|
||||
padding: 10px 12px;
|
||||
border-radius: 3px;
|
||||
background: #EEF4FF;
|
||||
// 换行
|
||||
word-break: break-all;
|
||||
// 英文数字换行
|
||||
word-wrap: break-word;
|
||||
font-size: 14px;
|
||||
|
||||
a {
|
||||
color: var(--base-color-primary);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 150px;
|
||||
max-height: 150px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-item-attachment {
|
||||
margin-top: .2rem;
|
||||
|
||||
.reply-item-attachment-item {
|
||||
font-size: .32rem;
|
||||
color: var(--base-color-primary);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reply-time {
|
||||
font-size: .32rem;
|
||||
color: #878A99;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.is-user {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.reply-msg {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.reply-item-content {
|
||||
background: #E3FBFA;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.reply-head {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.ticket-bottom {
|
||||
background-color: #fff;
|
||||
padding: 12px;
|
||||
|
||||
.bottom-top {
|
||||
display: flex;
|
||||
column-gap: .32rem;
|
||||
justify-content: space-between;
|
||||
font-size: .3733rem;
|
||||
|
||||
.van-field {
|
||||
width: calc(100% - .8rem - .9867rem - 1rem);
|
||||
padding: 0;
|
||||
|
||||
.van-field__body {
|
||||
padding: .2133rem .32rem;
|
||||
border-radius: 99px;
|
||||
background: #F3F3F3;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.send-btn {
|
||||
border-radius: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.file-box {
|
||||
margin-top: .2rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: .2667rem;
|
||||
}
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
padding: .2667rem .4267rem;
|
||||
font-size: .4267rem;
|
||||
line-height: .64rem;
|
||||
color: var(--base-color-danger);
|
||||
cursor: pointer;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 480 B |
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
@@ -0,0 +1,442 @@
|
||||
(function (window, undefined) {
|
||||
var old_onload = window.onload;
|
||||
window.onload = function () {
|
||||
typeof old_onload == "function" && old_onload();
|
||||
window.lang = Object.assign(window.lang, window.plugin_lang);
|
||||
const { showToast } = vant;
|
||||
const app = Vue.createApp({
|
||||
components: {
|
||||
topMenu,
|
||||
curSelect,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lang: window.lang,
|
||||
// 分页
|
||||
params: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
pageSizes: [20, 50, 100],
|
||||
total: 200,
|
||||
orderby: "id",
|
||||
sort: "desc",
|
||||
keywords: "",
|
||||
status: [3],
|
||||
ticket_type_id: "",
|
||||
},
|
||||
ticketData: {
|
||||
title: "",
|
||||
ticket_type_id: "",
|
||||
host_ids: "",
|
||||
content: "",
|
||||
attachment: [],
|
||||
// 工单部门id
|
||||
admin_role_id: "",
|
||||
},
|
||||
hasApp: false,
|
||||
rules: {
|
||||
title: [
|
||||
{
|
||||
required: true,
|
||||
message: lang.ticket_tips9,
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
ticket_type_id: [
|
||||
{
|
||||
required: true,
|
||||
message: lang.ticket_tips2,
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
content: [
|
||||
{
|
||||
required: true,
|
||||
message: lang.ticket_tips6,
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
// 通用数据
|
||||
commonData: {},
|
||||
// 表格数据
|
||||
dataList: [],
|
||||
// 表格加载
|
||||
tableLoading: false,
|
||||
tableFinished: false,
|
||||
// 创建工单弹窗是否显示
|
||||
isShowDialog: false,
|
||||
// 创建工单弹窗 数据
|
||||
formData: {
|
||||
title: "",
|
||||
ticket_type_id: "",
|
||||
host_ids: [],
|
||||
content: "",
|
||||
attachment: [],
|
||||
},
|
||||
// 表单错误信息显示
|
||||
errText: "",
|
||||
// 工单类别
|
||||
ticketType: [],
|
||||
ticketStatus: [],
|
||||
// 关联产品列表
|
||||
hostList: [],
|
||||
createBtnLoading: false,
|
||||
loading: false,
|
||||
fileList: [],
|
||||
configObj: {
|
||||
ticket_notice_open: 0,
|
||||
ticket_notice_description: "",
|
||||
},
|
||||
statusIsChange: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
calcTicketType() {
|
||||
return [
|
||||
{
|
||||
value: "",
|
||||
text: lang.all,
|
||||
},
|
||||
].concat(this.ticketType);
|
||||
},
|
||||
calcStatus() {
|
||||
const arrName = [];
|
||||
this.ticketStatus.forEach((item) => {
|
||||
if (this.params.status.includes(item.id)) {
|
||||
arrName.push(item.name);
|
||||
}
|
||||
});
|
||||
return arrName.length > 1
|
||||
? arrName[0] + " +" + (arrName.length - 1).toString()
|
||||
: arrName.join("、");
|
||||
},
|
||||
calcHostName() {
|
||||
const item = this.hostList.find((item) => {
|
||||
return item.id == this.ticketData.host_ids;
|
||||
});
|
||||
if (item) {
|
||||
return item.product_name + "(" + item.name + ")";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
// 获取通用信息
|
||||
this.getCommonData();
|
||||
this.getOrderConfig();
|
||||
// 获取工单类型
|
||||
this.getTicketType();
|
||||
// 获取工单状态
|
||||
this.getTicketStatus();
|
||||
// 获取关联产品列表
|
||||
this.getHostList();
|
||||
},
|
||||
mounted() {
|
||||
this.hasApp = havePlugin("IdcsmartAppMarket");
|
||||
},
|
||||
methods: {
|
||||
handleRenew(item) {
|
||||
const hostId = item.parent_host_id || item.id;
|
||||
window.open(`/productdetail.htm?id=${hostId}`);
|
||||
},
|
||||
goBack() {
|
||||
window.history.back();
|
||||
},
|
||||
async getOrderConfig() {
|
||||
try {
|
||||
const res = await getOrderConfig();
|
||||
this.configObj = res.data.data;
|
||||
} catch (error) {}
|
||||
},
|
||||
|
||||
// 获取通用配置
|
||||
getCommonData() {
|
||||
this.commonData = JSON.parse(
|
||||
localStorage.getItem("common_set_before")
|
||||
);
|
||||
document.title =
|
||||
this.commonData.website_name + "-" + lang.ticket_label15;
|
||||
},
|
||||
handeSelecFile() {
|
||||
this.$refs.uploadRef.chooseFile();
|
||||
},
|
||||
afterRead(file) {
|
||||
const arr = [];
|
||||
if (file instanceof Array) {
|
||||
arr.push(...file);
|
||||
} else {
|
||||
arr.push(file);
|
||||
}
|
||||
this.uploadFiles(arr);
|
||||
},
|
||||
handeDelFile(file, index) {
|
||||
this.ticketData.attachment = this.ticketData.attachment.filter(
|
||||
(item) => {
|
||||
return item != file.save_name;
|
||||
}
|
||||
);
|
||||
this.fileList.splice(index, 1);
|
||||
},
|
||||
delAllFile() {
|
||||
this.ticketData.attachment = [];
|
||||
this.fileList = [];
|
||||
},
|
||||
uploadFiles(arr) {
|
||||
arr.forEach((item) => {
|
||||
const formData = new FormData();
|
||||
formData.set("file", item.file); // 这里要用set,如果用append,还是会出现一起上传的情况
|
||||
uploadFile(formData)
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
if (res.data.status === 200) {
|
||||
this.fileList.push({
|
||||
file: item.file,
|
||||
save_name: res.data.data.save_name,
|
||||
});
|
||||
this.ticketData.attachment.push(res.data.data.save_name);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast(err.data.msg);
|
||||
});
|
||||
});
|
||||
},
|
||||
initPage() {
|
||||
this.params.page = 1;
|
||||
this.dataList = [];
|
||||
// 获取列表
|
||||
this.getTicketList();
|
||||
},
|
||||
// 获取工单列表
|
||||
getTicketList() {
|
||||
this.tableLoading = true;
|
||||
ticketList(this.params)
|
||||
.then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.dataList = this.dataList.concat(res.data.data.list);
|
||||
this.tableLoading = false;
|
||||
this.params.page++;
|
||||
this.params.total = res.data.data.count;
|
||||
this.tableFinished =
|
||||
this.dataList.length >= res.data.data.count;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.tableLoading = false;
|
||||
showToast(err.data.msg);
|
||||
});
|
||||
},
|
||||
// 展示创建弹窗 并初始化弹窗数据
|
||||
showCreateDialog() {
|
||||
location.href = `addTicket.htm`;
|
||||
},
|
||||
handelMore() {},
|
||||
calcProductName(item) {
|
||||
const curTime = parseInt(new Date().getTime() / 1000);
|
||||
if (item.due_time > 0) {
|
||||
if (item.due_time <= curTime) {
|
||||
// 已到期
|
||||
return `(${lang.ticket_label21})`;
|
||||
} else if (item.due_time - curTime <= item.renewal_first_day_time) {
|
||||
// 即将到期
|
||||
return `(${item.name.slice(0, 8)}......${item.name.slice(-5)})${
|
||||
lang.ticket_label22
|
||||
}`;
|
||||
} else {
|
||||
return `(${item.name})`;
|
||||
}
|
||||
} else {
|
||||
return `(${item.name})`;
|
||||
}
|
||||
},
|
||||
calcShowRenew(item) {
|
||||
const curTime = parseInt(new Date().getTime() / 1000);
|
||||
if (
|
||||
item.due_time > 0 &&
|
||||
(item.due_time <= curTime ||
|
||||
item.due_time - curTime <= item.renewal_first_day_time)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs.ticketForm.validate().then(() => {
|
||||
this.loading = true;
|
||||
const params = { ...this.ticketData };
|
||||
params.host_ids = params.host_ids ? [params.host_ids] : [];
|
||||
createTicket(params)
|
||||
.then((res) => {
|
||||
if (res.data.status == 200) {
|
||||
const id = res.data.data.id;
|
||||
location.href = `ticketDetails.htm?id=${id}`;
|
||||
}
|
||||
this.loading = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.loading = false;
|
||||
showToast(error.data.msg);
|
||||
});
|
||||
});
|
||||
},
|
||||
statusClose() {
|
||||
if (this.statusIsChange) {
|
||||
this.initPage();
|
||||
this.statusIsChange = false;
|
||||
}
|
||||
},
|
||||
|
||||
clickStatus(item) {
|
||||
if (this.params.status.includes(item)) {
|
||||
this.params.status.splice(this.params.status.indexOf(item), 1);
|
||||
} else {
|
||||
this.params.status.push(item);
|
||||
}
|
||||
this.statusIsChange = true;
|
||||
},
|
||||
openAddTicket() {
|
||||
this.ticketData = {
|
||||
title: "",
|
||||
ticket_type_id: "",
|
||||
host_ids: "",
|
||||
content: "",
|
||||
attachment: [],
|
||||
// 工单部门id
|
||||
admin_role_id: "",
|
||||
};
|
||||
this.$refs.ticketForm && this.$refs.ticketForm.resetValidation();
|
||||
this.isShowDialog = true;
|
||||
},
|
||||
closeDialog() {
|
||||
this.delAllFile();
|
||||
this.isShowDialog = false;
|
||||
},
|
||||
hexToRgb(hex) {
|
||||
const color = hex.split("#")[1];
|
||||
const r = parseInt(color.substring(0, 2), 16);
|
||||
const g = parseInt(color.substring(2, 4), 16);
|
||||
const b = parseInt(color.substring(4, 6), 16);
|
||||
return `rgba(${r},${g},${b},0.12)`;
|
||||
},
|
||||
// 获取工单类型
|
||||
getTicketType() {
|
||||
ticketType().then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.ticketType = res.data.data.list.map((item) => {
|
||||
item.value = item.id;
|
||||
item.text = item.name;
|
||||
return item;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取工单状态列表
|
||||
getTicketStatus() {
|
||||
ticketStatus().then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.params.status = [3];
|
||||
this.ticketStatus = res.data.data.list.map((item) => {
|
||||
item.value = item.id;
|
||||
item.text = item.name;
|
||||
return item;
|
||||
});
|
||||
res.data.data.list.forEach((item) => {
|
||||
if (item.status === 0) {
|
||||
this.params.status.push(item.id);
|
||||
}
|
||||
});
|
||||
// 获取工单列表
|
||||
this.initPage();
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取产品列表
|
||||
getHostList() {
|
||||
const params = {
|
||||
keywords: "",
|
||||
status: "",
|
||||
page: 1,
|
||||
limit: 1000,
|
||||
orderby: "id",
|
||||
sort: "desc",
|
||||
scene: "ticket",
|
||||
};
|
||||
hostAll(params).then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.hostList = res.data.data.list
|
||||
.filter((item) => item.status !== "Deleted")
|
||||
.map((item) => {
|
||||
const curTime = parseInt(new Date().getTime() / 1000);
|
||||
item.isDue = item.due_time > 0 && item.due_time <= curTime;
|
||||
return item;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
chooseItem(e) {
|
||||
const val = e[0].id;
|
||||
const cur = this.hostList.filter((el) => el.id === val);
|
||||
if (this.hasApp && cur.length > 0 && cur[0].isDue) {
|
||||
this.ticketData.host_ids = "";
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转工单详情
|
||||
itemReply(record) {
|
||||
const id = record.id;
|
||||
location.href = `ticketDetails.htm?id=${id}`;
|
||||
},
|
||||
// 关闭工单
|
||||
itemClose(record) {
|
||||
const id = record.id;
|
||||
const params = {
|
||||
id,
|
||||
};
|
||||
// 调用关闭工单接口 给出结果
|
||||
closeTicket(params)
|
||||
.then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
showToast(res.data.msg);
|
||||
this.initPage();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast(err.data.msg);
|
||||
});
|
||||
},
|
||||
// 催单
|
||||
itemUrge(record) {
|
||||
const nowDate = new Date().getTime();
|
||||
const last_reply_time = record.last_urge_time * 1000;
|
||||
if (nowDate - last_reply_time < 1000 * 60 * 15) {
|
||||
showToast(lang.ticket_label16);
|
||||
return;
|
||||
}
|
||||
const id = record.id;
|
||||
const params = { id };
|
||||
// 调用催单接口 给出结果
|
||||
urgeTicket(params)
|
||||
.then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
showToast(res.data.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast(err.data.msg);
|
||||
});
|
||||
},
|
||||
|
||||
titleClick(record) {
|
||||
const id = record.id;
|
||||
location.href = `ticketDetails.htm?id=${id}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
window.directiveInfo.forEach((item) => {
|
||||
app.directive(item.name, item.fn);
|
||||
});
|
||||
app.use(vant).mount("#template");
|
||||
};
|
||||
})(window);
|
||||
@@ -0,0 +1,400 @@
|
||||
(function (window, undefined) {
|
||||
var old_onload = window.onload;
|
||||
window.onload = function () {
|
||||
window.lang = Object.assign(window.lang, window.plugin_lang);
|
||||
typeof old_onload == "function" && old_onload();
|
||||
const {showToast, showImagePreview} = vant;
|
||||
const app = Vue.createApp({
|
||||
components: {
|
||||
topMenu,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lang: window.lang,
|
||||
commonData: {},
|
||||
id: null,
|
||||
isShowMore: false,
|
||||
ticketData: {},
|
||||
// 工单类别
|
||||
ticketTypeList: [],
|
||||
// 关联产品列表
|
||||
hostList: [],
|
||||
sdasaasd: {maxHeight: ".9867rem", minHeight: 0},
|
||||
// 基本信息
|
||||
baseMsg: {
|
||||
title: "",
|
||||
type: "",
|
||||
hosts: "",
|
||||
status: "",
|
||||
create_time: "",
|
||||
color: "#0AB39C",
|
||||
},
|
||||
replyData: {
|
||||
id: null,
|
||||
content: "",
|
||||
attachment: [],
|
||||
},
|
||||
sendBtnLoading: false,
|
||||
fileList: [],
|
||||
visible: false,
|
||||
delLoading: false,
|
||||
isClose: false,
|
||||
viewer: null,
|
||||
preImg: "",
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
updated() {},
|
||||
destroyed() {},
|
||||
created() {
|
||||
// 获取通用信息
|
||||
this.getCommonData();
|
||||
|
||||
// 获取工单详情
|
||||
this.getDetails();
|
||||
this.autoRefresh();
|
||||
},
|
||||
watch: {},
|
||||
filters: {},
|
||||
methods: {
|
||||
autoRefresh() {
|
||||
setInterval(() => {
|
||||
this.getDetails();
|
||||
}, 1000 * 60);
|
||||
},
|
||||
goBack() {
|
||||
location.href = "ticket.htm";
|
||||
},
|
||||
handeSelecFile() {
|
||||
this.$refs.uploadRef.chooseFile();
|
||||
},
|
||||
afterRead(file) {
|
||||
const arr = [];
|
||||
if (file instanceof Array) {
|
||||
arr.push(...file);
|
||||
} else {
|
||||
arr.push(file);
|
||||
}
|
||||
this.uploadFiles(arr);
|
||||
},
|
||||
uploadFiles(arr) {
|
||||
arr.forEach((item) => {
|
||||
const formData = new FormData();
|
||||
formData.set("file", item.file); // 这里要用set,如果用append,还是会出现一起上传的情况
|
||||
uploadFile(formData)
|
||||
.then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.fileList.push({
|
||||
file: item.file,
|
||||
save_name: res.data.data.save_name,
|
||||
});
|
||||
this.replyData.attachment.push(res.data.data.save_name);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast(err.data.msg);
|
||||
});
|
||||
});
|
||||
},
|
||||
handeDelFile(file, index) {
|
||||
this.replyData.attachment = this.replyData.attachment.filter(
|
||||
(item) => {
|
||||
return item != file.save_name;
|
||||
}
|
||||
);
|
||||
this.fileList.splice(index, 1);
|
||||
},
|
||||
// 使 right-main 的滚动条平滑的滚动到底部
|
||||
scrollToBottom() {
|
||||
let rightMain = document.getElementsByClassName("ticket-content")[0];
|
||||
rightMain.scrollTop = rightMain.scrollHeight;
|
||||
},
|
||||
// 获取通用配置
|
||||
getCommonData() {
|
||||
this.commonData = JSON.parse(
|
||||
localStorage.getItem("common_set_before")
|
||||
);
|
||||
document.title =
|
||||
this.commonData.website_name + "-" + lang.ticket_label17;
|
||||
},
|
||||
// 返回工单列表页面
|
||||
backTicket() {
|
||||
location.href = "ticket.htm";
|
||||
},
|
||||
hexToRgb(hex) {
|
||||
const color = hex.split("#")[1];
|
||||
const r = parseInt(color.substring(0, 2), 16);
|
||||
const g = parseInt(color.substring(2, 4), 16);
|
||||
const b = parseInt(color.substring(4, 6), 16);
|
||||
return `rgba(${r},${g},${b},0.12)`;
|
||||
},
|
||||
// 获取url中的id参数然后获取工单详情信息
|
||||
getDetails() {
|
||||
let url = window.location.href;
|
||||
let getqyinfo = url.split("?")[1];
|
||||
let getqys = new URLSearchParams("?" + getqyinfo);
|
||||
let id = getqys.get("id");
|
||||
this.id = id;
|
||||
const params = {
|
||||
id,
|
||||
};
|
||||
// 调用查看工单接口
|
||||
ticketDetail(params).then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.ticketData = res.data.data.ticket;
|
||||
const replies = res.data.data.ticket.replies;
|
||||
const arrEntities = {
|
||||
lt: "<",
|
||||
gt: ">",
|
||||
nbsp: " ",
|
||||
amp: "&",
|
||||
quot: '"',
|
||||
};
|
||||
this.ticketData.replies = replies.reverse().map((item) => {
|
||||
item.content = filterXSS(item.content).replace(
|
||||
/&(lt|gt|nbsp|amp|quot);/gi,
|
||||
function (all, t) {
|
||||
return arrEntities[t];
|
||||
}
|
||||
);
|
||||
return item;
|
||||
});
|
||||
// 工单类型
|
||||
this.getTicketType();
|
||||
// 当前状态
|
||||
this.baseMsg.status = this.ticketData.status;
|
||||
// 标题
|
||||
this.baseMsg.title = this.ticketData.title;
|
||||
this.baseMsg.create_time = this.ticketData.create_time;
|
||||
this.baseMsg.color = this.ticketData.color;
|
||||
// 关联产品
|
||||
this.getHostList();
|
||||
this.$nextTick(() => {
|
||||
this.scrollToBottom();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取工单类型
|
||||
getTicketType() {
|
||||
ticketType().then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.ticketTypeList = res.data.data.list;
|
||||
this.ticketTypeList.map((item) => {
|
||||
if (item.id == this.ticketData.ticket_type_id) {
|
||||
this.baseMsg.type = item.name;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取产品列表
|
||||
getHostList() {
|
||||
const params = {
|
||||
keywords: "",
|
||||
status: "",
|
||||
page: 1,
|
||||
limit: 1000,
|
||||
orderby: "id",
|
||||
sort: "desc",
|
||||
};
|
||||
hostAll(params).then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
this.hostList = res.data.data.list;
|
||||
// let names = ""
|
||||
|
||||
let hosts = [];
|
||||
this.ticketData.host_ids.forEach((element) => {
|
||||
this.hostList.forEach((item) => {
|
||||
if (item.id == element) {
|
||||
let hostitem = {
|
||||
id: item.id,
|
||||
label: item.product_name + " (" + item.name + ")",
|
||||
};
|
||||
|
||||
hosts.push(hostitem);
|
||||
|
||||
// names += item.product_name + " (" + item.name + ")" + ","
|
||||
}
|
||||
});
|
||||
});
|
||||
// names = names.slice(0, -1)
|
||||
this.baseMsg.hosts = hosts;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 回复工单
|
||||
doReplyTicket() {
|
||||
if (this.sendBtnLoading) return;
|
||||
if (!this.replyData.content) {
|
||||
showToast(lang.ticket_label18);
|
||||
return;
|
||||
}
|
||||
|
||||
// 将content中的 /n 替换成 <br>
|
||||
this.replyData.content = this.replyData.content.replace(
|
||||
/\n/g,
|
||||
"<br>"
|
||||
);
|
||||
const params = {
|
||||
...this.replyData,
|
||||
id: this.id,
|
||||
};
|
||||
this.sendBtnLoading = true;
|
||||
replyTicket(params)
|
||||
.then((res) => {
|
||||
if (res.data.status === 200) {
|
||||
// 清空输入框
|
||||
this.replyData.content = "";
|
||||
this.replyData.attachment = [];
|
||||
this.fileList = [];
|
||||
// 重新拉取工单详情
|
||||
this.getDetails();
|
||||
}
|
||||
this.sendBtnLoading = false;
|
||||
})
|
||||
.catch((err) => {
|
||||
this.sendBtnLoading = false;
|
||||
console.log(err);
|
||||
showToast(err.data.msg);
|
||||
});
|
||||
},
|
||||
// 上传文件相关
|
||||
handleSuccess(response, file, fileList) {
|
||||
// console.log(response);
|
||||
if (response.status != 200) {
|
||||
showToast(response.msg);
|
||||
// 清空上传框
|
||||
let uploadFiles = this.$refs["fileupload"].uploadFiles;
|
||||
let length = uploadFiles.length;
|
||||
uploadFiles.splice(length - 1, length);
|
||||
} else {
|
||||
this.replyData.attachment.push(response.data.save_name);
|
||||
}
|
||||
},
|
||||
handleProgress(response) {
|
||||
console.log("response", response);
|
||||
},
|
||||
beforeRemove(file, fileList) {
|
||||
// 获取到删除的 save_name
|
||||
let save_name = file.response.data.save_name;
|
||||
this.replyData.attachment = this.replyData.attachment.filter(
|
||||
(item) => {
|
||||
return item != save_name;
|
||||
}
|
||||
);
|
||||
},
|
||||
// 附件下载
|
||||
downloadfile(item) {
|
||||
const url = item.url;
|
||||
const name = item.name;
|
||||
const type = name.substring(name.lastIndexOf(".") + 1);
|
||||
if (
|
||||
[
|
||||
"png",
|
||||
"jpg",
|
||||
"jepg",
|
||||
"jpeg",
|
||||
"JPEG",
|
||||
"bmp",
|
||||
"webp",
|
||||
"PNG",
|
||||
"JPG",
|
||||
"JEPG",
|
||||
"BMP",
|
||||
"WEBP",
|
||||
].includes(type)
|
||||
) {
|
||||
showImagePreview([url]);
|
||||
} else {
|
||||
window.open(url);
|
||||
}
|
||||
},
|
||||
showClose() {
|
||||
this.visible = true;
|
||||
},
|
||||
// 关闭工单
|
||||
doCloseTicket() {
|
||||
const params = {
|
||||
id: this.id,
|
||||
};
|
||||
this.delLoading = true;
|
||||
closeTicket(params)
|
||||
.then((res) => {
|
||||
if (res.data.status == 200) {
|
||||
showToast(res.data.msg);
|
||||
this.visible = false;
|
||||
// 重新拉取工单详情
|
||||
this.getDetails();
|
||||
}
|
||||
this.delLoading = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
showToast(error.data.msg);
|
||||
this.delLoading = false;
|
||||
});
|
||||
},
|
||||
// 载入富文本
|
||||
initTemplate() {
|
||||
tinymce.init({
|
||||
selector: "#tiny",
|
||||
language_url: "/tinymce/langs/zh_CN.js",
|
||||
language: "zh_CN",
|
||||
min_height: 400,
|
||||
width: "100%",
|
||||
plugins:
|
||||
"link lists image code table colorpicker textcolor wordcount contextmenu fullpage",
|
||||
toolbar:
|
||||
"bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image fullpage code | removeformat",
|
||||
images_upload_url: "/console/v1/upload",
|
||||
convert_urls: false,
|
||||
images_upload_handler: this.handlerAddImg,
|
||||
});
|
||||
},
|
||||
// 富文本图片上传
|
||||
handlerAddImg(blobInfo, success, failure) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const formData = new FormData();
|
||||
formData.append("file", blobInfo.blob());
|
||||
axios
|
||||
.post("/console/v1/upload", formData, {
|
||||
headers: {
|
||||
Authorization: "Bearer" + " " + localStorage.getItem("jwt"),
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
const json = {};
|
||||
if (res.status !== 200) {
|
||||
failure("HTTP Error: " + res.data.msg);
|
||||
return;
|
||||
}
|
||||
json.location = res.data.data?.image_url;
|
||||
if (!json || typeof json.location !== "string") {
|
||||
failure("Error:" + res.data.msg);
|
||||
return;
|
||||
}
|
||||
success(json.location);
|
||||
});
|
||||
});
|
||||
},
|
||||
toHost(id) {
|
||||
location.href = "/productdetail.htm?id=" + id;
|
||||
},
|
||||
hanldeImage(event) {
|
||||
console.log(event);
|
||||
if (
|
||||
event.target.nodeName == "IMG" ||
|
||||
event.target.nodeName == "img"
|
||||
) {
|
||||
const img = event.target.currentSrc;
|
||||
showImagePreview([img]);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
window.directiveInfo.forEach((item) => {
|
||||
app.directive(item.name, item.fn);
|
||||
});
|
||||
app.use(vant).mount("#template");
|
||||
};
|
||||
})(window);
|
||||
@@ -0,0 +1,196 @@
|
||||
(function () {
|
||||
const plugin_lang = {
|
||||
"zh-cn": {
|
||||
// 工单系统
|
||||
all: "全部",
|
||||
type: "类型",
|
||||
ticket_title: "工单系统",
|
||||
ticket_title2: "新建工单",
|
||||
ticket_title3: "工单详情",
|
||||
ticket_title4: "基本信息",
|
||||
ticket_title5: "沟通记录",
|
||||
ticket_title6: "关闭工单",
|
||||
ticket_text1: "待接单",
|
||||
ticket_text2: "处理中",
|
||||
ticket_text3: "待回复",
|
||||
ticket_text4: "已回复",
|
||||
ticket_text5: "已关闭",
|
||||
ticket_btn1: "新建工单",
|
||||
ticket_btn2: "查询",
|
||||
ticket_btn3: "回复",
|
||||
ticket_btn4: "催单",
|
||||
ticket_btn5: "关闭",
|
||||
ticket_btn6: "确认",
|
||||
ticket_btn7: "关闭工单",
|
||||
ticket_btn8: "发送",
|
||||
ticket_btn9: "取消",
|
||||
ticket_tips1: "请输入工单编号或标题",
|
||||
ticket_tips2: "请选择工单部门",
|
||||
ticket_tips3: "请选择工单状态",
|
||||
ticket_tips4: "请输入工单标题",
|
||||
ticket_tips5: "请选择关联产品",
|
||||
ticket_tips6: "请输入问题描述",
|
||||
ticket_tips7:
|
||||
"已收到您的催单通知,我们将尽快处理您的工单,感谢您的支持和配合",
|
||||
ticket_tips8: "请选择工单部门",
|
||||
ticket_tips9: "请输入工单标题",
|
||||
ticket_tips10: "请选择商品",
|
||||
ticket_tips11: "您将关闭工单",
|
||||
ticket_tips12: "是否继续",
|
||||
ticket_label1: "工单标题",
|
||||
ticket_label2: "工单部门",
|
||||
ticket_label3: "最近回复时间",
|
||||
ticket_label4: "状态",
|
||||
ticket_label5: "操作",
|
||||
ticket_label6: "工单标题",
|
||||
ticket_label7: "关联产品",
|
||||
ticket_label8: "详细描述",
|
||||
ticket_label9: "标题",
|
||||
ticket_label10: "提交时间",
|
||||
ticket_label11: "当前状态",
|
||||
ticket_label12: "请输入内容",
|
||||
ticket_label13: "上传文件",
|
||||
ticket_label14: "工单详情",
|
||||
ticket_label15: "工单系统",
|
||||
ticket_label16:
|
||||
"已收到您的催单通知,我们将尽快处理您的工单,感谢您的支持和配合",
|
||||
ticket_label17: "工单详情",
|
||||
ticket_label18: "请输入要回复的内容",
|
||||
ticket_label19: "短信验证",
|
||||
ticket_label20: "续费",
|
||||
ticket_label21: "已到期",
|
||||
ticket_label22: "即将到期",
|
||||
ticket_label23: "即将跳转产品详情页进行续费",
|
||||
ticket_label24: "续费完成后,请重新进入新建工单页面",
|
||||
},
|
||||
"en-us": {
|
||||
all: "all",
|
||||
type: "type",
|
||||
// Work order system
|
||||
ticket_title: "Ticket Order System",
|
||||
ticket_title2: "New ticket",
|
||||
ticket_title3: "Ticket details",
|
||||
ticket_title4: "Basic information",
|
||||
ticket_title5: "Communication Record",
|
||||
ticket_title6: "Close ticket",
|
||||
ticket_text1: "Awaiting orders",
|
||||
ticket_text2: "Processing",
|
||||
ticket_text3: "To be replied",
|
||||
ticket_text4: "Replyed",
|
||||
ticket_text5: "Close",
|
||||
ticket_btn1: "New ticket",
|
||||
ticket_btn2: "query",
|
||||
ticket_btn3: "reply",
|
||||
ticket_btn4: "Reminder",
|
||||
ticket_btn5: "Close",
|
||||
ticket_btn6: "Confirm",
|
||||
ticket_btn7: "Close ticket",
|
||||
ticket_btn8: "Send",
|
||||
ticket_btn9: "Cancel",
|
||||
ticket_tips1: "Please enter the ticket number or title",
|
||||
ticket_tips2: "Please select the ticket department",
|
||||
ticket_tips3: "Please select the ticket status",
|
||||
ticket_tips4: "Please enter the ticket title",
|
||||
ticket_tips5: "Please select related products",
|
||||
ticket_tips6: "Please enter a description of the problem",
|
||||
ticket_tips7:
|
||||
"We have received your reminder notice and we will process your work order as soon as possible. Thank you for your support and cooperation",
|
||||
ticket_tips8: "Please select the ticket department",
|
||||
ticket_tips9: "Please enter the ticket title",
|
||||
ticket_tips10: "Please select a product",
|
||||
ticket_tips11: "You will close the ticket",
|
||||
ticket_tips12: "Do you want to continue?",
|
||||
ticket_label1: "Title of ticket",
|
||||
ticket_label2: "Ticket Department",
|
||||
ticket_label3: "Last reply time",
|
||||
ticket_label4: "Status",
|
||||
ticket_label5: "Operation",
|
||||
ticket_label6: "Title of ticket",
|
||||
ticket_label7: "Associated products",
|
||||
ticket_label8: "Detailed description",
|
||||
ticket_label9: "Title",
|
||||
ticket_label10: "Submission time",
|
||||
ticket_label11: "Current status",
|
||||
ticket_label12: "Please enter content",
|
||||
ticket_label13: "Upload file",
|
||||
ticket_label14: "Ticket details",
|
||||
ticket_label15: "Ticket Order System",
|
||||
ticket_label16:
|
||||
"We have received your reminder notice and we will process your work order as soon as possible. Thank you for your support and cooperation",
|
||||
ticket_label17: "Ticket details",
|
||||
ticket_label18: "Please enter the content to be replied",
|
||||
ticket_label19: "SMS Verification",
|
||||
ticket_label20: "Renewal",
|
||||
ticket_label21: "Expired",
|
||||
ticket_label22: "Due",
|
||||
ticket_label23:
|
||||
"You will be redirected to the product details page for renewal",
|
||||
ticket_label24:
|
||||
"After renewal is completed, please re-enter the new work order page",
|
||||
},
|
||||
"zh-hk": {
|
||||
all: "全部",
|
||||
type: "類型",
|
||||
ticket_title: "工單系統",
|
||||
ticket_title2: "新建工單",
|
||||
ticket_title3: "工單詳情",
|
||||
ticket_title4: "基本資訊",
|
||||
ticket_title5: "溝通記錄",
|
||||
ticket_title6: "關閉工單",
|
||||
ticket_text1: "待接單",
|
||||
ticket_text2: "處理中",
|
||||
ticket_text3: "待回覆",
|
||||
ticket_text4: "已回覆",
|
||||
ticket_text5: "已關閉",
|
||||
ticket_btn1: "新建工單",
|
||||
ticket_btn2: "查詢",
|
||||
ticket_btn3: "回覆",
|
||||
ticket_btn4: "催單",
|
||||
ticket_btn5: "關閉",
|
||||
ticket_btn6: "確認",
|
||||
ticket_btn7: "關閉工單",
|
||||
ticket_btn8: "發送",
|
||||
ticket_btn9: "取消",
|
||||
ticket_tips1: "請輸入工單編號或標題",
|
||||
ticket_tips2: "請選擇工單部門",
|
||||
ticket_tips3: "請選擇工單狀態",
|
||||
ticket_tips4: "請輸入工單標題",
|
||||
ticket_tips5: "請選擇關聯產品",
|
||||
ticket_tips6: "請輸入問題描述",
|
||||
ticket_tips7:
|
||||
"已收到您的催單通知,我們將盡快處理您的工單,感謝您的支持與配合",
|
||||
ticket_tips8: "請選擇工單部門",
|
||||
ticket_tips9: "請輸入工單標題",
|
||||
ticket_tips10: "請選擇商品",
|
||||
ticket_tips11: "您將關閉工單",
|
||||
ticket_tips12: "是否繼續",
|
||||
ticket_label1: "工單標題",
|
||||
ticket_label2: "工單部門",
|
||||
ticket_label3: "最近回覆時間",
|
||||
ticket_label4: "狀態",
|
||||
ticket_label5: "操作",
|
||||
ticket_label6: "工單標題",
|
||||
ticket_label7: "關聯產品",
|
||||
ticket_label8: "詳細描述",
|
||||
ticket_label9: "標題",
|
||||
ticket_label10: "提交時間",
|
||||
ticket_label11: "當前狀態",
|
||||
ticket_label12: "請輸入內容",
|
||||
ticket_label13: "上傳檔案",
|
||||
ticket_label14: "工單明細",
|
||||
ticket_label15: "工單系統",
|
||||
ticket_label16:
|
||||
"已收到您的催單通知,我們將盡快處理您的工單,感謝您的支持與配合",
|
||||
ticket_label17: "工單明細",
|
||||
ticket_label18: "請輸入要回覆的內容",
|
||||
ticket_label19: "簡訊驗證",
|
||||
ticket_label20: "續費",
|
||||
ticket_label21: "已到期",
|
||||
ticket_label22: "即將到期",
|
||||
ticket_label23: "即將跳轉產品詳情頁進行續費",
|
||||
ticket_label24: "續費完成後,請重新進入新建工單頁面",
|
||||
},
|
||||
};
|
||||
const DEFAULT_LANG = localStorage.getItem("lang") || "zh-cn";
|
||||
window.plugin_lang = plugin_lang[DEFAULT_LANG];
|
||||
})();
|
||||
@@ -0,0 +1,144 @@
|
||||
<!-- 页面引入样式位置 -->
|
||||
<link rel="stylesheet" href="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/css/ticket.css">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="template" v-cloak>
|
||||
<top-menu neednav>
|
||||
<template #left>
|
||||
<van-icon @click="goBack" class="left-icon" name="arrow-left"></van-icon>
|
||||
</template>
|
||||
<template #center>
|
||||
<div class="nav-title">{{lang.ticket_title}}</div>
|
||||
</template>
|
||||
<template #right>
|
||||
</template>
|
||||
</top-menu>
|
||||
<form action="/">
|
||||
<van-search class="search-input" v-model="params.keywords" :placeholder="lang.ticket_tips1" @search="initPage">
|
||||
<template #left>
|
||||
<van-dropdown-menu>
|
||||
<van-dropdown-item :title="params.ticket_type_id ? '': lang.type" @change="initPage"
|
||||
v-model="params.ticket_type_id" :options="calcTicketType">
|
||||
</van-dropdown-item>
|
||||
<van-dropdown-item @close="statusClose"
|
||||
:title="params.status.length !== 0 ? calcStatus : lang.ticket_label4" ref="statusDropdown">
|
||||
<van-cell v-for="(item, index) in ticketStatus" @click="clickStatus(item.id)">
|
||||
<template #title>
|
||||
<span
|
||||
:style="{'color': params.status.includes(item.id) ? 'var(--base-color-primary)' : ''}">{{item.name}}</span>
|
||||
</template>
|
||||
<template #right-icon v-if="params.status.includes(item.id)">
|
||||
<van-icon name="success" style="color: var(--base-color-primary);">
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</template>
|
||||
</van-search>
|
||||
<div class="ticket-box">
|
||||
<template v-if="dataList.length !== 0">
|
||||
<van-list v-model:loading="tableLoading" :finished="tableFinished" @load="getTicketList"
|
||||
:immediate-check="false">
|
||||
<div v-for="(item,index) in dataList" class="ticket-item" @click="itemReply(item)">
|
||||
<div class="ticket-title">
|
||||
<div class="title-box">
|
||||
<span>{{'#' + item.ticket_num + "-" + item.title }}</span>
|
||||
<span class="status-text"
|
||||
:style="{background:hexToRgb(item.color),color:item.color}">{{item.status}}</span>
|
||||
</div>
|
||||
<div class="op-box">
|
||||
<span class="op-text" @click.stop="itemUrge(item)"
|
||||
v-if="item.status_id !== 4">{{lang.ticket_btn4}}</span>
|
||||
<span class="op-text danger" @click.stop="itemClose(item)"
|
||||
v-if="item.status_id !== 4">{{lang.ticket_btn5}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ticket-des">
|
||||
<span class="ticket-lebal">{{lang.ticket_label2}}:</span>
|
||||
<span class="ticket-value">{{item.name || '--'}}</span>
|
||||
</div>
|
||||
<div class="ticket-des">
|
||||
<span class="ticket-lebal">{{lang.ticket_label3}}:</span>
|
||||
<span class="ticket-value" v-time="item.last_reply_time">{{item.last_reply_time || '--'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</template>
|
||||
<van-empty v-else></van-empty>
|
||||
</div>
|
||||
<van-sticky position="bottom">
|
||||
<div class="all-btn-box">
|
||||
<van-button @click="openAddTicket" type="primary" block>{{lang.ticket_btn1}}</van-button>
|
||||
</div>
|
||||
</van-sticky>
|
||||
</form>
|
||||
<!-- 新建工单 -->
|
||||
<van-popup v-model:show="isShowDialog" round closeable style="width: 90%;" @close="closeDialog">
|
||||
<div class="common-pop-box">
|
||||
<div class="common-pop-title">{{lang.ticket_btn1}}</div>
|
||||
<div class="common-pop-body">
|
||||
<van-form ref="ticketForm">
|
||||
<cur-select label-align="top" :label="lang.ticket_label2" cur-class="form-select"
|
||||
v-model:firpick="ticketData.ticket_type_id" :columns="ticketType" :rules="rules.ticket_type_id"
|
||||
:placeholder="lang.ticket_tips2" :columns-names=" { text: 'name', value: 'id' }" right-icon="arrow">
|
||||
</cur-select>
|
||||
<van-field label-align="top" class="form-select" v-model="ticketData.title" :rules="rules.title"
|
||||
:label="lang.ticket_label6" :placeholder="lang.ticket_tips9 ">
|
||||
</van-field>
|
||||
<cur-select label-align="top" :text="calcHostName" :label="lang.ticket_label7" cur-class="form-select"
|
||||
@change="chooseItem" v-model:firpick="ticketData.host_ids" :columns="hostList" :rules="rules.host_ids"
|
||||
:placeholder="lang.ticket_tips10" :columns-names=" { text: 'name', value: 'id' }" right-icon="arrow">
|
||||
<template #option="option">
|
||||
<div style="text-align: center;">
|
||||
<span v-if="!hasApp">
|
||||
{{option.product_name}}
|
||||
<template v-if="option.dedicate_ip || option.name">
|
||||
({{ option.dedicate_ip ? option.dedicate_ip : option.name ? option.name : "--"}})
|
||||
</template>
|
||||
</span>
|
||||
<span v-else
|
||||
:class="{'dis-item': option.isDue}">{{option.product_name + calcProductName(option)}}</span>
|
||||
<span v-if="calcShowRenew(option) && hasApp" class="renew"
|
||||
@click="handleRenew(option)">{{lang.ticket_label20}}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</cur-select>
|
||||
<van-field label-align="top" type="textarea" class="form-select" v-model="ticketData.content"
|
||||
:rules="rules.content" :label="lang.ticket_label8" :placeholder="lang.ticket_label12" maxlength="3000">
|
||||
</van-field>
|
||||
<van-field class="wai-filed" :label="lang.ticket_label13" label-align="top" readonly>
|
||||
<template #input>
|
||||
<div class="code-select" @click="handeSelecFile">
|
||||
<van-icon name="plus"></van-icon>
|
||||
</div>
|
||||
<van-uploader :after-read="afterRead" ref="uploadRef" multiple accept="*" v-show="false">
|
||||
</van-uploader>
|
||||
</template>
|
||||
</van-field>
|
||||
<div class="file-box">
|
||||
<van-tag v-for="(item,index) in fileList" class="file-item" :show="true" closeable size="medium"
|
||||
type="primary" @close="handeDelFile(item,index)">
|
||||
{{item.file.name}}
|
||||
</van-tag>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
<div class="common-pop-fotter">
|
||||
<van-button class="can-btn" block @click="closeDialog">{{lang.ticket_btn9}}</van-button>
|
||||
<van-button class="sub-btn" block type="primary" @click="onSubmit" :loading="loading">
|
||||
{{lang.ticket_btn6}}
|
||||
</van-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
|
||||
<!-- =======页面独有======= -->
|
||||
<script src="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/api/ticket.js"></script>
|
||||
<script src="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/lang/index.js"></script>
|
||||
<script src="/{$template_catalog}/template/{$themes}/components/vanSelect/curSelect.js"></script>
|
||||
<script src="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/js/ticket.js"></script>
|
||||
@@ -0,0 +1,134 @@
|
||||
<!-- 页面引入样式位置 -->
|
||||
<link rel="stylesheet" href="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/css/ticketDetails.css">
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="template" v-cloak class="tick-detail-page">
|
||||
<top-menu neednav class="top-nav">
|
||||
<template #left>
|
||||
<van-icon @click="goBack" class="left-icon" name="arrow-left"></van-icon>
|
||||
</template>
|
||||
<template #center>
|
||||
<div class="nav-title" @click="isShowMore = !isShowMore">
|
||||
{{lang.ticket_label17}}
|
||||
<p class="more-text">
|
||||
{{lang.ticket_text13}}
|
||||
<van-icon :name="isShowMore ? 'arrow-up' : 'arrow-down'"></van-icon>
|
||||
</p>
|
||||
</div>
|
||||
<div class="detail-box" v-show="isShowMore">
|
||||
<div class="info-item">
|
||||
<div class="info-item-label">{{lang.ticket_label9}}:</div>
|
||||
<div class="info-item-text">{{baseMsg.title}}</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item-label">{{lang.ticket_label2}}:</div>
|
||||
<div class="info-item-text">{{baseMsg.type}}</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item-label">{{lang.ticket_label10}}:</div>
|
||||
<div class="info-item-text" v-time="baseMsg.create_time">{{baseMsg.create_time}}</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item-label">{{lang.ticket_label11}}:</div>
|
||||
<div class="info-item-text status-tag" :style="{background:hexToRgb(baseMsg.color),color:baseMsg.color}">
|
||||
{{baseMsg.status}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item-label">{{lang.ticket_label7}}:</div>
|
||||
<div class="info-item-text">
|
||||
<template v-if="baseMsg.hosts[0]">
|
||||
<a class="host-item a-text" v-for="(item,index) in baseMsg.hosts" :key="item.id"
|
||||
:href="`/productdetail.htm?id=${item.id}`">
|
||||
{{item.label}}
|
||||
<span v-if="index !== baseMsg.hosts.length - 1">、</span>
|
||||
</a>
|
||||
</template>
|
||||
<div v-else>--</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #right>
|
||||
<van-popover placement="bottom-end">
|
||||
<template #reference>
|
||||
<van-icon name="ellipsis"
|
||||
v-if="baseMsg.status != lang.ticket_text5 && ticketData.can_operate !== 0"></van-icon>
|
||||
</template>
|
||||
<div class="close-btn" @click="showClose">{{lang.ticket_btn7}}</div>
|
||||
</van-popover>
|
||||
</template>
|
||||
|
||||
</top-menu>
|
||||
<div class="ticket-content">
|
||||
<div class="reply-item" v-for="item in ticketData.replies" :key="item.create_time"
|
||||
:class="item.type === 'Client' ? 'is-user' : ''">
|
||||
<div class="reply-head">
|
||||
<div class="reply-name">
|
||||
{{item.type == 'Client'? item.client_name : item.admin_name}}
|
||||
</div>
|
||||
<div class="reply-time" v-time="item.create_time"></div>
|
||||
</div>
|
||||
<div class="reply-msg">
|
||||
<div class="reply-item-content">
|
||||
<div v-html="item.content" @click="hanldeImage($event)"></div>
|
||||
</div>
|
||||
<div class="reply-item-attachment" v-if="item.attachment.length > 0">
|
||||
<div class="reply-item-attachment-item van-ellipsis" v-for="(f,i) in item.attachment" :key="i"
|
||||
@click="downloadfile(f)">
|
||||
<span :title="f.name">
|
||||
<van-icon name="orders-o"></van-icon><span>{{f.name}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ticket-bottom">
|
||||
<div class="bottom-top">
|
||||
<van-uploader :after-read="afterRead" ref="uploadRef" multiple accept="*" v-show="false"></van-uploader>
|
||||
<van-field type="textarea" rows="1" :autosize="sdasaasd" maxlength="3000" :placeholder="lang.ticket_label12"
|
||||
v-model="replyData.content">
|
||||
</van-field>
|
||||
<van-button icon="plus" plain type="primary" @click="handeSelecFile"></van-button>
|
||||
<van-button class="send-btn" @click="doReplyTicket" type="primary"
|
||||
:loading="sendBtnLoading">{{lang.ticket_btn8}}
|
||||
</van-button>
|
||||
</div>
|
||||
<div class="file-box" v-if="fileList.length !==0">
|
||||
<van-tag v-for="(item,index) in fileList" class="file-item" :show="true" closeable size="medium" type="primary"
|
||||
@close="handeDelFile(item,index)">
|
||||
{{item.file.name}}
|
||||
</van-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 关闭工单弹窗 -->
|
||||
<van-popup v-model:show="visible" round closeable :style="{ width: '90%' }">
|
||||
<div class="common-pop-box">
|
||||
<div class="common-pop-title" style="color: var(--base-color-danger);">
|
||||
<van-icon name="warning-o"></van-icon>
|
||||
{{lang.ticket_title6}}
|
||||
</div>
|
||||
<div class="common-pop-body">
|
||||
{{lang.ticket_tips11}} {{baseMsg.title}},{{lang.ticket_tips12}}
|
||||
</div>
|
||||
<div class="common-pop-fotter">
|
||||
<van-button class="can-btn" @click="visible = false">{{lang.ticket_btn9}}</van-button>
|
||||
<van-button class="sub-btn" type="danger" @click="doCloseTicket"
|
||||
:loading="delLoading">{{ lang.ticket_btn6}}</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =======页面引入js和相关组件位置======= -->
|
||||
<script src="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/api/ticket.js"></script>
|
||||
<script src="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/lang/index.js"></script>
|
||||
<script src="/{$template_catalog}/template/{$themes}/components/vanSelect/curSelect.js"></script>
|
||||
<script src="/{$template_catalog}/template/{$themes}/lib/xss.js"></script>
|
||||
<script src="/plugins/addon/idcsmart_ticket/template/clientarea/mobile/mfm201/js/ticketDetails.js"></script>
|
||||
Reference in New Issue
Block a user