Compare commits

..

No commits in common. 'main' and 'dev' have entirely different histories.
main ... dev

  1. 2
      .gitignore
  2. 34
      package-lock.json
  3. 1
      package.json
  4. 12
      src/apis/ec_api.js
  5. 2
      src/apis/mock.js
  6. 105
      src/apis/product.js
  7. 4
      src/apis/update.js
  8. 150
      src/components/ec_api/CardLevel.vue
  9. 25
      src/components/ec_api/CardPassword.vue
  10. 43
      src/components/ec_api/CinemaGoods.vue
  11. 192
      src/components/ec_api/MapiLockBuySelector.vue
  12. 5
      src/components/ec_api/PackageSelector.vue
  13. 185
      src/components/ec_api/TabArea.vue
  14. 203
      src/components/product/ProductAdmin.vue
  15. 7
      src/components/update/CinemaUpdate.vue
  16. 6
      src/components/update/Tips.vue
  17. 3
      src/env_config.js
  18. 6
      src/layout/components/PageAside.vue
  19. 5
      src/request/config.js
  20. 111
      src/request/index.js
  21. 11
      src/request/local.js
  22. 24
      src/request/prd.js
  23. 8
      src/router/index.js
  24. 12
      src/storage/storage.js
  25. 22
      src/store/index.js
  26. 240
      src/views/config/index.vue
  27. 342
      src/views/product/index.vue
  28. 22
      yarn.lock

2
.gitignore vendored

@ -22,5 +22,3 @@ dist-ssr
*.njsproj
*.sln
*.sw?
src/env_config.js*

34
package-lock.json generated

@ -11,17 +11,14 @@
"@element-plus/icons-vue": "^2.3.1",
"@originjs/vite-plugin-commonjs": "^1.0.3",
"@types/node": "^20.10.4",
"ace-builds": "^1.35.4",
"axios": "^1.6.2",
"element-plus": "^2.4.3",
"js-md5": "^0.8.3",
"json-editor-vue3": "^1.0.9",
"normalize.css": "^8.0.1",
"sortablejs": "^1.15.2",
"vite-plugin-commonjs": "^0.10.1",
"vue": "^3.3.8",
"vue-router": "^4.0.13",
"vue3-ace-editor": "^2.2.4",
"vuex": "^4.0.2",
"ws": "^8.16.0"
},
@ -1003,9 +1000,9 @@
}
},
"node_modules/ace-builds": {
"version": "1.37.5",
"resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.37.5.tgz",
"integrity": "sha512-VMJ4Cnhq6L9dwvOCyuyyvQuiVTSwdZC7zDKJBBBJJax0wGQ7MvzQZFoi0gMmCm2I4Zuv/ZbtwU/dlglIhCNLhw==",
"version": "1.32.2",
"resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.32.2.tgz",
"integrity": "sha512-mnJAc803p+7eeDt07r6XI7ufV7VdkpPq4gJZT8Jb3QsowkaBTVy4tdBgPrVT0WbXLm0toyEQXURKSVNj/7dfJQ==",
"license": "BSD-3-Clause"
},
"node_modules/acorn": {
@ -1808,12 +1805,6 @@
"node": ">= 0.6.0"
}
},
"node_modules/js-md5": {
"version": "0.8.3",
"resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz",
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==",
"license": "MIT"
},
"node_modules/json-editor-vue3": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/json-editor-vue3/-/json-editor-vue3-1.0.9.tgz",
@ -2176,12 +2167,6 @@
"node": ">=8.10.0"
}
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==",
"license": "MIT"
},
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@ -2634,19 +2619,6 @@
"vue": "^3.2.0"
}
},
"node_modules/vue3-ace-editor": {
"version": "2.2.4",
"resolved": "https://registry.npmmirror.com/vue3-ace-editor/-/vue3-ace-editor-2.2.4.tgz",
"integrity": "sha512-FZkEyfpbH068BwjhMyNROxfEI8135Sc+x8ouxkMdCNkuj/Tuw83VP/gStFQqZHqljyX9/VfMTCdTqtOnJZGN8g==",
"license": "MIT",
"dependencies": {
"resize-observer-polyfill": "^1.5.1"
},
"peerDependencies": {
"ace-builds": "*",
"vue": "^3"
}
},
"node_modules/vuex": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",

@ -15,7 +15,6 @@
"ace-builds": "^1.35.4",
"axios": "^1.6.2",
"element-plus": "^2.4.3",
"js-md5": "^0.8.3",
"json-editor-vue3": "^1.0.9",
"normalize.css": "^8.0.1",
"sortablejs": "^1.15.2",

@ -1,4 +1,4 @@
import {request, request_ip} from "@/request/index.js";
import request from "@/request/index.js";
export const get_ec_api_env = () => {
return request({
@ -77,7 +77,7 @@ export const get_ec_api_request_url = (req_data) => {
}
export const ec_api_send_request = (req_data) => {
return request_ip({
return request({
url: 'ec/send_request',
method: 'post',
data: {
@ -103,7 +103,7 @@ export const ec_api_get_suggest = (api_type, api, env, cid, pid, options) => {
if (options) {
req_params['options'] = options
}
return request_ip({
return request({
url: 'ec/get_suggest_params',
method: 'get',
params: req_params
@ -121,7 +121,7 @@ export const ec_api_get_suggest_timestamp = (api_type, api, env, cid, pid, optio
if (options !== null) {
req_params['options'] = options
}
return request_ip({
return request({
url: 'ec/get_suggest_params_timestamp',
method: 'get',
params: req_params
@ -129,7 +129,7 @@ export const ec_api_get_suggest_timestamp = (api_type, api, env, cid, pid, optio
}
export const ec_api_set_user_data = (req_data) => {
return request_ip({
return request({
url: 'ec/set_user_data',
method: 'post',
data: {
@ -145,7 +145,7 @@ export const ec_api_set_user_data = (req_data) => {
}
export const ec_api_clear_user_data = (req_data) => {
return request_ip({
return request({
url: 'ec/clear_user_data',
method: 'post',
data: {

@ -1,4 +1,4 @@
import {request, request_ip} from "@/request/index.js";
import request from "@/request/index.js";
export const get_overtime_show_info = (params) => {
const req_params = {

@ -1,105 +0,0 @@
import {request, request_ip} from "@/request/index.js";
// 获取项目列表
export const project_list = () => {
// console.log('project_list')
return request({
url: '/prd/project_list',
method: 'get'
})
}
// 获取产品版本列表
export const prd_list = (page_num, page_size, project = '') => {
// console.log('prd_list')
return request({
url: '/prd/prd_list',
method: 'get',
params: {
page: page_num,
page_size: page_size,
project: project
}
})
}
// 添加产品版本
export const prd_add = (params) => {
// console.log('prd_add')
const req_data = JSON.stringify({
project: params['project'],
prd_version: params['prd_version'],
prd_doc_link: params['prd_doc_link'],
prd_comment: params['prd_comment'],
is_delete: params['is_delete'],
})
return request({
url: `/prd/prd_add`,
method: 'post',
data: req_data,
})
}
// 获取产品版本列表
export const prd_get = (id) => {
// console.log('prd_get')
return request({
url: `/prd/prd_list/${id}/`,
method: 'get',
})
}
// 更新产品版本
export const prd_update = (params, id) => {
// console.log('prd_update')
const req_data = JSON.stringify({
project: params['project'],
prd_version: params['prd_version'],
prd_doc_link: params['prd_doc_link'],
prd_comment: params['prd_comment'],
is_delete: params['is_delete'],
})
return request({
url: `/prd/prd_update/${id}/`,
method: 'put',
data: req_data,
})
}
// 删除产品版本
export const prd_delete = (id) => {
// console.log('prd_delete')
return request({
url: `/prd/prd_delete/${id}/`,
method: 'delete',
})
}
// 获取历史数据
export const prd_history = (id) => {
return request({
url: `/prd/prd_history`,
method: 'get',
params: {
prd_id: id,
}
})
}
// 获取产品版本列表
export const prd_list_ax_cloud = (page_num, page_size, project = '') => {
// console.log('prd_list')
return request({
url: '/prd/prd_list/ax_cloud',
method: 'get',
params: {
page: page_num,
page_size: page_size,
project: project
}
})
}

@ -1,4 +1,4 @@
import {request, request_ip} from "@/request/index.js";
import request from "@/request/index.js";
export const cinema_list = () => {
// console.log('cinema_list')
@ -80,6 +80,6 @@ export const handle_update = (params) => {
url: '/update/update_cine/',
method: 'get',
params: params,
timeout: 6*60*1000,
timeout: 3*60*1000,
})
}

@ -1,150 +0,0 @@
<script setup>
import {ref, reactive, computed, watch, onMounted, onBeforeMount} from 'vue'
import {ec_api_set_user_data, ec_api_clear_user_data} from '@/apis/ec_api.js'
import {ElMessage} from "element-plus";
// TabArea
const props = defineProps(['level', 'data', 'base_info'])
//
const selectLevel = ref('')
const levelList = reactive([])
//
async function handle_set_user_data() {
let selectLevelData = {}
props.level.forEach((item) => {
if (item['levelId'] === selectLevel.value) {
selectLevelData = item
}
})
const req_data = {
api: props.data.path,
member_type: props.data.type,
format: props.data.format,
user_data: JSON.stringify(selectLevelData),
env: props.base_info.env,
cid: props.base_info.cinema,
pid: props.base_info.channel,
}
console.log('handle_set_user_data', req_data)
await ec_api_set_user_data(req_data).then(
(req) => {
if (req['result'] === 'success') {
ElMessage({message: '选择的卡级别已做为后续测试数据!', type: 'success'})
} else {
ElMessage({message: '设置用户选择卡级别数据失败!', type: 'error'})
}
}
).catch(
(err) => {
console.log(err)
ElMessage({message: '设置用户选择卡级别数据失败!', type: 'error'})
}
)
}
async function handle_clear_user_data() {
const req_data = {
api: props.data.path,
member_type: props.data.type,
env: props.base_info.env,
cid: props.base_info.cinema,
pid: props.base_info.channel,
}
console.log('handle_clear_user_data', req_data)
await ec_api_clear_user_data(req_data).then(
(req) => {
if (req['result'] === 'success') {
ElMessage({message: '选择的联名卡级别已清除,推荐参数将使用随机值!', type: 'success'})
} else {
ElMessage({message: '清除用户选择联名卡级别数据失败!', type: 'error'})
}
}
).catch(
(err) => {
console.log(err)
ElMessage({message: '清除用户选择联名卡级别数据失败!', type: 'error'})
}
)
}
onBeforeMount(() => {
console.log('CardLevel onBeforeMount')
console.log(props.level)
//
props.level.forEach((item) => {
levelList.push({
key: item['levelId'],
name: item['levelName'],
fee: item['initMoney'],
type: item['typeDesc'],
ticket_discount: `${item['ticketDiscount']}%`,
online: item['enableOnlineIssue'],
data: item
})
})
console.log(levelList)
})
watch(() => selectLevel.value, () => {
console.log('selectLevel.value', selectLevel.value)
handle_set_user_data()
})
</script>
<template>
<hr id="break_line"/>
<div style="font-size: 16px; font-weight: bold; color: #909399; text-align: left; margin-bottom: 10px">选择场次
<el-tooltip
class="box-item"
effect="dark"
content="点击清除选择后会将后台服务器中记录的选择内容清空,其他接口将通过随机获取的方式从此接口返回的数据中模拟参数"
placement="right"
>
<el-button size="small" style="font-weight: bold;color: #909399" @click="handle_clear_user_data">清除选择
</el-button>
</el-tooltip>
</div>
<el-form style="max-width: 600px; margin-left: 20px">
<el-form-item>
<el-radio-group v-model="selectLevel">
<el-radio-button v-for="s in levelList" :label="s.key" :value="s.key" :key="s.key">
<div style="text-align: left">
<div style="margin-top: 5px"><span>{{ s.key }}</span> -- <span style="font-weight: bold">{{ s.name }}</span> -- <span>{{s.type}}</span><span v-if="s.online=== '1'"> -- </span><span style="font-weight: bold">{{s.online === '1' ? '支持线上开': ''}}</span>
</div>
<div style="margin-top: 5px"><span>开卡费 {{ s.fee }} </span><span>&nbsp&nbsp&nbsp&nbsp{{s.renew}}</span></div>
</div>
</el-radio-button>
</el-radio-group>
</el-form-item>
</el-form>
</template>
<style scoped>
#break_line {
margin-top: 30px;
margin-bottom: 30px;
background-color: rgba(144, 147, 153, 0.5);
height: 1px;
border: none
}
:deep(.el-radio-button) {
margin-bottom: 10px;
margin-right: 15px;
}
:deep(.el-radio-button__inner) {
width: 400px;
height: 60px;
background: #ebebeb;
color: #333;
border: 0 !important;
border-radius: 10px !important;
}
</style>

@ -1,25 +0,0 @@
<script setup>
import {ref, watch} from 'vue'
const pwd = ref('123321')
const emits = defineEmits(['get_card_pwd'])
watch(() => pwd.value, () => {
console.log(pwd.value)
emits("getCardPwd", pwd.value)
})
</script>
<template>
<el-row style="margin: 20px 0 20px 0">
<el-col :span="2"><label style="font-size: 14px; margin-left: 20px">会员卡密码:</label></el-col>
<el-col :span="7">
<el-input style="margin-left: 20px" size="small" v-model="pwd"></el-input>
</el-col>
</el-row>
</template>
<style scoped>
</style>

@ -95,24 +95,11 @@ function openOptionalPackageDialog(goods_type, goods_info) {
//
function numChange(goods_id, goods_num) {
let find_in_select = false
selectGoods.value.forEach((goods) => {
if (goods.id === goods_id) {
find_in_select = true
goods['buy_num'] = goods_num
}
})
if (find_in_select === false) {
goodsList.forEach((item) => {
if (item['id'] === goods_id) {
selectGoods.value.push(item)
console.log('可选套餐', item)
if (item['show_type'] === '可选套餐') {
openOptionalPackageDialog(item['show_type'], item)
}
}
})
}
handle_set_user_data()
}
@ -132,31 +119,18 @@ const getOptionalPackageDetail = (select) => {
handle_set_user_data()
}
//
const removeOptionalPackage = (select) => {
console.log('getOptionalPackageDetail', select)
goodsDialogVisible.value = false
const g_index = selectGoods.value.indexOf(select)
console.log('g_index', g_index)
selectGoods.value.splice(g_index,1)
console.log('select', select)
console.log('removeOptionalPackage', selectGoods.value)
handle_set_user_data()
}
//
const getDiscountDetail = (discount) => {
console.log('getDiscountDetail', discount)
discountDialogVisible.value = false
discount.forEach((item) => {
selectGoods.value.forEach((select) => {
if (select.id === discount.id) {
select.discount1 = item.discount1
select.discount2 = item.discount2
}
})
})
selectGoods.value.forEach((select) => {
if (select.id === discount.id) {
select.discount1 = item.discount1
select.discount2 = item.discount2
}
})
})
console.log('getDiscountDetail-selectGoods.value', selectGoods.value)
handle_set_user_data()
}
@ -236,8 +210,7 @@ watch(() => selectGoods.value, () => {
</el-checkbox-group>
</el-form-item>
</el-form>
<PackageSelector v-if="goodsDialogVisible" @get_detail="getOptionalPackageDetail"
@remove_package="removeOptionalPackage" :is_show="goodsDialogVisible"
<PackageSelector v-if="goodsDialogVisible" @get_detail="getOptionalPackageDetail" :is_show="goodsDialogVisible"
:package="optionalPackageInfo"></PackageSelector>
<GoodsDiscount v-if="discountDialogVisible" @get_discount="getDiscountDetail" :is_show="discountDialogVisible"
:goods_array="selectGoods"></GoodsDiscount>

@ -1,192 +0,0 @@
<script setup>
import {ref, watch} from 'vue'
import {ElMessageBox} from "element-plus";
// props
const props = defineProps(['type'])
// emits
const emits = defineEmits(["getSaleType", "getPriceType"])
//
const selectSaleType = props.type === 'goods' ? ref('goods') : ref('ticket')
const selectPriceType = ref("cinema_price")
const ticketPrice = ref('20.00')
const haveServiceFee = ref(true)
const ticketQuanCheck = ref(false)
const ticketQuanNum = ref('0')
const ticketQuanValue = ref('0.00')
const ticketQuanType = ref('兑换券')
const ticketQuanTypeOptions = ref([{value: '兑换券', label: '兑换券'},{value: '抵值兑换券', label: '抵值兑换券'}, {value: '代金券', label: '代金券'}])
const goodsQuanCheck = ref(false)
const goodsQuanNum = ref('0')
const goodsQuanValue = ref('0.00')
const goodsQuanType = ref('兑换券')
const goodsQuanTypeOptions = ref([{value: '兑换券', label: '兑换券'},{value: '抵值兑换券', label: '抵值兑换券'}, {value: '代金券', label: '代金券'}])
const containTicket = ["ticket", "all"]
const containGoods = ["goods", "all"]
//
watch(() => selectSaleType.value, () => {
emits("getSaleType", selectSaleType.value)
})
watch(() => ticketQuanCheck.value, () => {
if (ticketQuanCheck.value) {
console.log("ticketQuanCheck.value", ticketQuanCheck.value, ticketQuanNum.value, ticketQuanValue.value)
if (ticketQuanNum.value === 0 || ticketQuanValue.value === 0) {
ElMessageBox.alert('请设置影票券数量和面值!', "影票券", {
confirmButtonText: '知道了',
callback: () => {
ticketQuanCheck.value = false
}
})
}
}
})
watch(() => goodsQuanCheck.value, () => {
if (goodsQuanCheck.value) {
console.log("goodsQuanCheck.value", goodsQuanCheck.value, goodsQuanNum.value, goodsQuanValue.value)
if (goodsQuanNum.value === 0 || goodsQuanValue.value === 0) {
ElMessageBox.alert('请设置卖品券数量和面值!', "卖品券", {
confirmButtonText: '知道了',
callback: () => {
goodsQuanCheck.value = false
}
})
}
}
})
//
watch(() => [selectPriceType.value, haveServiceFee.value, ticketPrice.value, ticketQuanCheck.value, ticketQuanNum.value, ticketQuanValue.value, goodsQuanCheck.value, goodsQuanNum.value, goodsQuanValue.value, goodsQuanType.value, ticketQuanType.value], () => {
emits("getPriceType", {
select_price_type: selectPriceType.value,
ticket_info: {
ticket_price: ticketPrice.value,
have_service_fee: haveServiceFee.value,
},
ticket_quan_check: ticketQuanCheck.value,
ticket_quan: {
ticket_quan_num: ticketQuanNum.value,
ticket_quan_value: ticketQuanValue.value,
ticket_quan_type: ticketQuanType.value,
},
goods_quan_check: goodsQuanCheck.value,
goods_quan: {
goods_quan_num: goodsQuanNum.value,
goods_quan_value: goodsQuanValue.value,
goods_quan_type: goodsQuanType.value,
}
})
})
</script>
<template>
<el-row type="flex" justify="start" align="middle" style="margin: 20px 0 10px 20px">
<el-col :span="1" style="font-size: 14px; font-weight: bold; color: #919399;" class="col-right">售卖类型</el-col>
<el-col :span="6" class="col-left">
<el-radio-group v-model="selectSaleType">
<el-radio label="ticket" v-if="props['type'] === 'ticket'">单影票</el-radio>
<el-radio label="goods" v-if="props['type'] === 'goods'">单卖品</el-radio>
<el-radio label="all" v-if="props['type'] === 'ticket'">影票加卖品</el-radio>
</el-radio-group>
</el-col>
</el-row>
<el-row type="flex" justify="start" align="middle" style="margin: 0 0 10px 20px">
<el-col :span="1" style="font-size: 14px; font-weight: bold; color: #919399;" class="col-right">定价方式</el-col>
<el-col :span="7" class="col-left">
<el-radio-group v-model="selectPriceType">
<el-radio label="cinema_price">影院定价</el-radio>
<el-radio label="third_price">三方定价</el-radio>
</el-radio-group>
</el-col>
</el-row>
<el-row v-if="selectPriceType === 'third_price'" type="flex" justify="start" align="middle" style="margin: 0 0 0 20px">
<el-col :span="1" style="font-size: 14px; font-weight: bold; color: #919399;" class="col-right">三方定价</el-col>
<el-col v-if="containTicket.includes(selectSaleType)" :span="8" class="col-left">
<span style="font-size: 14px">单张影票结算价</span>
<el-input-number v-model="ticketPrice" :min="0.01" :max="99999.99" :step="0.01"
controls-position="right" size="small"></el-input-number>
<el-checkbox v-model="haveServiceFee" style="margin-left: 20px">是否包含服务费</el-checkbox>
</el-col>
</el-row>
<el-row v-if="selectPriceType === 'third_price' && containTicket.includes(selectSaleType)" type="flex" justify="start" align="middle" style="margin: 0 0 0 20px">
<el-col :span="1" style="font-size: 14px; font-weight: bold; color: #919399;" class="col-right"></el-col>
<el-col :span="15" class="col-left">
<span>影票券</span>
<el-input-number v-model="ticketQuanNum" :min="0" :max="10" :step="1"
controls-position="right" size="small"></el-input-number>
<span>&nbsp张价值&nbsp</span>
<el-input-number v-model="ticketQuanValue" :min="0.00" :max="99999.99" :step="0.01"
controls-position="right" size="small"></el-input-number>
<span>&nbsp元</span>
<span style="margin-left: 20px">券类型&nbsp</span>
<el-select
v-model="ticketQuanType"
placeholder="请选择"
size="small"
style="width: 120px"
>
<el-option
v-for="item in ticketQuanTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-checkbox v-model="ticketQuanCheck" style="margin-left: 20px">使用影票券</el-checkbox>
</el-col>
</el-row>
<el-row v-if="selectPriceType === 'third_price' && containGoods.includes(selectSaleType)" type="flex" justify="start" align="middle" style="margin: 0 0 30px 20px">
<el-col :span="1" style="font-size: 14px; font-weight: bold; color: #919399;" class="col-right"></el-col>
<el-col :span="15" class="col-left">
<span>卖品券</span>
<el-input-number v-model="goodsQuanNum" :min="0" :max="10" :step="1"
controls-position="right" size="small"></el-input-number>
<span>&nbsp张价值&nbsp</span>
<el-input-number v-model="goodsQuanValue" :min="0.00" :max="99999.99" :step="0.01"
controls-position="right" size="small"></el-input-number>
<span>&nbsp元</span>
<span style="margin-left: 20px">券类型&nbsp</span>
<el-select
v-model="goodsQuanType"
placeholder="请选择"
size="small"
style="width: 120px"
>
<el-option
v-for="item in goodsQuanTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-checkbox v-model="goodsQuanCheck" style="margin-left: 20px">使用卖品券</el-checkbox>
</el-col>
</el-row>
</template>
<style scoped>
.col-right {
display: flex;
justify-content: end;
align-items: center;
height: 100%;
}
.col-left {
display: flex;
justify-content: start;
align-items: center;
height: 100%;
margin-left: 20px;
font-size: 14px;
}
</style>

@ -53,10 +53,6 @@ function finish() {
}
}
function cancel() {
emit('remove_package', props.package)
}
//
function beforeClose(done) {
if (!checkResult()) {
@ -110,7 +106,6 @@ onBeforeMount(() => {
</el-tabs>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="finish">完成</el-button>
</div>
</template>

@ -29,10 +29,7 @@ import CinemaGoods from "@/components/ec_api/CinemaGoods.vue";
import EcardLevel from "@/components/ec_api/EcardLevel.vue";
import CheckQuan from "@/components/ec_api/CheckQuan.vue";
import ApiLockBuySelector from "@/components/ec_api/ApiLockBuySelector.vue";
import MapiLockBuySelector from "@/components/ec_api/MapiLockBuySelector.vue";
import CardLevel from "@/components/ec_api/CardLevel.vue";
import CardPassword from "@/components/ec_api/CardPassword.vue";
import {md5} from "js-md5";
// store
const store = useStore()
@ -59,31 +56,6 @@ const saleType = ref('ticket')
//
const payType = ref('cash')
//
const priceType = ref({
select_price_type: "cinema_price",
ticket_info: {
ticket_price: "20",
have_service_fee: true,
},
ticket_quan_check: false,
ticket_quan: {
ticket_quan_num: 0,
ticket_quan_value: "0.00",
ticket_quan_type: "兑换券",
},
goods_quan_check: false,
goods_quan: {
goods_quan_num: 0,
goods_quan_value: "0.00",
goods_quan_type: "兑换券",
},
card_num: null,
card_password: '123321',
})
const card_pwd = ref('c8837b23ff8aaa8a2dde915473ce0991')
//
//
function handleParamsChange(newCheckedResult) {
@ -289,6 +261,7 @@ function send_request() {
send_btn.value = '发送'
ElMessage.error('获取请求结果失败!')
})
}
async function get_suggest(options = {sale_type: saleType.value, pay_type: payType.value}) {
@ -298,21 +271,6 @@ async function get_suggest(options = {sale_type: saleType.value, pay_type: payTy
const env = UserApiData.value.base_info['env']
const cid = UserApiData.value.base_info['cinema']
const pid = UserApiData.value.base_info['channel']
if (api_type === 'member') {
UserApiData.value.api[activeTab.value]['params'].forEach(p => {
if (p['param'] === 'card') {
const reg = /^\d*?$/
const result = reg.test(p['value'])
console.log('正则结果', result)
if (result) {
priceType.value['card_num'] = p['value']
}
}
})
options['pay_type'] = JSON.stringify(priceType.value)
console.log('options.pay_type', options.pay_type)
console.log('priceType.value', priceType.value)
}
await ec_api_get_suggest(api_type, api, env, cid, pid, options).then(
(res) => {
@ -348,21 +306,6 @@ async function get_timestamp(options = {sale_type: saleType.value, pay_type: pay
const env = UserApiData.value.base_info['env']
const cid = UserApiData.value.base_info['cinema']
const pid = UserApiData.value.base_info['channel']
if (api_type === 'member') {
UserApiData.value.api[activeTab.value]['params'].forEach(p => {
if (p['param'] === 'card') {
const reg = /^\d*?$/
const result = reg.test(p['value'])
console.log('正则结果', result)
if (result) {
priceType.value['card_num'] = p['value']
}
}
})
options['pay_type'] = JSON.stringify(priceType.value)
console.log('options.pay_type', options.pay_type)
console.log('priceType.value', priceType.value)
}
await ec_api_get_suggest_timestamp(api_type, api, env, cid, pid, options).then(
res => {
console.log('get_timestamp', res['timestamp'])
@ -391,11 +334,8 @@ function check_params(checked, unchecked) {
//
function get_sale_type(sale_type) {
saleType.value = sale_type
if (UserApiData.value.api[activeTab.value].path === "order/buy-goods")
saleType.value = 'goods'
console.log('sale_type', sale_type)
saleType.value = sale_type
if (UserApiData.value.api[activeTab.value].path === "seat/check-coupon") {
switch (saleType.value) {
case 'ticket':
@ -422,13 +362,6 @@ function get_sale_type(sale_type) {
break;
}
}
if (UserApiData.value.api[activeTab.value].path === "order/buy-goods") {
switch (saleType.value) {
case 'goods':
check_params(["goods"], ["play_id", "play_update_time", "seat", "lock_flag"]);
break;
}
}
get_timestamp()
get_suggest()
markIsChecked()
@ -490,73 +423,6 @@ function get_pay_type(pay_type) {
markIsChecked()
}
function setup_sale_type() {
console.log('UserApiData.value.api[activeTab.value].path', UserApiData.value.api[activeTab.value].path)
console.log('saleType.value', saleType.value)
if (UserApiData.value.api[activeTab.value].path === "order/buy-goods")
console.log('UserApiData.value.api[activeTab.value].path === "order/buy-goods"')
saleType.value = 'goods'
}
function get_sale_type_member(sale_type) {
saleType.value = sale_type
console.log('sale_type', sale_type)
if (UserApiData.value.api[activeTab.value].path === "seat/lock-buy") {
switch (saleType.value) {
case 'ticket':
check_params(["play_id", "play_update_time", "seat", "lock_flag"], ["goods", "goods_card_balance_pay", "goods_cash", "delivery_type", "delivery_location", "delivery_appoint_time", "contact_number"]);
break;
case 'goods':
check_params(["goods", "goods_card_balance_pay", "goods_cash"], ["play_id", "play_update_time", "seat", "lock_flag"]);
break;
case 'all':
check_params(["play_id", "play_update_time", "seat", "lock_flag", "goods", "goods_card_balance_pay", "goods_cash"], []);
break;
}
}
if (UserApiData.value.api[activeTab.value].path === "order/buy-goods") {
switch (saleType.value) {
case 'goods':
check_params(["goods", "goods_card_balance_pay", "goods_cash"], ["play_id", "play_update_time", "seat", "lock_flag"]);
break;
}
}
get_timestamp()
get_suggest()
markIsChecked()
}
function get_price_type_member(price_type) {
console.log('price_type', price_type)
priceType.value = price_type
console.log('get_price_type_member', price_type.value)
if (payType.value["select_price_type"] === "cinema_price") {
check_params(["is_cinema_price", "t3d_pay_amount"], ["is_split_service_fee", "seat_coupons"]);
} else {
check_params(["is_cinema_price", "t3d_pay_amount", "is_split_service_fee"], []);
}
if (payType.value["ticket_quan_check"] === true) {
check_params(["seat_coupons"], []);
} else {
check_params([], ["seat_coupons"]);
}
get_timestamp()
get_suggest()
markIsChecked()
}
function get_card_pwd(pwd) {
card_pwd.value = md5(pwd)
priceType.value['card_password'] = card_pwd.value
get_timestamp()
get_suggest()
markIsChecked()
}
//
function test() {
console.log('store.state.ecApiModule.ec_api_data', store.state.ecApiModule.ec_api_data)
@ -669,24 +535,6 @@ const levelList = computed(() => {
}
}
}
if (api.path === 'cinema/card-level-rule') {
if (api.format === 'json') {
if (api.response === '{"root": "root"}') {
return []
} else {
console.log("api.handled['res']['data']['ecardLevelData']", api.handled['res']['data']['rule'])
return api.handled['res']['data']['rule']
}
}
if (api.format === 'xml' || api.format === 'html') {
if (api.response === '<root></root>') {
return []
} else {
console.log("api.handled['res']['data']['rule']", api.handled['res']['data']['rule'])
return api.handled['res']['data']['rule']
}
}
}
return []
})
@ -706,7 +554,6 @@ watch(() => store.state.ecApiModule.ec_api_data.api, (oldValue, newValue) => {
// activeTab
watch(activeTab, () => {
console.log('watch.activeTab')
setup_sale_type()
markIsChecked()
get_timestamp()
get_suggest()
@ -781,20 +628,10 @@ const ace_options = {
>
<CheckQuan v-if="api['path'] === 'seat/check-coupon'" @getQuan="get_quan_detail" @getSaleType="get_sale_type"
:cid="UserApiData['base_info']['cinema']"></CheckQuan>
<ApiLockBuySelector v-if="api['path'] === 'seat/lock-buy' && api['type'] === 'nonmember'"
@getSaleType="get_sale_type"
<ApiLockBuySelector v-if="api['path'] === 'seat/lock-buy'" @getSaleType="get_sale_type"
@getPayType="get_pay_type" type="ticket"></ApiLockBuySelector>
<ApiLockBuySelector v-if="api['path'] === 'order/buy-goods' && api['type'] === 'nonmember'"
@getSaleType="get_sale_type"
<ApiLockBuySelector v-if="api['path'] === 'order/buy-goods'" @getSaleType="get_sale_type"
@getPayType="get_pay_type" type="goods"></ApiLockBuySelector>
<MapiLockBuySelector v-if="api['path'] === 'seat/lock-buy' && api['type'] === 'member'"
@getSaleType="get_sale_type_member"
@getPriceType="get_price_type_member" type="ticket"></MapiLockBuySelector>
<MapiLockBuySelector v-if="api['path'] === 'order/buy-goods' && api['type'] === 'member'"
@getSaleType="get_sale_type_member"
@getPriceType="get_price_type_member" type="goods"></MapiLockBuySelector>
<CardPassword v-if="api['path'] === 'card/auth' || api['path'] === 'card/regist'"
@getCardPwd="get_card_pwd"></CardPassword>
<el-table
ref='ApiTableRef'
:data="UserApiData.api[api['id']].params"
@ -846,9 +683,9 @@ const ace_options = {
<el-button type="primary" @click="send_request" :loading="req_loading" :disabled="req_loading">
{{ send_btn }}
</el-button>
<!-- <el-button @click="test" >-->
<!-- 测试-->
<!-- </el-button>-->
<!-- <el-button @click="test" >-->
<!-- 测试-->
<!-- </el-button>-->
</el-col>
<el-col :span="8">
</el-col>
@ -861,12 +698,8 @@ const ace_options = {
:base_info="UserApiData.base_info"/>
<CinemaGoods v-if="goodsList.length > 0" :goods="goodsList" :data="UserApiData.api[activeTab]"
:base_info="UserApiData.base_info"/>
<EcardLevel v-if="levelList.length > 0 && api['path'] === 'ecard/ecard-levels'" :level="levelList"
:data="UserApiData.api[activeTab]"
<EcardLevel v-if="levelList.length > 0" :level="levelList" :data="UserApiData.api[activeTab]"
:base_info="UserApiData.base_info"/>
<CardLevel v-if="levelList.length > 0 && api['path'] === 'cinema/card-level-rule'" :level="levelList"
:data="UserApiData.api[activeTab]"
:base_info="UserApiData.base_info"/>
</el-tab-pane>
</el-tabs>
<el-backtop :right="300" :bottom="100" :visibility-height="100"/>

@ -1,203 +0,0 @@
<script setup>
import {onBeforeMount, onMounted, onBeforeUnmount, reactive, ref, unref, computed} from 'vue';
import {useStore, mapGetters, mapState} from "vuex";
import {
project_list,
prd_list,
prd_add,
prd_get,
prd_update,
prd_delete,
prd_history,
prd_list_ax_cloud
} from "@/apis/product.js";
import {storage} from "@/storage/storage.js";
import {onBeforeRouteLeave} from "vue-router";
// vuex
const store = useStore()
// region
//
const fromData = reactive({
project: '全部',
})
// region
//
const tableData = ref([])
//
const projectList = ref([])
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)
//
const handleCurrentChange = (newPage) => {
currentPage.value = newPage
get_table_data(currentPage.value, pageSize.value, fromData.project)
}
const handleSizeChange = (newPageSize) => {
pageSize.value = newPageSize
get_table_data(currentPage.value, pageSize.value, fromData.project)
}
//
const submitSearch = async () => {
tableData.value = []
await get_table_data(currentPage.value, pageSize.value, fromData.project).then(
res => {
if (Array.isArray(res)) {
tableData.value = [...res]
} else {
}
}
).catch(
err => {
}
)
}
//
async function get_project_data() {
projectList.value = []
await project_list().then(res => {
if (Array.isArray(res)) {
projectList.value = [...res]
projectList.value.unshift({'id': 0, 'project_name': '全部', is_delete: false})
} else {
}
}).catch(err => {
console.log(err)
}
)
}
//
async function get_table_data(page_num = currentPage.value, page_size = pageSize.value, project_val = fromData.project) {
//
tableData.value = []
console.log('get_table_data')
console.log(project_val)
project_val = project_val === '全部' ? '' : project_val
console.log(project_val)
await prd_list_ax_cloud(page_num, page_size, project_val).then(res => {
total.value = res['count']
if (Array.isArray(res['results'])) {
tableData.value = [...res['results']]
console.log(tableData.value)
} else {
console.log('get_table_data.res is not an array')
}
}).catch(err => {
console.log(err)
}
)
}
//
onMounted(
async () => {
await get_project_data();
await get_table_data(currentPage.value, pageSize.value, fromData.project);
}
)
// endregion
</script>
<template>
<el-form
:model="fromData"
:inline="true"
class="search_form"
>
<el-form-item label="所属项目" label-width="90">
<el-select v-model="fromData.project" placeholder="请选择">
<el-option v-for="item in projectList" :key="item['project_name']" :label="item['project_name']"
:value="item['project_name']"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitSearch">搜索</el-button>
</el-form-item>
<!-- <el-button style="margin-right: 0">添加</el-button>-->
</el-form>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="project" label="所属项目" min-width="200"></el-table-column>
<el-table-column prop="prd_version" label="版本" min-width="200"></el-table-column>
<el-table-column prop="prd_doc_link" label="产品原型链接" min-width="300" show-overflow-tooltip>
<template v-slot="scope">
<a target="_blank" style="color:#007bff;" v-if="scope.row.prd_doc_link!=null"
@click="mark_read(scope.row.id, scope.row.update_at)"
v-bind:href="scope.row.prd_doc_link">
{{
scope.row.prd_doc_link.length > 30 ? scope.row.prd_doc_link.slice(0, 30) + '...' : scope.row.prd_doc_link
}}
</a>
</template>
</el-table-column>
<el-table-column prop="prd_comment" label="版本描述" min-width="260">
<template #default="{ row }">
<el-tooltip
class="item"
popper-class="custom-tooltip"
effect="dark"
:raw-content="true"
:content="row.prd_comment.split('\n').join('<br>')"
placement="top-end">
<span>{{ row.prd_comment.length > 10 ? row.prd_comment.slice(0, 10) + '...' : row.prd_comment }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="update_at" label="最后更新时间" min-width="210">
</el-table-column>
<el-table-column prop="id" label="操作" min-width="120">
<template v-slot="scope">
<el-button type="primary" size="small" @click="PrdItemEdit(scope.row.id)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50]"
size="small"
layout="sizes, prev, pager, next"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
</template>
<style>
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
.search_form {
display: flex;
justify-content: flex-start;
}
.custom-tooltip {
max-width: 500px; /* 设置最大宽度为 300px */
}
</style>

@ -3,7 +3,7 @@ import {onBeforeMount, ref, computed} from "vue";
import {useStore} from "vuex";
import {get_git_ver, get_update_alter, get_update_option, handle_update} from "@/apis/update.js"
import Tips from "@/components/update/Tips.vue"
import config from "@/request/prd.js"
import config from "@/request/config.js"
import ProcessIcon from "@/components/update/ProcessIcon.vue";
import {ElMessageBox} from "element-plus";
@ -42,7 +42,7 @@ const createWs = () => {
console.log(ws)
if (!ws) {
console.log("建立ws连接")
ws = new WebSocket(config.direct.baseWS + "/ws/update/")
ws = new WebSocket(config.baseWS + "/ws/update/")
ws.onopen = wsOpen
ws.onmessage = wsMessage
ws.onerror = wsError
@ -187,9 +187,6 @@ onBeforeMount(
console.log(res)
res.forEach(
(value, index) => {
if (value.process === "before_sys") {
updateCmd.value.setup.push(value)
}
if (value.process === "setup") {
updateCmd.value.setup.push(value)
}

@ -37,8 +37,4 @@ const props = defineProps({
</template>
<style>
.el-popover {
height: 200px;
overflow: auto;
}
</style>
</style>

@ -1,3 +0,0 @@
export default function env_config() {
return 'local'
}

@ -38,12 +38,6 @@ const route = useRoute()
</el-icon>
<span>网售接口测试</span>
</el-menu-item>
<el-menu-item index="prd">
<el-icon>
<icon-menu/>
</el-icon>
<span>产品文档</span>
</el-menu-item>
</el-menu>
</el-col>
</el-row>

@ -1,6 +1,11 @@
export default {
// method: 'get',
// baseURL: 'http://172.16.1.63:8000',
baseURL: 'http://172.16.1.168:8000',
// baseURL: 'http://127.0.0.1:8000',
// baseWS: 'ws://172.16.1.63:8000',
baseWS: 'ws://172.16.1.168:8000',
// baseWS: 'ws://127.0.0.1:8000',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': 'token 4e63b8854974c1fdac9deb891fd74dc145b53f85'

@ -1,105 +1,40 @@
import axios from "axios";
import prd from "@/request/prd.js";
import dev from "@/request/dev.js";
import local from "@/request/local.js";
import env_config from "@/env_config.js";
import config from "@/request/config.js";
// import {ElMessage} from "element-plus";
// import {rejects} from "node:assert";
// import router from "@/router";
const environment = env_config()
const config = {
'prd': {direct: {...prd.direct}, nginx: {...prd.nginx}},
'dev': {direct: {...dev}, nginx: {...dev}},
'local': {direct: {...local}, nginx: {...local}}
}
// console.log(environment, config[environment], config[environment].direct, config[environment].nginx)
export function request(options) {
const instance = axios.create({
baseURL: config[environment].direct.baseURL,
baseWS: config[environment].direct.baseWS,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': 'token 4e63b8854974c1fdac9deb891fd74dc145b53f85'
},
timeout: 60000,
withCredentials: true,
responseType: 'json',
})
function request(options) {
const instance = axios.create({...config})
options = {...options, instance} // 使用创建的实例
// 请求拦截器
instance.interceptors.request.use(config => {
// 处理请求前的逻辑...
return config
}, error => {
// 请求错误处理
return Promise.reject(error)
})
// 响应拦截器
instance.interceptors.response.use(response => {
// 处理响应数据
return response
}, error => {
// 处理响应错误
return Promise.reject(error)
})
return new Promise((resolve, reject) => {
instance(options)
.then(res => {
resolve(res.data)
// console.log(res.data)
})
.catch(err => {
reject(err)
})
})
}
instance.interceptors.request.use(
config => {
// 处理请求前的逻辑...
export function request_ip(options) {
const instance = axios.create({
baseURL: config[environment].direct.baseURL,
baseWS: config[environment].direct.baseWS,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': 'token 4e63b8854974c1fdac9deb891fd74dc145b53f85'
return config
},
timeout: 60000,
withCredentials: true,
responseType: 'json',
})
options = {...options, instance} // 使用创建的实例
// 请求拦截器
instance.interceptors.request.use(config => {
// 处理请求前的逻辑...
error => {
// 请求错误处理
return config
}, error => {
// 请求错误处理
return Promise.reject(error)
})
return Promise.reject(error)
}
)
// 响应拦截器
instance.interceptors.response.use(response => {
// 处理响应数据
instance.interceptors.response.use(
response => {
// 处理响应数据
return response
}, error => {
// 处理响应错误
return response
},
error => {
// 处理响应错误
return Promise.reject(error)
})
return Promise.reject(error)
}
)
return new Promise((resolve, reject) => {
instance(options)
@ -140,4 +75,4 @@ export function request_ip(options) {
// console.log(res)
// })
// export default request
export default request

@ -1,11 +0,0 @@
export default {
baseURL: 'http://127.0.0.1:8000',
baseWS: 'ws://127.0.0.1:8000',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': 'token 4e63b8854974c1fdac9deb891fd74dc145b53f85'
},
timeout: 60000,
withCredentials: true,
responseType: 'json',
}

@ -1,24 +0,0 @@
export default {
direct: {
baseURL: 'http://172.16.1.63:8000',
baseWS: 'ws://172.16.1.63:8000',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': 'token 4e63b8854974c1fdac9deb891fd74dc145b53f85'
},
timeout: 60000,
withCredentials: true,
responseType: 'json',
},
nginx:{
baseURL: 'http://172.16.1.222',
baseWS: 'ws://172.16.1.63:8000',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': 'token 4e63b8854974c1fdac9deb891fd74dc145b53f85'
},
timeout: 60000,
withCredentials: true,
responseType: 'json',
}
}

@ -41,14 +41,6 @@ const routes = [
meta:{
keepAlive: true,
}
},
{
path: 'prd',
name: 'Prd',
component: () => import('@/views/product/index.vue'),
meta:{
keepAlive: true,
}
}
]
}

@ -1,12 +0,0 @@
export const storage = {
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
get(key) {
const value = localStorage.getItem(key);
return value ? JSON.parse(value) : null;
},
remove(key) {
localStorage.removeItem(key);
}
}

@ -38,7 +38,7 @@ const updateModule = {
const ecApiModule = {
namespaced: true,
state: {
ec_api_data: {api: []}, // 所有api数据
ec_api_data: {api:[]}, // 所有api数据
// ec_select_api: [], // 默认选中的api
first_tab_api_id: 1,
show_tab_area: true, //是否显示表格区域
@ -76,35 +76,21 @@ const ecApiModule = {
// console.log('state.ec_api_data.api', state.ec_api_data.api)
},
handle_sort_ec_select_api: (state, payload) => {
const movedTab = state.ec_api_data.api.splice(payload.oldIndex - 1, 1)[0];
state.ec_api_data.api.splice(payload.newIndex - 1, 0, movedTab);
const movedTab = state.ec_api_data.api.splice(payload.oldIndex-1, 1)[0];
state.ec_api_data.api.splice(payload.newIndex-1, 0, movedTab);
},
add_ec_api_data: (state, payload) => {
state.ec_api_data = {api: []}
state.ec_api_data = {api:[]}
state.ec_api_data = payload
}
},
actions: {},
}
//
// const prdModule = {
// namespaced: true,
// state: {
// history_dialog_show: false,
// },
// getter: {
// dialog_change: state => {
// state.history_dialog_show = !state.history_dialog_show
// return state.history_dialog_show
// },
// },
// }
export default createStore({
modules: {
updateModule,
ecApiModule,
// prdModule,
},
})

@ -1,240 +0,0 @@
<script setup>
import {onBeforeMount, onMounted, reactive, ref, unref, computed} from 'vue';
import {useStore, mapGetters, mapState} from "vuex";
import {cinema_list, cinema_search, cinema_user, change_cinema_user, write_git_version_to_db} from "@/apis/update.js";
import CinemaUpdate from "@/components/update/CinemaUpdate.vue";
// vuex
const store = useStore()
// region
//
const cinemaSearch = reactive({
ip: '',
version: '',
})
//
const cinemaSearchRef = ref()
// ip
const ip_validate = (rule, value, callback) => {
const regex = new RegExp('((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}');
if (value === '') {
callback()
}
if (!regex.test(value)) {
callback(new Error('请输入正确的IP地址'))
} else {
callback()
}
}
// ip
const ipRule = reactive({
ip: [{validator: ip_validate, trigger: 'change'}]
})
//
const submitSearch = async (formEl) => {
const {ip, version} = unref(cinemaSearch)
tableData.value = []
await cinema_search({ip, version}).then(
res => {
if (Array.isArray(res)) {
tableData.value = [...res]
} else {
}
}
).catch(
err => {
}
)
if (!formEl) return
formEl.validate((valid) => {
if (valid) {
console.log('提交数据')
} else {
console.log('提交失败')
return false
}
})
}
//
const resetSearch = (formEl) => {
if (!formEl) return
formEl.resetFields()
}
//
const refresh = (formEL) => {
formEL.resetFields()
refresh_disable.value = true;
refresh_loading.value = true;
get_table_data()
update_git_version()
setTimeout(() => {
refresh_disable.value = false;
refresh_loading.value = false;
}, 5000)
}
// endregion
// region
const update_git_version = async () => {
await write_git_version_to_db().then(res => {
console.log(res)
}).catch(err => {
console.log(err)
}
)
}
// endregion
// region
//
const tableData = ref([])
// disableloading
let refresh_disable = ref(false)
let refresh_loading = ref(false)
//
async function get_table_data() {
tableData.value = []
await cinema_list().then(res => {
if (Array.isArray(res)) {
tableData.value = [...res]
} else {
}
}).catch(err => {
console.log(err)
}
)
}
//
onMounted(
async () => {
await get_table_data();
}
)
// endregion
// region
//
const selectedUser = ref('')
//
let userData = ref([])
//
onMounted(async () => {
await cinema_user().then((res) => {
const user_list = res.map((item, index) => {
return {key: item.id, label: item.username, value: item.username}
})
user_list.unshift({key: 0, label: '暂无', value: '暂无'})
userData.value = [...user_list]
}).catch((err) => {
})
})
const cinemaUserChange = (user, id) => {
const params = {user, id}
change_cinema_user(params).then(res => {
}).catch(err => {
})
}
// endregion
// region
const update_ip = ref('')
const ver_id = ref(0)
const changeDialogStatus = (ip, ver) => {
store.state.updateModule.update_dialog_show = true
update_ip.value = ip
ver_id.value = ver
}
// endregion
</script>
<template>
<el-form
ref="cinemaSearchRef"
:model="cinemaSearch"
status-icon
:rules="ipRule"
class="cinema-search"
>
<el-row>
<el-col :span="5">
<el-form-item label="影院IP" prop="ip" label-width="60">
<el-input v-model="cinemaSearch.ip" placeholder="请输入完整的影院IP" style="width: 180px;"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="系统版本" prop="version">
<el-input v-model="cinemaSearch.version" placeholder="支持模糊查询" style="width: 160px;"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-button type="primary" @click="submitSearch(cinemaSearchRef)">搜索</el-button>
<el-button @click="resetSearch(cinemaSearchRef)">重置</el-button>
<el-button v-bind:disabled="refresh_disable" @click="refresh(cinemaSearchRef)" v-bind:loading="refresh_loading">
刷新
</el-button>
</el-col>
</el-row>
</el-form>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="update_time" label="最后查询时间" min-width="180"></el-table-column>
<el-table-column prop="ip" label="操作" min-width="80">
<template v-slot="scope">
<el-button type="info" size="small" @click="changeDialogStatus(scope.row.ip, scope.row.ver_id)">更新</el-button>
</template>
</el-table-column>
<el-table-column prop="selectedUser" label="当前使用人" min-width="120">
<template v-slot="scope">
<el-select v-model="scope.row.user" class="m-2" size="small" laceholder="请选择" style="width: 80px"
@change="cinemaUserChange(scope.row.user, scope.row.id)">
<el-option v-for="data in userData" :key="data.id" :label="data.label"
:value="data.value"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="name" label="影院名称" min-width="250"></el-table-column>
<el-table-column prop="ip" label="影院IP" min-width="120">
<template v-slot="scope">
<a target="_blank" style="color:#007bff;" v-if="scope.row.ip!=null"
v-bind:href="'http://'+scope.row.ip+'/?code=leying'">
{{ scope.row.ip }}
</a>
<span v-else> {{ scope.row.ip }}</span>
</template>
</el-table-column>
<el-table-column prop="zz_num" label="专资编码" min-width="100"></el-table-column>
<el-table-column prop="inner_id" label="鼎新编码" min-width="90"></el-table-column>
<el-table-column prop="sys_ver" label="系统版本" min-width="175"></el-table-column>
<el-table-column prop="client_ver" label="客户端版本" min-width="150"></el-table-column>
<el-table-column prop="is_cloud" label="云版本" min-width="80"></el-table-column>
<el-table-column prop="remote_label" label="远程办公识别码" min-width="160" class-name="remote"></el-table-column>
<el-table-column prop="db_user" label="数据库账号" min-width="100"></el-table-column>
<el-table-column prop="db_pwd" label="数据库密码" min-width="120"></el-table-column>
</el-table>
<CinemaUpdate :ip="update_ip" :ver_id="ver_id"></CinemaUpdate>
</template>
<style scoped>
:deep(td.remote div) {
font-family: "YaHei Consolas Hybrid";
}
</style>

@ -1,342 +0,0 @@
<script setup>
import {onBeforeMount, onMounted, onBeforeUnmount, reactive, ref, unref, computed} from 'vue';
import {useStore, mapGetters, mapState} from "vuex";
import {
project_list,
prd_list,
prd_add,
prd_get,
prd_update,
prd_delete,
prd_history,
prd_list_ax_cloud
} from "@/apis/product.js";
import {storage} from "@/storage/storage.js";
import {onBeforeRouteLeave} from "vue-router";
// vuex
const store = useStore()
// region
//
const fromData = reactive({
project: '全部',
})
// region
//
const tableData = ref([])
//
const projectList = ref([])
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)
const history_dialog_id = ref(1)
let local_storage_array = storage.get("prd_history")
//
const handleCurrentChange = (newPage) => {
currentPage.value = newPage
get_table_data(currentPage.value, pageSize.value, fromData.project)
}
const handleSizeChange = (newPageSize) => {
pageSize.value = newPageSize
get_table_data(currentPage.value, pageSize.value, fromData.project)
}
//
const changeDialogStatus = (id) => {
history_dialog_id.value = id
console.log('changeDialogStatus', id)
get_history(history_dialog_id.value)
}
//
const history_data = ref([])
//
let history_dialog_show = ref(false)
//
function get_history(id) {
prd_history(id).then(res => {
console.log('get_history')
if (Array.isArray(res)) {
history_data.value = [...res]
}
history_dialog_show.value = true
}).catch(err => {
console.log(err)
});
}
const handleClose = () => {
history_dialog_show.value = false
history_data.value = []
}
//
const submitSearch = async () => {
tableData.value = []
await get_table_data(currentPage.value, pageSize.value, fromData.project).then(
res => {
if (Array.isArray(res)) {
tableData.value = [...res]
} else {
}
}
).catch(
err => {
}
)
}
// localstorage
function update_local_storage(id, update_at, update_mode = true) {
if (local_storage_array !== null) {
let find_local_data = false
local_storage_array.forEach((item) => {
if (item["id"] === id) {
if (update_mode === true) {
item["update_at"] = update_at
}
find_local_data = true
return true
}
})
if (!find_local_data) {
local_storage_array.push({id, update_at})
return true
}
return false
} else {
local_storage_array = new Array({id, update_at})
}
}
const update_table_data = (id) => {
tableData.value.forEach((item) => {
if (item.id === id) {
item.have_update = false
}
})
}
const mark_read = (id, update_at) => {
update_local_storage(id, update_at)
update_table_data(id)
save_local_storage()
}
const save_local_storage = () => {
tableData.value.forEach((table_item) => {
update_local_storage(table_item["id"], table_item["update_at"], false)
}
)
storage.remove('prd_history')
storage.set('prd_history', local_storage_array)
}
//
async function get_project_data() {
projectList.value = []
await project_list().then(res => {
if (Array.isArray(res)) {
projectList.value = [...res]
projectList.value.unshift({'id': 0, 'project_name': '全部', is_delete: false})
} else {
}
}).catch(err => {
console.log(err)
}
)
}
//
async function get_table_data(page_num = currentPage.value, page_size = pageSize.value, project_val = fromData.project) {
//
tableData.value = []
console.log('get_table_data')
console.log(project_val)
project_val = project_val === '全部' ? '' : project_val
console.log(project_val)
await prd_list_ax_cloud(page_num, page_size, project_val).then(res => {
total.value = res['count']
if (Array.isArray(res['results'])) {
tableData.value = [...res['results']]
console.log(tableData.value)
} else {
console.log('get_table_data.res is not an array')
}
}).catch(err => {
console.log(err)
}
)
if (local_storage_array !== null) {
//
tableData.value.forEach((table_item, table_index) => {
let find_local_data = false
table_item['have_update'] = false
local_storage_array.forEach((local_item, local_index) => {
if (table_item['id'] === local_item['id']) {
find_local_data = true
const table_datetime = new Date(table_item['update_at'])
const local_datetime = new Date(local_item['update_at'])
if (table_datetime > local_datetime) {
table_item['have_update'] = true
}
}
})
if (!find_local_data) {
table_item['have_update'] = true
}
})
}
}
//
onMounted(
async () => {
await get_project_data();
await get_table_data(currentPage.value, pageSize.value, fromData.project);
save_local_storage()
}
)
onBeforeUnmount(
() => {
save_local_storage()
}
)
onBeforeRouteLeave(
() => {
save_local_storage()
}
)
// endregion
</script>
<template>
<el-form
:model="fromData"
:inline="true"
class="search_form"
>
<el-form-item label="所属项目" label-width="90">
<el-select v-model="fromData.project" placeholder="请选择">
<el-option v-for="item in projectList" :key="item['project_name']" :label="item['project_name']"
:value="item['project_name']"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitSearch">搜索</el-button>
</el-form-item>
<!-- <el-button style="margin-right: 0">添加</el-button>-->
</el-form>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="project" label="所属项目" min-width="200"></el-table-column>
<el-table-column prop="prd_version" label="版本" min-width="200"></el-table-column>
<el-table-column prop="prd_doc_link" label="产品原型链接" min-width="300" show-overflow-tooltip>
<template v-slot="scope">
<a target="_blank" style="color:#007bff;" v-if="scope.row.prd_doc_link!=null"
@click="mark_read(scope.row.id, scope.row.update_at)"
v-bind:href="scope.row.prd_doc_link">
{{
scope.row.prd_doc_link.length > 30 ? scope.row.prd_doc_link.slice(0, 30) + '...' : scope.row.prd_doc_link
}}
</a>
<sup v-if="scope.row.have_update"
style="color: red; margin-left: 3px; font-size: 10px">有更新</sup>
<!-- <span v-else> {{ scope.row.prd_doc_link }}</span>-->
</template>
</el-table-column>
<el-table-column prop="prd_comment" label="版本描述" min-width="260">
<template #default="{ row }">
<el-tooltip
class="item"
popper-class="custom-tooltip"
effect="dark"
:raw-content="true"
:content="row.prd_comment.split('\n').join('<br>')"
placement="top-end">
<span>{{ row.prd_comment.length > 10 ? row.prd_comment.slice(0, 10) + '...' : row.prd_comment }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="update_at" label="最后更新时间" min-width="210">
</el-table-column>
<el-table-column prop="id" label="历史文档" min-width="120">
<template v-slot="scope">
<el-button type="primary" size="small" @click="changeDialogStatus(scope.row.id)"
:disabled="!scope.row.have_history">查看
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50]"
size="small"
layout="sizes, prev, pager, next"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
<template>
<el-dialog v-model="history_dialog_show" title="历史记录" width="500px" :modal="true"
:close-on-click-modal="false" :append-to-body="true" @close="handleClose">
<el-table :data="history_data" style="width: 100%">
<el-table-column prop="update_at" label="版本发布日期" min-width="100"></el-table-column>
<el-table-column prop="history_doc_link" label="产品原型链接" min-width="300" show-overflow-tooltip>
<template v-slot="scope">
<a target="_blank" style="color:#007bff;" v-if="scope.row.history_doc_link!=null"
v-bind:href="scope.row.history_doc_link">
{{
scope.row.history_doc_link.length > 30 ? scope.row.history_doc_link.slice(0, 30) + '...' : scope.row.history_doc_link
}}
</a>
</template>
</el-table-column>
</el-table>
</el-dialog>
</template>
</template>
<style>
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
.search_form {
display: flex;
justify-content: flex-start;
}
.custom-tooltip {
max-width: 500px; /* 设置最大宽度为 300px */
}
</style>

@ -445,10 +445,15 @@
dependencies:
vue-demi "*"
ace-builds@^1.31.1, ace-builds@^1.35.4:
version "1.37.5"
resolved "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.37.5.tgz"
integrity sha512-VMJ4Cnhq6L9dwvOCyuyyvQuiVTSwdZC7zDKJBBBJJax0wGQ7MvzQZFoi0gMmCm2I4Zuv/ZbtwU/dlglIhCNLhw==
ace-builds@^1.31.1:
version "1.32.2"
resolved "https://registry.npmjs.org/ace-builds/-/ace-builds-1.32.2.tgz"
integrity sha512-mnJAc803p+7eeDt07r6XI7ufV7VdkpPq4gJZT8Jb3QsowkaBTVy4tdBgPrVT0WbXLm0toyEQXURKSVNj/7dfJQ==
ace-builds@^1.35.4:
version "1.35.4"
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.35.4.tgz#f41d7ef57c3a7d424cd7e3300bef0cbef905c84f"
integrity sha512-r0KQclhZ/uk5a4zOqRYQkJuQuu4vFMiA6VTj54Tk4nI1TUR3iEMMppZkWbNoWEgWwv4ciDloObb9Rf4V55Qgjw==
acorn@^8.10.0, acorn@^8.11.2, acorn@^8.8.2:
version "8.11.2"
@ -876,11 +881,6 @@ jmespath@^0.16.0:
resolved "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz"
integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==
js-md5@^0.8.3:
version "0.8.3"
resolved "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz"
integrity sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==
json-editor-vue3@^1.0.9:
version "1.0.9"
resolved "https://registry.npmjs.org/json-editor-vue3/-/json-editor-vue3-1.0.9.tgz"
@ -1102,7 +1102,7 @@ readdirp@~3.6.0:
resize-observer-polyfill@^1.5.1:
version "1.5.1"
resolved "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
resolve@^1.22.4:
@ -1320,7 +1320,7 @@ vue-router@^4.0.13:
vue3-ace-editor@^2.2.4:
version "2.2.4"
resolved "https://registry.npmmirror.com/vue3-ace-editor/-/vue3-ace-editor-2.2.4.tgz"
resolved "https://registry.yarnpkg.com/vue3-ace-editor/-/vue3-ace-editor-2.2.4.tgz#1f2a787f91cf7979f27fab29e0e0604bb3ee1c17"
integrity sha512-FZkEyfpbH068BwjhMyNROxfEI8135Sc+x8ouxkMdCNkuj/Tuw83VP/gStFQqZHqljyX9/VfMTCdTqtOnJZGN8g==
dependencies:
resize-observer-polyfill "^1.5.1"

Loading…
Cancel
Save