appletView.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. <template>
  2. <div class="page-box">
  3. <moduleView :propConfig="config" ref="view" v-loading="load" @pagination="pagination" @onRefresh="getList" @resert="queryList" @search="queryList" @clickHandle="clickHandle" @modalHandle="modalHandle" @detail="detail" />
  4. <el-drawer
  5. size="50%"
  6. v-model="drawer"
  7. close-on-click-modal
  8. title="操作日志"
  9. direction="rtl"
  10. >
  11. <el-table ref="operlogRef" :data="logData">
  12. <el-table-column label="日志编号" align="center" prop="operId" width="130" />
  13. <el-table-column label="操作类型" align="center" prop="businessType">
  14. <template #default="scope">
  15. <dict-tag :options="sys_oper_type" :value="scope.row.businessType" />
  16. </template>
  17. </el-table-column>
  18. <el-table-column label="操作人员" align="center" width="110" prop="operName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
  19. <el-table-column label="主机" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
  20. <el-table-column label="操作状态" align="center" prop="status">
  21. <template #default="scope">
  22. <dict-tag :options="sys_common_status" :value="scope.row.status" />
  23. </template>
  24. </el-table-column>
  25. <el-table-column label="操作日期" align="center" prop="operTime" width="180" sortable="custom" :sort-orders="['descending', 'ascending']">
  26. <template #default="scope">
  27. <span>{{ parseTime(scope.row.operTime) }}</span>
  28. </template>
  29. </el-table-column>
  30. </el-table>
  31. <div class="page-log">
  32. <el-pagination layout="prev, pager, next" :total="logPage.total" @current-change="handleCurrentChange"
  33. :current-page="logPage.pageNo" />
  34. </div>
  35. </el-drawer>
  36. </div>
  37. </template>
  38. <script setup>
  39. import { computed,getCurrentInstance,ref, shallowRef } from "vue";
  40. const { proxy } = getCurrentInstance();
  41. import {appList,addApp,updateApp,deleApp,disableApp,enableApp} from '@/api/base/shopManage'
  42. const { sys_oper_type, sys_common_status } = proxy.useDict("sys_oper_type","sys_common_status");
  43. import { list} from "@/api/monitor/operlog";
  44. import txt from "./txt.vue";
  45. // import merchant from "./merchant.vue";
  46. import stateRadio from "@/components/stateRadio/stateRadio.vue";
  47. const drawer = ref(false)
  48. const config = ref({
  49. attr:{
  50. calculateH:true
  51. },
  52. search:{
  53. attr:{
  54. size:'mini'
  55. },
  56. columns:[
  57. [{
  58. span:8,
  59. // label:'设备名称',
  60. labelWidth:16,
  61. prop:'searchText',
  62. component:'by-input',
  63. compConfig:{
  64. attr:{
  65. placeholder:'请输入小程序名称',
  66. prefixIcon:'vxe-icon-search'
  67. }
  68. }
  69. }]
  70. ]
  71. },
  72. tool:{
  73. tools:{
  74. export:true,
  75. add:true,
  76. search:true,
  77. refresh:true
  78. },
  79. customTools:[{
  80. name: '操作日志',
  81. icon: 'Notebook',
  82. event:{
  83. click:() =>{
  84. drawer.value = true
  85. }
  86. }
  87. }]
  88. },
  89. table:{
  90. attr:{
  91. size:'mini',
  92. seq:true,
  93. align:'center',
  94. // checkbox:true
  95. },
  96. columns:[
  97. {
  98. isDetail:true,
  99. title:'小程序名称',
  100. field:'appName',
  101. },
  102. {
  103. title:'应用ID',
  104. field:'appkey',
  105. },
  106. {
  107. title:'所属商户',
  108. field:'commercialName'
  109. },
  110. {
  111. title:'状态',
  112. field:'state',
  113. component: 'textChange',
  114. compConfig:{
  115. attr:{
  116. data:[{
  117. label:'已启用',
  118. value:1,
  119. backgroundColor:'#f0f9eb',
  120. color:'#67c23a'
  121. },{
  122. label:'已禁用',
  123. value:0,
  124. backgroundColor:'#fef0f0',
  125. color:'#f56c6c'
  126. }]
  127. }
  128. }
  129. },
  130. {
  131. title:'创建时间',
  132. field:'createTime'
  133. },
  134. {
  135. title:'操作',
  136. action:true,
  137. plugins:[{
  138. name:'禁用',
  139. event:{
  140. show:row => {
  141. return row.state == 1
  142. },
  143. click:item => {
  144. disableHandle(item)
  145. }
  146. }
  147. },{
  148. name:'启用',
  149. event:{
  150. show:row => {
  151. return row.state == 0
  152. },
  153. click:item => {
  154. enableHandle(item)
  155. }
  156. }
  157. }]
  158. }]
  159. },
  160. modal:{
  161. tool:{
  162. tools:{
  163. return:true,
  164. add:true
  165. }
  166. },
  167. form:{
  168. attr:{
  169. width:'1000px',
  170. size:'small',
  171. labelWidth:'130px',
  172. rules:{
  173. appLogo:[
  174. {required: true, message: '请上传小程序logo', trigger: 'change'}
  175. ],
  176. appName:[
  177. {required: true, message: '请输入小程序名称', trigger: 'blur'}
  178. ],
  179. appIntroduce:[
  180. {required: true, message: '请输入小程序描述', trigger: 'blur'},
  181. ],
  182. commercialName:[
  183. {required: true, message: '请选择商户', trigger: 'change'}
  184. ],
  185. callBack:[
  186. {required: true, message: '请输入回调地址', trigger: 'blur'}
  187. ]
  188. }
  189. },
  190. columns:[
  191. [{
  192. label:'小程序logo',
  193. prop:'appLogo',
  194. component:'ByUpload'
  195. }],
  196. [{
  197. label:'小程序名称',
  198. prop:'appName',
  199. component:'by-input'
  200. }],
  201. [{
  202. label:'小程序描述',
  203. prop:'appIntroduce',
  204. component:'by-input',
  205. compConfig:{
  206. attr:{
  207. type:'textarea'
  208. }
  209. }
  210. }],
  211. [{
  212. label:'商户',
  213. prop:'commercialName',
  214. component:'by-select',
  215. compConfig:{
  216. attr:{
  217. label:'commercialName',
  218. value:'commercialId',
  219. retConfig:{
  220. commercialName:'commercialName',
  221. commercialId:'commercialId'
  222. },
  223. // disabledHandle: item => {
  224. // return item.state == 1 ? false : true
  225. // }
  226. },
  227. request:{
  228. url:'/app/getCommercialList',
  229. method:'get'
  230. }
  231. }
  232. }],
  233. [{
  234. label:'回调地址',
  235. prop:'callBack',
  236. component:'by-input',
  237. compConfig:{
  238. attr:{
  239. type:'textarea'
  240. }
  241. }
  242. }],
  243. [{
  244. label:'状态',
  245. prop:'state',
  246. component:shallowRef(stateRadio)
  247. }],
  248. [{
  249. label:'应用ID',
  250. prop:'appkey',
  251. component:shallowRef(txt)
  252. }],
  253. [{
  254. label:'应用秘钥',
  255. prop:'appSecret',
  256. component:shallowRef(txt)
  257. }],
  258. [{
  259. label:'备注',
  260. prop:'annotation',
  261. component:'by-input',
  262. compConfig:{
  263. attr:{
  264. type:'textarea'
  265. }
  266. }
  267. }]
  268. ]
  269. }
  270. }
  271. })
  272. const logData = ref([])
  273. const logPage = ref({
  274. pageNo: 1, //当前页
  275. pageSize: 20, //每页条数
  276. total: 0 //总条数
  277. })
  278. const load = ref(false)
  279. const isSearch = ref(false)
  280. const timeNum = ref(0);
  281. const initLog= () => {
  282. list({
  283. pageNum:logPage.value.pageNo,
  284. pageSize:logPage.value.pageSize,
  285. title:'小程序'
  286. }).then(res => {
  287. logData.value = res.rows;
  288. logPage.value.total = res.total;
  289. }).catch(()=> {
  290. })
  291. }
  292. const handleCurrentChange = v => {
  293. logPage.value.pageNo = v;
  294. initLog()
  295. }
  296. // 禁用
  297. const disableHandle = item => {
  298. disableApp(item.appkey).then(() => {
  299. proxy.$message({
  300. message: '“' + item.appName + '”' + '已成功禁用!',
  301. type: 'success'
  302. })
  303. getList()
  304. initLog()
  305. }).catch(() => {})
  306. }
  307. //启用
  308. const enableHandle = item => {
  309. enableApp(item.appkey).then(() => {
  310. proxy.$message({
  311. message: '“' + item.appName + '”' + '已成功启用!',
  312. type: 'success'
  313. })
  314. getList()
  315. initLog()
  316. }).catch(() => {})
  317. }
  318. const detail = () => {
  319. config.value.modal.tool.tools.save = true;
  320. delete config.value.modal.tool.tools.add;
  321. proxy.$refs.view.initFormTool();
  322. }
  323. const clickHandle = n => {
  324. if(n == 'onAdd'){
  325. config.value.modal.tool.tools.add = true;
  326. delete config.value.modal.tool.tools.save;
  327. proxy.$refs.view.initFormTool();
  328. }
  329. if(n == 'onDelete'){
  330. delHandle()
  331. }
  332. }
  333. const modalHandle = n =>{
  334. if(n == 'onAdd'){
  335. proxy.$refs.view.getFormValidate(addData)
  336. }
  337. if(n == 'onSave'){
  338. proxy.$refs.view.getFormValidate(onSave)
  339. }
  340. }
  341. const delHandle = () => {
  342. let data = proxy.$refs.view.getSelectData();
  343. let ids = []
  344. if(!data && data.lenght == 0) {
  345. proxy.$message('请选择数据')
  346. return
  347. }
  348. for(const item of data) {
  349. ids.push(item.equipmentId)
  350. }
  351. proxy.$confirm('此操作将永久删除数据, 是否继续?', '提示', {
  352. confirmButtonText: '确定',
  353. cancelButtonText: '取消',
  354. type: 'warning'
  355. }).then(() => {
  356. load.value = true;
  357. deleApp({
  358. appKeys:appkey,
  359. }).then(()=>{
  360. proxy.$message({message:'删除成功!',type:'success'})
  361. load.value = false;
  362. getList();
  363. }).catch(()=>{
  364. load.value = false;
  365. })
  366. }).catch(()=>{})
  367. }
  368. //添加
  369. const addData = () => {
  370. let value = proxy.$refs.view.getFormValue();
  371. if(value){
  372. load.value = true;
  373. addApp(value).then(res =>{
  374. load.value = false;
  375. proxy.$message({
  376. message:res.msg,
  377. type:'success'
  378. });
  379. proxy.$refs.view.closeModal();
  380. getList();
  381. }).catch(()=>{
  382. load.value = false;
  383. })
  384. }
  385. }
  386. //保存
  387. const onSave = () => {
  388. let data = proxy.$refs.view.getFormValue();
  389. load.value = true;
  390. updateApp(data).then(res => {
  391. proxy.$message({
  392. message:res.msg,
  393. type:'success'
  394. });
  395. load.value = false;
  396. proxy.$refs.view.closeModal();
  397. pagination();
  398. }).catch(() => {
  399. load.value = false;
  400. })
  401. }
  402. const pagination = () => {
  403. if(isSearch.value){
  404. queryList();
  405. }else{
  406. getList()
  407. }
  408. }
  409. //列表请求(包含分页和搜素条件)
  410. const queryList = () => {
  411. isSearch.value = true;
  412. let data = proxy.$refs.view.getQuery();
  413. requestList(data);
  414. }
  415. const getList = () => {
  416. if(!proxy.$refs.view){
  417. if(timeNum.value > 5){
  418. return
  419. }
  420. setTimeout(()=>{
  421. getList()
  422. },500)
  423. timeNum.value ++;
  424. return
  425. }
  426. timeNum.value = 0;
  427. isSearch.value = false;
  428. let data = proxy.$refs.view.getPage();
  429. requestList(data);
  430. }
  431. const requestList = data => {
  432. load.value = true;
  433. data.pageNum = data.pageNo;
  434. delete data.pageNo;
  435. appList(data).then(res => {
  436. load.value = false;
  437. proxy.$refs.view.setTableValue(res.data.records);
  438. let page = {
  439. pageNo: res.data.current, //当前页
  440. pageSize: data.pageSize, //每页条数
  441. total: res.data.total //总条数
  442. };
  443. proxy.$refs.view.setPage(page)
  444. }).catch(()=>{
  445. load.value = false;
  446. })
  447. }
  448. nextTick(()=>{
  449. getList()
  450. })
  451. const calculateTable = () => {
  452. nextTick(() => {
  453. proxy.$refs.view.initTable()
  454. })
  455. }
  456. defineExpose({
  457. calculateTable
  458. })
  459. initLog()
  460. </script>
  461. <style scoped>
  462. .page-log{
  463. width: 100%;
  464. display: flex;
  465. justify-content: flex-end;
  466. }
  467. </style>