txTarget.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. <template>
  2. <div>
  3. <div class="gva-search-box">
  4. <el-form ref="searchForm" :inline="true" :model="searchInfo">
  5. <el-form-item label="任务Id">
  6. <el-input v-model="searchInfo.task_id" placeholder="任务ID" />
  7. </el-form-item>
  8. <el-form-item label="负责人">
  9. <el-input v-model="searchInfo.user" placeholder="负责人" />
  10. </el-form-item>
  11. <el-form-item label="日期" prop="create_date">
  12. <el-date-picker
  13. v-model="searchInfo.create_date"
  14. popper-class="picker-popovers"
  15. class="timefilter"
  16. type="datetime"
  17. placeholder="选择日期时间"
  18. value-format="YYYY-MM-DD"
  19. >
  20. </el-date-picker>
  21. </el-form-item>
  22. <el-form-item>
  23. <el-button size="small" type="primary" icon="search" @click="onSubmit">查询</el-button>
  24. <el-button size="small" icon="refresh" @click="onReset">重置</el-button>
  25. </el-form-item>
  26. </el-form>
  27. </div>
  28. <div class="gva-table-box">
  29. <el-table :data="tableData" border @sort-change="sortChange" @selection-change="handleSelectionChange">
  30. <el-table-column label="任务日期" min-width="70" prop="create_date" />
  31. <el-table-column label="任务名称" min-width="80" prop="task_name" sortable="custom" />
  32. <el-table-column label="负责人" min-width="60" prop="user" sortable="custom" />
  33. <el-table-column label="新增目标" min-width="45" prop="new_target" />
  34. <el-table-column label="新增完成" min-width="45" prop="new_complete" />
  35. <el-table-column label="留存目标" min-width="45" prop="retained_target" />
  36. <el-table-column label="留存完成" min-width="45" prop="retained_complete" />
  37. <el-table-column label="付费目标" min-width="45" prop="pay_target" />
  38. <el-table-column label="付费完成" min-width="45" prop="pay_complete" />
  39. <el-table-column label="付费流水" min-width="45" prop="amount"/>
  40. <el-table-column align="left" fixed="right" label="操作" width="200">
  41. <template #default="scope">
  42. <el-button
  43. icon="edit"
  44. size="small"
  45. type="primary"
  46. link
  47. @click="editCardFunc(scope.row)"
  48. >编辑</el-button>
  49. </template>
  50. </el-table-column>
  51. </el-table>
  52. <div class="gva-pagination">
  53. <el-pagination
  54. :current-page="page"
  55. :page-size="pageSize"
  56. :page-sizes="[10, 30, 50, 100]"
  57. :total="total"
  58. layout="total, sizes, prev, pager, next, jumper"
  59. @current-change="handleCurrentChange"
  60. @size-change="handleSizeChange"
  61. />
  62. </div>
  63. </div>
  64. <el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle">
  65. <el-form ref="apiForm" :model="form" :rules="rules" label-width="80px" :inline="true">
  66. <el-form-item label="任务名称" prop="task_name">
  67. <el-input v-model="form.task_name" autocomplete="off" :disabled="true"/>
  68. </el-form-item>
  69. <el-form-item label="负责人" prop="user" >
  70. <el-input v-model="form.user" autocomplete="off" :disabled="true"/>
  71. </el-form-item>
  72. <el-form-item label="任务日期" prop="create_date" >
  73. <el-input v-model="form.create_date" autocomplete="off" :disabled="true"/>
  74. </el-form-item>
  75. </el-form>
  76. <el-form ref="apiForm" :model="form" :rules="rules" label-width="80px" :inline="true">
  77. <el-form-item label="新增目标" prop="new_target">
  78. <el-input v-model="form.new_target" autocomplete="off" />
  79. </el-form-item>
  80. <el-form-item label="付费目标" prop="pay_target">
  81. <el-input v-model="form.pay_target" autocomplete="off"/>
  82. </el-form-item>
  83. </el-form>
  84. <template #footer>
  85. <div class="dialog-footer">
  86. <el-button size="small" @click="closeDialog">取 消</el-button>
  87. <el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
  88. </div>
  89. </template>
  90. </el-dialog>
  91. </div>
  92. </template>
  93. <script>
  94. export default {
  95. name: 'TxTargetTask',
  96. }
  97. </script>
  98. <script setup>
  99. import {
  100. getGameTaskTargetById,
  101. updateGameTaskTarget,
  102. getGameTxTaskList,
  103. } from '@/api/task'
  104. import { toSQLLine } from '@/utils/stringFun'
  105. import warningBar from '@/components/warningBar/warningBar.vue'
  106. import { ref } from 'vue'
  107. import { ElMessage, ElMessageBox } from 'element-plus'
  108. const apis = ref([])
  109. const rules = ref({
  110. task_id: [{ required: true, message: '输入任务ID', trigger: 'blur' }],
  111. task_name: [
  112. { required: true, message: '请输入任务名称', trigger: 'blur' }
  113. ],
  114. user: [
  115. { required: true, message: '请输入使用者', trigger: 'blur' }
  116. ],
  117. new_retained: [
  118. { required: true, message: '请选择重要参数', trigger: 'blur' }
  119. ],
  120. game_name: [
  121. { required: true, message: '请选择游戏', trigger: 'blur' }
  122. ],
  123. date: [
  124. { required: true, message: '请选择开始时间', trigger: 'blur' }
  125. ],
  126. game_port_id: [
  127. { required: true, message: '请选择游戏端口', trigger: 'blur' }
  128. ],
  129. account_type: [
  130. { required: true, message: '请选择账号类型', trigger: 'blur' }
  131. ],
  132. login_method: [
  133. { required: true, message: '请选择登录方式', trigger: 'blur' }
  134. ],
  135. tx_channel: [
  136. { required: true, message: '请输入腾讯渠道号', trigger: 'blur' }
  137. ],
  138. mz_channel: [
  139. { required: true, message: '请输入魅族渠道号', trigger: 'blur' }
  140. ],
  141. new_target: [
  142. { required: true, message: '请输入新增目标', trigger: 'blur' }
  143. ],
  144. pay_target: [
  145. { required: true, message: '请输入付费目标', trigger: 'blur' }
  146. ],
  147. retained_target: [
  148. { required: true, message: '请输入留存目标', trigger: 'blur' }
  149. ],
  150. retained_target: [
  151. { required: true, message: '请输入付费单价', trigger: 'blur' }
  152. ]
  153. })
  154. const form = ref({
  155. task_id: '',
  156. task_name: '',
  157. user: '',
  158. new_retained: '1',
  159. game_name:'',
  160. date:'',
  161. game_port_id:'',
  162. account_type:'',
  163. login_method:'',
  164. tx_channel:'',
  165. tx_game_id:'',
  166. mz_channel:'',
  167. mz_game_id:'',
  168. game_id_xmy:'',
  169. new_target:'',
  170. pay_target:'',
  171. retained_target:'',
  172. pay_price:'',
  173. free:-1
  174. })
  175. const GamePortOptions = ref([
  176. {
  177. id: 1,
  178. name: '腾讯游戏',
  179. },
  180. {
  181. id: 2,
  182. name: '360游戏',
  183. },
  184. {
  185. id: 3,
  186. name: '网易游戏',
  187. },
  188. {
  189. id: 4,
  190. name: '酷派游戏',
  191. },
  192. {
  193. id: 5,
  194. name: '魅族游戏',
  195. },
  196. ])
  197. const accountTypeOptions = ref([
  198. {
  199. id: 1,
  200. name: '小绵羊账号',
  201. },
  202. {
  203. id: 2,
  204. name: 'QQ账号',
  205. },
  206. {
  207. id: 3,
  208. name: '魅族账号',
  209. },
  210. {
  211. id: 4,
  212. name: '华为账号',
  213. },
  214. {
  215. id: 5,
  216. name: '测试类型',
  217. },
  218. {
  219. id: 6,
  220. name: '微信',
  221. },
  222. {
  223. id: 7,
  224. name: '微信+QQ',
  225. },
  226. ])
  227. const loginMethodOptions = ref([
  228. {
  229. id: 1,
  230. name: '小绵羊登录',
  231. },
  232. {
  233. id: 2,
  234. name: '魅族账号登录',
  235. },
  236. {
  237. id: 3,
  238. name: 'QQ账号登录',
  239. },
  240. {
  241. id: 4,
  242. name: '网易账号登录',
  243. },
  244. {
  245. id: 5,
  246. name: '微信授权登录',
  247. },
  248. {
  249. id: 6,
  250. name: '微信+QQ授权登录',
  251. },
  252. ])
  253. const FreeMethodOptions = ref([
  254. {
  255. id: 1,
  256. name: 'QQ卡',
  257. },
  258. {
  259. id: 2,
  260. name: '微信',
  261. },
  262. {
  263. id: 3,
  264. name: '支付宝',
  265. },
  266. {
  267. id: 4,
  268. name: '银行卡',
  269. },
  270. ])
  271. // 新增可控按钮
  272. const addBtn = (form) => {
  273. if (!form.card_list) {
  274. form.card_list = []
  275. }
  276. form.card_list.push({
  277. card: '',
  278. amount: 0
  279. })
  280. }
  281. // 删除可控按钮
  282. const deleteBtn = async(btns, index) => {
  283. const btn = btns[index]
  284. if (btn.ID === 0) {
  285. btns.splice(index, 1)
  286. return
  287. }
  288. btns.splice(index, 1)
  289. }
  290. const type = ref('')
  291. const page = ref(1)
  292. const total = ref(0)
  293. const pageSize = ref(10)
  294. const tableData = ref([])
  295. const searchInfo = ref({})
  296. const onReset = () => {
  297. searchInfo.value = {}
  298. }
  299. // 搜索
  300. const onSubmit = () => {
  301. page.value = 1
  302. pageSize.value = 10
  303. searchInfo.value.task_id = Number(searchInfo.value.task_id)
  304. getTableData()
  305. }
  306. // 分页
  307. const handleSizeChange = (val) => {
  308. pageSize.value = val
  309. getTableData()
  310. }
  311. const handleCurrentChange = (val) => {
  312. page.value = val
  313. getTableData()
  314. }
  315. // 排序
  316. const sortChange = ({ prop, order }) => {
  317. if (prop) {
  318. if (prop === 'id') {
  319. prop = 'id'
  320. }
  321. searchInfo.value.orderKey = toSQLLine(prop)
  322. searchInfo.value.desc = order === 'descending'
  323. }
  324. getTableData()
  325. }
  326. // 查询
  327. const getTableData = async() => {
  328. const table = await getGameTxTaskList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value })
  329. if (table.code === 0) {
  330. tableData.value = table.data.list
  331. total.value = table.data.total
  332. page.value = table.data.page
  333. pageSize.value = table.data.pageSize
  334. }
  335. }
  336. getTableData()
  337. // 批量操作
  338. const handleSelectionChange = (val) => {
  339. apis.value = val
  340. }
  341. const deleteVisible = ref(false)
  342. const onClose = async() => {
  343. const ids = apis.value.map(item => item.id)
  344. console.log(ids)
  345. const status = -1
  346. const res = await colsePc({ ids,status })
  347. if (res.code === 0) {
  348. ElMessage({
  349. type: 'success',
  350. message: res.msg
  351. })
  352. if (tableData.value.length === ids.length && page.value > 1) {
  353. page.value--
  354. }
  355. deleteVisible.value = false
  356. getTableData()
  357. }
  358. }
  359. const onOpen = async() => {
  360. const ids = apis.value.map(item => item.id)
  361. console.log(ids)
  362. const status = 1
  363. const res = await colsePc({ ids,status })
  364. if (res.code === 0) {
  365. ElMessage({
  366. type: 'success',
  367. message: res.msg
  368. })
  369. if (tableData.value.length === ids.length && page.value > 1) {
  370. page.value--
  371. }
  372. deleteVisible.value = false
  373. getTableData()
  374. }
  375. }
  376. // 弹窗相关
  377. const apiForm = ref(null)
  378. const initForm = () => {
  379. apiForm.value.resetFields()
  380. form.value = {
  381. task_id: '',
  382. task_name: '',
  383. user: '',
  384. new_retained: '1',
  385. game_name:'',
  386. date:'',
  387. game_port_id:'',
  388. account_type:'',
  389. login_method:'',
  390. tx_channel:'',
  391. tx_game_id:'',
  392. mz_channel:'',
  393. mz_game_id:'',
  394. game_id_xmy:'',
  395. new_target:'',
  396. pay_target:'',
  397. retained_target:'',
  398. pay_price:'',
  399. }
  400. }
  401. const dialogTitle = ref('新增')
  402. const dialogFormVisible = ref(false)
  403. const openDialog = (key) => {
  404. switch (key) {
  405. case 'addCard':
  406. dialogTitle.value = '新增'
  407. form.value.is_add = 1
  408. break
  409. case 'edit':
  410. dialogTitle.value = '编辑'
  411. form.value.is_add = 0
  412. break
  413. default:
  414. break
  415. }
  416. type.value = key
  417. dialogFormVisible.value = true
  418. }
  419. const closeDialog = () => {
  420. initForm()
  421. dialogFormVisible.value = false
  422. }
  423. const editCardFunc = async(row) => {
  424. const res = await getGameTaskTargetById({ id: row.task_id, create_date:row.create_date })
  425. if (res.code === 0) {
  426. form.value = res.data
  427. openDialog('edit')
  428. }
  429. }
  430. const enterDialog = async() => {
  431. apiForm.value.validate(async valid => {
  432. form.value.task_id = Number(form.value.task_id)
  433. form.value.new_target = Number(form.value.new_target)
  434. form.value.pay_price = Number(form.value.pay_price)
  435. form.value.pay_target = Number(form.value.pay_target)
  436. form.value.retained_target = Number(form.value.retained_target)
  437. form.value.hand_new_complete = Number(form.value.hand_new_complete)
  438. form.value.hand_retained_complete = Number(form.value.hand_retained_complete)
  439. form.value.hand_pay_complete = Number(form.value.hand_pay_complete)
  440. form.value.hand_amount_total = Number(form.value.hand_amount_total)
  441. form.value.is_free = Number(form.value.is_free)
  442. form.value.free_method = Number(form.value.free_method)
  443. form.value.is_upload_xjf = Number(form.value.is_upload_xjf)
  444. form.value.is_upload_wt = Number(form.value.is_upload_wt)
  445. if (valid) {
  446. switch (type.value) {
  447. case 'edit':
  448. {
  449. const res = await updateGameTaskTarget(form.value)
  450. if (res.code === 0) {
  451. ElMessage({
  452. type: 'success',
  453. message: '编辑成功',
  454. showClose: true
  455. })
  456. }
  457. getTableData()
  458. closeDialog()
  459. }
  460. break
  461. default:
  462. // eslint-disable-next-line no-lone-blocks
  463. {
  464. ElMessage({
  465. type: 'error',
  466. message: '未知操作',
  467. showClose: true
  468. })
  469. }
  470. break
  471. }
  472. }
  473. })
  474. }
  475. const deleteApiFunc = async(row) => {
  476. ElMessageBox.confirm('此操作将永久删除所有角色下该api, 是否继续?', '提示', {
  477. confirmButtonText: '确定',
  478. cancelButtonText: '取消',
  479. type: 'warning'
  480. })
  481. .then(async() => {
  482. const res = await deleteGameTask(row)
  483. if (res.code === 0) {
  484. ElMessage({
  485. type: 'success',
  486. message: '删除成功!'
  487. })
  488. if (tableData.value.length === 1 && page.value > 1) {
  489. page.value--
  490. }
  491. getTableData()
  492. }
  493. })
  494. }
  495. const switchEnable = async(row) => {
  496. const res = await statusOperation({task_id:row.task_id, status:row.status})
  497. if (res.code === 0) {
  498. ElMessage({ type: 'success', message: `${row.status === -1 ? '停止' : '开启'}成功` })
  499. }
  500. }
  501. const links = ref([])
  502. const querySearch = (queryString, cb) => {
  503. const results = queryString
  504. ? links.value.filter(createFilter(queryString))
  505. : links.value
  506. // call callback function to return suggestion objects
  507. cb(results)
  508. }
  509. const createFilter = (queryString) => {
  510. return (restaurant) => {
  511. return (
  512. restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
  513. )
  514. }
  515. }
  516. const loadAll = () => {
  517. return [
  518. { game_id: 1, game_name: '龙腾传世' },
  519. { game_id: 2, game_name: '龙皇传说' },
  520. { game_id: 3, game_name: '龙之国物语' },
  521. { game_id: 4, game_name: '黑月' },
  522. { game_id: 5, game_name: '麻将来了' },
  523. { game_id: 6, game_name: '鸿途归来' },
  524. { game_id: 7, game_name: '魔力宝贝归来' },
  525. ]
  526. }
  527. const handleSelect = (item) => {
  528. form.value.game_id = item.game_id
  529. console.log(item)
  530. }
  531. const handleIconClick = (ev) => {
  532. console.log(ev)
  533. }
  534. links.value = loadAll()
  535. </script>
  536. <style scoped lang="scss">
  537. .button-box {
  538. padding: 10px 20px;
  539. .el-button {
  540. float: right;
  541. }
  542. }
  543. :deep(.el-tabs__nav-scroll){
  544. width:35%;
  545. margin:0 auto
  546. }
  547. :deep(.el-tabs__nav-scroll)
  548. .warning {
  549. color: #dc143c;
  550. }
  551. </style>