index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. <template>
  2. <div class="app-container" ref="appContainer">
  3. <PropTable :loading="loading" @selection-change="selectionChange" :columns="column" :data="list" @reset="reset"
  4. @onSubmit="onSubmit">
  5. <template v-slot:btn>
  6. <div style="display: flex; justify-content: flex-end">
  7. <el-button type="primary" @click="importByExcel"><el-icon>
  8. <Upload />
  9. </el-icon>导入</el-button>
  10. <el-button type="primary" @click="add"><el-icon>
  11. <plus />
  12. </el-icon>添加</el-button>
  13. <el-button type="danger" @click="batchDelete"><el-icon>
  14. <delete />
  15. </el-icon>删除</el-button>
  16. </div>
  17. </template>
  18. <template v-slot:isOpenSvr="scope">{{ getIsOpenSvrLabel(scope.row.isOpenSvr) }}</template>
  19. <template v-slot:operation="scope">
  20. <el-button type="primary" size="small" icon="Edit" @click="edit(scope.row)">
  21. 编辑
  22. </el-button>
  23. <el-button @click="del(scope.row)" type="danger" size="small" icon="Delete">
  24. 删除
  25. </el-button>
  26. </template>
  27. </PropTable>
  28. <el-dialog v-model="dialogVisible" :title='title' width="50%">
  29. <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm"
  30. :size="formSize">
  31. <el-form-item label="ID" prop="id">
  32. <el-input v-model="ruleForm.id" type="number"/>
  33. </el-form-item>
  34. <el-form-item label="模版名称" prop="name">
  35. <el-input v-model="ruleForm.name" />
  36. </el-form-item>
  37. <el-form-item label="模版描述" prop="des">
  38. <el-input v-model="ruleForm.des" />
  39. </el-form-item>
  40. <el-form-item label="模版奖励" prop="reward">
  41. <el-input v-model="ruleForm.reward" />
  42. </el-form-item>
  43. <el-form-item label="模版备注" prop="remark">
  44. <el-input v-model="ruleForm.remark" />
  45. </el-form-item>
  46. <el-form-item label="持续天数" prop="keepDay">
  47. <el-input v-model="ruleForm.keepDay" type="number"/>
  48. </el-form-item>
  49. <el-form-item label="停留天数" prop="stayDay">
  50. <el-input v-model="ruleForm.stayDay" type="number"/>
  51. </el-form-item>
  52. <el-form-item label="开服活动" prop="isOpenSvr">
  53. <el-radio-group v-model="ruleForm.isOpenSvr">
  54. <el-radio :label="0">否</el-radio>
  55. <el-radio :label="1">是</el-radio>
  56. </el-radio-group>
  57. </el-form-item>
  58. </el-form>
  59. <template #footer>
  60. <span class="dialog-footer">
  61. <el-button @click="dialogVisible = false">取消</el-button>
  62. <el-button type="primary" @click="handleClose(ruleFormRef)">确定</el-button>
  63. </span>
  64. </template>
  65. </el-dialog>
  66. <el-dialog v-model="importVisible" :title='title' width="70%" @close="importClose">
  67. <PageWrapLayout class="m-upload-excel">
  68. <el-upload style="width: 100%" ref="upload" class="upload-demo" drag action="/" :before-upload="beforeUploadAction" type="file"
  69. accept=".xlsx, .xls" :limit="1" :on-remove="handleRemove">
  70. <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  71. <div class="el-upload__text"> 拖拽上传 <em>或者点击上传 Excel</em> </div>
  72. </el-upload>
  73. <div>
  74. <el-table :data="tableData" border highlight-current-row style="width: 100%; margin-top: 20px">
  75. <el-table-column v-for="item of tableHeader" :prop="item.value" :label="item.label" :key="item">
  76. </el-table-column>
  77. </el-table>
  78. </div>
  79. </PageWrapLayout>
  80. <template #footer>
  81. <span class="dialog-footer">
  82. <el-button @click="importClose">取消</el-button>
  83. <el-button type="primary" @click="handleConfirm">确定</el-button>
  84. </span>
  85. </template>
  86. </el-dialog>
  87. </div>
  88. </template>
  89. <script lang="ts" setup name="comprehensive">
  90. import { ref, reactive, onMounted, nextTick, onBeforeMount } from 'vue'
  91. import { ElMessage, ElMessageBox } from 'element-plus'
  92. import type { FormInstance } from 'element-plus'
  93. import activityTemplateApi from '@/api/activityTemplate'
  94. import dateUtils from '@/common/dateUtils'
  95. const loading = ref(true)
  96. const appContainer = ref(null)
  97. import PropTable from '@/components/Table/PropTable/index.vue'
  98. // import { ref } from 'vue'
  99. import ExcelJS from 'exceljs'
  100. import { UploadFilled } from '@element-plus/icons-vue'
  101. import type { UploadProps, UploadInstance } from 'element-plus'
  102. // import { ElMessage } from 'element-plus'
  103. const tableData = ref([])
  104. const tableHeader = ref([])
  105. const upload = ref<UploadInstance>()
  106. const tableColumn = ["id","name","des","reward","remark","keepDay","stayDay","isOpenSvr"]
  107. const beforeUploadAction = (file, fileLi) => {
  108. return new Promise((resolve, reject) => {
  109. const reader = new FileReader()
  110. reader.onload = async (e) => {
  111. const data = e.target.result
  112. const workbook = new ExcelJS.Workbook()
  113. try {
  114. let res = await workbook.xlsx.load(data)
  115. const sheets =
  116. res._worksheets && res._worksheets.filter((item) => typeof item !== 'undefined')
  117. const table = []
  118. let headers = []
  119. sheets.forEach((sheet) => {
  120. sheet._rows.forEach((row, index) => {
  121. if (index === 0) {
  122. row.values.forEach((it, i) => {
  123. // console.log("string" + it + " " + i + "" + tableColumn[i])
  124. headers.push({label: it, value: tableColumn[i - 1]})
  125. })
  126. } else {
  127. let obj = {}
  128. let arr = []
  129. row.values.forEach((it) => {
  130. arr.push(it)
  131. })
  132. tableColumn.forEach((ite, i) => {
  133. if (arr[i] == undefined) {
  134. obj[ite] = null
  135. } else {
  136. obj[ite] = arr[i]
  137. }
  138. })
  139. table.push(obj)
  140. }
  141. // const tableRow = {
  142. // position: "",
  143. // val: "",
  144. // };
  145. // row._cells.forEach((cell) => {
  146. // tableRow.position = cell._address;
  147. // tableRow.val = cell._value.model.value || "";
  148. // });
  149. })
  150. })
  151. tableData.value = table
  152. tableHeader.value = headers
  153. console.log("table", table)
  154. console.log("headers", headers)
  155. } catch (e) {
  156. ElMessage.error('解析失败')
  157. }
  158. }
  159. reader.readAsArrayBuffer(file)
  160. })
  161. }
  162. const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  163. tableData.value = null
  164. tableHeader.value = null
  165. }
  166. const data = ref([])
  167. let currPageNum = 1;
  168. const pageSize = 1000;
  169. onBeforeMount(() => {
  170. loadActivityTemplateInfo()
  171. })
  172. const loadActivityTemplateInfo = () => {
  173. let queryParams = reactive({
  174. pageNum: currPageNum,
  175. pageSize: pageSize
  176. })
  177. activityTemplateApi.query(queryParams).then(res => {
  178. data.value = res.data.result;
  179. console.log(data)
  180. })
  181. }
  182. const column = [
  183. { type: 'selection', width: 60, fixed: 'left' },
  184. { name: 'id', label: 'ID', width: 80 },
  185. { name: 'name', label: '模版名称', inSearch: true, valueType: 'input' },
  186. { name: 'des', label: '模版描述'},
  187. { name: 'reward', label: '模版奖励'},
  188. { name: 'remark', label: '模版备注'},
  189. { name: 'keepDay', label: '持续天数'},
  190. { name: 'stayDay', label: '停留天数'},
  191. { name: 'isOpenSvr', label: '开服活动', slot: true },
  192. { name: 'operation', slot: true, fixed: 'right', width: 200, label: '操作' },
  193. ]
  194. const getIsOpenSvrLabel = (val) => {
  195. if (val == 0) {
  196. return '否'
  197. } else if (val == 1) {
  198. return '是'
  199. }
  200. }
  201. const list = ref(data)
  202. const formSize = ref('default')
  203. const ruleFormRef = ref<FormInstance>()
  204. const ruleForm = reactive({
  205. id: null,
  206. name: null,
  207. des: null,
  208. reward: null,
  209. remark: null,
  210. keepDay: null,
  211. stayDay: null,
  212. isOpenSvr:0
  213. })
  214. const rules = reactive({
  215. name: [
  216. {
  217. required: true,
  218. message: '请输入名称',
  219. trigger: 'change',
  220. },
  221. ],
  222. keepDay: [
  223. {
  224. required: true,
  225. message: '请输入持续天数',
  226. trigger: 'change',
  227. },
  228. ]
  229. })
  230. const dialogVisible = ref(false)
  231. const importVisible = ref(false)
  232. const rowObj = ref({})
  233. const selectObj = ref([])
  234. const title = ref('详情')
  235. const importClose = () => {
  236. importVisible.value = false
  237. upload.value!.clearFiles()
  238. tableData.value = null
  239. tableHeader.value = null
  240. }
  241. const importByExcel = () => {
  242. title.value = '导入'
  243. importVisible.value = true
  244. tableData.value = null
  245. tableHeader.value = null
  246. }
  247. const add = () => {
  248. title.value = '新增'
  249. dialogVisible.value = true
  250. ruleForm.id = null
  251. ruleForm.name = null
  252. ruleForm.des = null
  253. ruleForm.reward = null
  254. ruleForm.remark = null
  255. ruleForm.keepDay = null
  256. ruleForm.stayDay = null
  257. ruleForm.isOpenSvr = 0
  258. }
  259. const handleConfirm = () => {
  260. // 验证table数据
  261. // ...
  262. let importParams = reactive({
  263. importValue: tableData.value
  264. })
  265. activityTemplateApi.importBatch(importParams).then(res => {
  266. console.log('result', res)
  267. if (res.data.code = 200) {
  268. loadActivityTemplateInfo()
  269. importVisible.value = false
  270. return ElMessage.success(res.data.msg)
  271. } else {
  272. return ElMessage.error(res.data.msg)
  273. }
  274. })
  275. console.log('import submit!')
  276. }
  277. const handleClose = async (done: () => void) => {
  278. await ruleFormRef.value.validate((valid, fields) => {
  279. if (valid) {
  280. if (title.value == '新增') {
  281. activityTemplateApi.add(ruleForm).then(res => {
  282. console.log('result', res)
  283. if (res.data.code = 200) {
  284. loadActivityTemplateInfo()
  285. dialogVisible.value = false
  286. return ElMessage.success(res.data.msg)
  287. } else {
  288. return ElMessage.error(res.data.msg)
  289. }
  290. })
  291. console.log('add submit!')
  292. } else {
  293. // let updateParams = reactive({
  294. // id: rowObj.value.id,
  295. // updateValue: ruleForm
  296. // })
  297. activityTemplateApi.update(ruleForm).then(res => {
  298. if (res.data.code = 200) {
  299. loadActivityTemplateInfo()
  300. dialogVisible.value = false
  301. return ElMessage.success('修改成功')
  302. } else {
  303. return ElMessage.error('修改失败')
  304. }
  305. })
  306. console.log('update submit!')
  307. }
  308. console.log('submit!', ruleForm)
  309. } else {
  310. console.log('error submit!', fields)
  311. }
  312. })
  313. }
  314. const batchDelete = () => {
  315. if (!selectObj.value.length) {
  316. return ElMessage.error('未选中任何行')
  317. }
  318. ElMessageBox.confirm('你确定要删除选中项吗?', '温馨提示', {
  319. confirmButtonText: '确定',
  320. cancelButtonText: '取消',
  321. type: 'warning',
  322. draggable: true,
  323. })
  324. .then(() => {
  325. let selectActivityTemplateIds = reactive([])
  326. for (let value of selectObj.value) {
  327. selectActivityTemplateIds.push(value.id)
  328. }
  329. let deleteParams = reactive({
  330. actTemIds: selectActivityTemplateIds
  331. })
  332. activityTemplateApi.deleteBatch(deleteParams).then(res => {
  333. loadActivityTemplateInfo()
  334. ElMessage.success('批量删除成功')
  335. })
  336. list.value = list.value.concat([])
  337. })
  338. .catch(() => { })
  339. }
  340. const selectionChange = (val) => {
  341. selectObj.value = val
  342. }
  343. const edit = (row) => {
  344. title.value = '编辑'
  345. rowObj.value = row
  346. dialogVisible.value = true
  347. ruleForm.id = row.id.toString()
  348. ruleForm.name = row.name
  349. ruleForm.des = row.des
  350. ruleForm.reward = row.reward
  351. ruleForm.remark = row.remark
  352. ruleForm.keepDay = row.keepDay.toString()
  353. ruleForm.stayDay = row.stayDay == null ? row.stayDay : row.stayDay.toString()
  354. ruleForm.isOpenSvr = row.isOpenSvr
  355. }
  356. const del = (row) => {
  357. console.log('row==', row)
  358. ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', {
  359. confirmButtonText: '确定',
  360. cancelButtonText: '取消',
  361. type: 'warning',
  362. draggable: true,
  363. })
  364. .then(() => {
  365. let deleteParams = reactive({
  366. id: row.id
  367. })
  368. activityTemplateApi.delete(deleteParams).then(res => {
  369. loadActivityTemplateInfo()
  370. ElMessage.success('删除成功')
  371. })
  372. loading.value = true
  373. setTimeout(() => {
  374. loading.value = false
  375. }, 500)
  376. })
  377. .catch(() => { })
  378. }
  379. const reset = () => {
  380. loadActivityTemplateInfo()
  381. loading.value = true
  382. setTimeout(() => {
  383. loading.value = false
  384. }, 500)
  385. ElMessage.success('重置成功')
  386. }
  387. const onSubmit = (val) => {
  388. if ((val.name == null || val.name == "") && val.isOpenSvr == null) {
  389. ElMessage.warning('请输入查询条件')
  390. return
  391. }
  392. let queryParams = reactive({
  393. pageNum: 1,
  394. pageSize: pageSize,
  395. condition: val
  396. })
  397. activityTemplateApi.query(queryParams).then(res => {
  398. data.value = res.data.result;
  399. console.log(data.value)
  400. })
  401. loading.value = true
  402. setTimeout(() => {
  403. loading.value = false
  404. }, 500)
  405. }
  406. const getHeight = () => {
  407. }
  408. onMounted(() => {
  409. nextTick(() => {
  410. // let data = appContainer.value.
  411. })
  412. setTimeout(() => {
  413. loading.value = false
  414. }, 500)
  415. })
  416. </script>
  417. <style scoped>
  418. .edit-input {
  419. padding-right: 100px;
  420. }
  421. .app-container {
  422. flex: 1;
  423. display: flex;
  424. width: 100%;
  425. padding: 16px;
  426. box-sizing: border-box;
  427. }
  428. .cancel-btn {
  429. position: absolute;
  430. right: 15px;
  431. top: 10px;
  432. }
  433. .m-upload-excel {
  434. .el-upload {
  435. width: 100%;
  436. }
  437. .el-upload-dragger {
  438. width: 100%;
  439. }
  440. }
  441. </style>