Jelajahi Sumber

Merge branch 'master' of http://git.dgtis.com/zhangningning/ali_ai_learn_web

zhangningning 1 bulan lalu
induk
melakukan
bbbb67d0ff

+ 11 - 1
src/api/my.js

@@ -47,6 +47,12 @@ export function delectQuest(data = {}) {
 export function updateQuestStatus(data = {}) {
   return request.put(`/quest/updateQuestStatus`,data)
 }
+
+// 拒绝同意
+export function applyUpdateQuestStatus(data = {}) {
+  return request.put(`/apply/updateStatus`,data)
+}
+
 // 取消报名
 export function cancelApply(data = {}) {
   return request.del(`/apply/${data}`)
@@ -109,7 +115,7 @@ export function sendSubAccount(data = {}) {
 
 // 分配积分
 export function allocatePoints(data = {}) {
-  return request.post('/employee/allocatePoints',data)
+  return request.put('/employee/allocatePoints',data)
 }
 
 // 计算可分配积分
@@ -124,4 +130,8 @@ export function deleteSubAccount(data = {}) {
 // 查询员工
 export function employeeList(data = {}) {
   return request.get('/employee/list',data)
+}
+// 根据手机号查询员工
+export function selectUserByPhone(data = {}) {
+  return request.get('/auth/user/selectUserByPhone',data)
 }

TEMPAT SAMPAH
src/assets/imgs/my/search@2x.png


+ 5 - 2
src/locales/en.js

@@ -56,7 +56,7 @@ export default {
     signUpDeadline: 'Sign Up Deadline',
     publish: 'Publish',
     actualAmount: 'Actual Amount',
-    goPay: 'Go Pay',
+    goPay: 'Pay',
     cancelOrder: 'Cancel Order',
     applyInvoice: 'Apply Invoice',
     applyRefund: 'Apply Refund',
@@ -64,7 +64,7 @@ export default {
     orderTime: 'Order Time',
     collected: 'Collected',
     cancelCollect: 'Cancel Collect',
-    orderCreateTime: 'Order Create Time',
+    orderCreateTime: 'Application for invoice issuance time',
     viewDetails: 'View Details',
     publishWorkflow: 'Publish Workflow',
     agree: 'Agree',
@@ -111,6 +111,7 @@ export default {
     fullscreenEdit:"Fullscreen Edit",
     expand:"Expand",
     collapse:"Collapse",
+    warning:"Warning",
   },
   login: {
     smsLogin: 'Captcha Login',
@@ -250,5 +251,7 @@ export default {
     vipEndTime: 'VIP End Time',
     businessManagement:'Enterprise information management',
     serviceManagement:'Customer Service Management',
+    jieshuxuqiu: 'Should this requirement be closed',
+    shifoushanchu:'Delete?'
   }
 }

+ 7 - 3
src/locales/zh-CN.js

@@ -61,7 +61,7 @@ export default {
     signUpDeadline: '报名截止时间',
     publish: '发布',
     actualAmount: '实际金额',
-    goPay: '支付',
+    goPay: '支付',
     cancelOrder: '取消订单',
     applyInvoice: '申请开票',
     applyRefund: '申请退款',
@@ -69,7 +69,7 @@ export default {
     orderTime: '下单时间',
     collected: '已收藏',
     cancelCollect: '取消收藏',
-    orderCreateTime: '订单创建时间',
+    orderCreateTime: '申请开票时间',
     viewDetails: '查看详情',
     publishWorkflow: '发布工作流',
     agree: '同意',
@@ -117,6 +117,7 @@ export default {
     fullscreenEdit:"全屏编辑",
     expand:"展开",
     collapse:"收起",
+    warning: "警告",
   },
   login: {
     smsLogin: '验证码登录',
@@ -253,7 +254,10 @@ export default {
     details: '明细',
     vipEndTime: '会员到期时间',
     businessManagement:'企业信息管理',
-    serviceManagement:'客服管理'
+    serviceManagement:'客服管理',
+    jieshuxuqiu:'是否结束该需求',
+    shifoushanchu:'是否删除?',
+    
   }
 
 }

+ 18 - 19
src/pages/Member.vue

@@ -19,18 +19,18 @@
           <!-- <div class="price-right">¥79.00/月</div> -->
         </div>
         <div class="btn" @click="confirmBuy({
-                callback:getList,
-                appStore,
-                router,
-                type:'baoMiBalance',
-                price:item.price,
-                t,
-                productId:item.typeId,
-                orderType:'member_recharge',
-                payMethod:'BMI'
-              })">开通{{ item.typeName }}</div>
+          callback: getList,
+          appStore,
+          router,
+          type: 'baoMiBalance',
+          price: item.price,
+          t,
+          productId: item.typeId,
+          orderType: 'member_recharge',
+          payMethod: 'BMI'
+        })">开通{{ item.typeName }}</div>
         <div class="line">尊享权益</div>
-        <div class="ul">
+        <div class="ul" v-if="item.privilege?.length">
           <div v-for="(em, ind) in item.privilege" :key="ind" class="li flex-center-between">
             <div class="">{{ em.privilegeName }}</div>
             <div class="">{{ em.privilegeValue }}{{ em.unit }}</div>
@@ -51,13 +51,13 @@ import { useRouter } from 'vue-router'
 
 import { useAppStore } from '@/pinia/appStore'
 
-import { vipList,privilege } from '@/api/my.js';
+import { vipList, privilege } from '@/api/my.js';
 
 import { confirmBuy } from '@/utils/util.js'
 
-import { useI18n } from 'vue-i18n' 
+import { useI18n } from 'vue-i18n'
 
-const { t } = useI18n() 
+const { t } = useI18n()
 
 const appStore = useAppStore()
 
@@ -67,10 +67,11 @@ const list = ref([])
 
 const getList = async () => {
   let res = await vipList();
-  res.data.forEach(async element => {
-    let privilegeRes = await privilege(element.typeId);
+  res.data.map(async element => {
+    let privilegeRes = await privilege(element.memberType);
     element.privilege = privilegeRes.data;
   });
+  console.log(res.data)
   list.value = res.data;
 }
 
@@ -80,9 +81,7 @@ onMounted(() => {
 
 </script>
 <style>
-body {
-  
-}
+body {}
 </style>
 <style lang="scss">
 .member {

+ 186 - 23
src/pages/Personal/BusinessManagement.vue

@@ -14,11 +14,11 @@
           <div class="custom-tree-node flex-center-between flex_1">
             <div class="">{{ node.label }}</div>
             <div @click.stop="" v-if="data.isBtn" class="flex-align-center custom-tree-node-right">
-              <el-input v-model="input" placeholder="Please input" />
-              <img @click.stop="changeNode(data,index,0)" src="/src/assets/imgs/my/jia2@2x.png" alt="">
+              <el-input v-model="node.label" placeholder="请输入" @keydown="(e) => changeLabel(e, data,node)" />
+              <img @click.stop="changeNode(data, index, 0)" src="/src/assets/imgs/my/jia2@2x.png" alt="">
 
-              <img  @click.stop="changeNode(data,index,1)" src="/src/assets/imgs/my/bianji@2x.png" alt="">
-              <img  @click.stop="changeNode(data,index,2)" src="/src/assets/imgs/my/shanchu@2x.png" alt="">
+              <img @click.stop="changeNode(data, index, 1)" src="/src/assets/imgs/my/bianji@2x.png" alt="">
+              <img @click.stop="changeNode(data, index, 2)" src="/src/assets/imgs/my/shanchu@2x.png" alt="">
               <!-- <el-button type="primary" link @click="append(data)">
                 Append
               </el-button>
@@ -35,20 +35,20 @@
         <div class="line_vertical"></div>
         <div class="">我的员工</div>
       </div>
-      <div class="flex-center-around">
-        <div class="flex-align-center">
-          <img src="" alt="">
-          <input type="text" placeholder="请输入要搜索的员工手机号">
+      <div class="flex-center-between businessManagement-right-search">
+        <div class="flex-align-center businessManagement-right-search-left">
+          <img src="/src/assets/imgs/my/search@2x.png" alt="">
+          <input @input="changePhone" type="text" placeholder="请输入要搜索的员工手机号" maxlength="11" v-model="form.userPhone">
         </div>
-        <div class="flex-align-center">
-          <div class="flex-align-center" @click="">
+        <div class="flex-align-center businessManagement-right-search-right">
+          <div class="flex-center gradient" @click="dialogVisible = true">
             <img src="/src/assets/imgs/my/jia1@2x.png" alt="">
-            <div class="">添加</div>
+            <span>添加</span>
           </div>
         </div>
       </div>
       <ul class="list">
-        <li v-for="(item,index) in list" :key="index">
+        <li v-for="(item, index) in list" :key="index">
           <div class="list_left">
             <el-avatar :size="52" :src="item.userAvatar" />
             <div class="list_left_con">
@@ -57,11 +57,11 @@
             </div>
           </div>
           <div class="list_right">
-            <div class="">
+            <div @click="changeEmployee(item, index, 1)" class="">
               <img src="/src/assets/imgs/my/jifen@2x.png" alt="">
               <span>分配</span>
             </div>
-            <div class="">
+            <div @click="changeEmployee(item, index, 2)" class="">
               <img src="/src/assets/imgs/my/shanchu@2x.png" alt="">
               <span>删除</span>
             </div>
@@ -74,13 +74,51 @@
       </template>
       <el-empty v-else :description="$t('common.empty')" />
     </div>
+
+    <el-dialog v-model="dialogVisible" title="添加员工" width="600">
+      <el-form :model="formInline" :rules="rules" class="demo-form-inline" ref="ruleFormRef">
+        <el-row :gutter="0">
+          <el-col :span="24">
+            <el-form-item label="部门" prop="deptId">
+              <el-tree-select v-model="formInline.deptId" :data="dataSource" :props="defaultProps" />
+            </el-form-item>
+          </el-col>
+
+        </el-row>
+        <el-row :gutter="0">
+          <el-col :span="24">
+            <el-form-item label="员工" prop="userPhone">
+              <!-- <el-input v-model="formInline.userPhone" placeholder="Approved by" clearable /> -->
+              <el-select v-model="formInline.userPhone" filterable remote reserve-keyword placeholder="请输入"
+                :remote-method="remoteMethod">
+                <el-option v-for="item in options" :key="item.userPhone" :label="item.nickName"
+                  :value="item.userPhone" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+
+        </el-row>
+      </el-form>
+
+
+
+      <template #footer>
+        <div class="dialog-footer flex-center">
+          <el-button @click="dialogVisible = false">Cancel</el-button>
+          <el-button type="primary" @click="confirmSubAccount(ruleFormRef)">
+            Confirm
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+
   </div>
 </template>
 <script setup lang="ts">
 
 import { ref, onMounted } from 'vue';
 
-import { deptList, employeeList,applyDept ,deleteDept} from '@/api/my';
+import { deptList, employeeList, applyDept, deleteDept, addSubAccount, deleteSubAccount, selectUserByPhone, allocatePoints, getAvailablePoints } from '@/api/my';
 
 import Pagination from '@/components/Pagination.vue'
 
@@ -91,17 +129,89 @@ const dataSource = ref([])
 const defaultProps = {
   children: 'children',
   label: 'deptName',
+  value: 'deptId'
 }
 
 const form = ref({
   total: 0,
   pageSize: 10,
   pageNum: 1,
+  userPhone: ''
 })
+
+const dialogVisible = ref(false);
+
+const ruleFormRef = ref(null);
+
+const formInline = ref({
+  deptId: '',
+  userPhone: ''
+})
+
+const options = ref([])
+
+const rules = ref({
+  deptId: [{ required: true, message: 'Please input Activity name', trigger: 'change' }],
+  userPhone: [{ required: true, message: 'Please input Activity name', trigger: 'change' }]
+})
+
+const changeEmployee = async (item, index, type) => {
+  if (type == 1) {
+    let res = await getAvailablePoints();
+    console.log(res)
+    let result = await allocatePoints({
+      points: 1,
+      userId: item.userId
+    })
+    if (result.code === 200) {
+      getemployeeList();
+    }
+  } else if (type == 2) {
+    let res = await deleteSubAccount(item.userId)
+    if (res.code == 200) {
+      getemployeeList();
+    }
+  }
+}
+
+// 添加员工
+const confirmSubAccount = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      let res = await addSubAccount(formInline.value);
+
+      getemployeeList();
+      dialogVisible.value = false;
+    } else {
+      console.log('error submit!', fields)
+    }
+  })
+
+}
+
+// 搜索员工
+const remoteMethod = async (query: string) => {
+  if (query && query.length == 11) {
+    let res = await selectUserByPhone({
+      userPhone: query
+    });
+    options.value = res.data ? [res.data] : [];
+  } else {
+    options.value = [];
+  }
+}
+
+const changePhone = (e) => {
+  if (e.target.value.length == 11 || e.target.value.length == 0) {
+    getemployeeList();
+  }
+}
+
 const handlePageChange = (pageNum) => {
   form.value.pageNum = pageNum;
   getemployeeList();
-} 
+}
 
 const getList = async () => {
   let res = await deptList();
@@ -110,7 +220,7 @@ const getList = async () => {
   getemployeeList();
 }
 
-const addFieldsToAllElements = (arr)=> {
+const addFieldsToAllElements = (arr) => {
 
   // 遍历当前层级的每一个元素
   arr.map(element => {
@@ -126,18 +236,18 @@ const addFieldsToAllElements = (arr)=> {
 }
 
 const getemployeeList = async () => {
-  let res = await employeeList();
+  let res = await employeeList(form.value);
   console.log(res.rows);
   list.value = res.rows;
   form.value.total = res.total;
 }
 
-const changeNode = async (item,index,type) => {
-  console.log(item,index,type)
+const changeNode = async (item, index, type) => {
+  console.log(item, index, type)
   if (type == 0) {
     let res = await applyDept({
-      deptName:'测试部门1730',
-      parentId:item.deptId
+      deptName: '测试部门1730',
+      parentId: item.deptId
     })
     getList()
   } else if (type == 1) {
@@ -148,6 +258,10 @@ const changeNode = async (item,index,type) => {
   }
 }
 
+const changeLabel = async (e, data,node) => {
+  console.log(e, data,node);
+}
+
 const handleNodeClick = (data) => {
   // console.log(data.isBtn = true)
   data.isBtn = !data.isBtn
@@ -202,6 +316,54 @@ onMounted(() => {
   .businessManagement-right {
     margin-left: 16px;
     flex: 1;
+
+    .title {
+      color: #333333;
+      font-size: 20px;
+      font-weight: bold;
+    }
+
+    .businessManagement-right-search {
+      padding: 16px 0;
+
+      .businessManagement-right-search-left {
+        width: 278px;
+        height: 32px;
+        padding: 0 12px;
+        background: #F5F7FA;
+        border-radius: 4px;
+        border: 1px solid #DCDFE6;
+
+        img {
+          width: 16px;
+          height: 16px;
+          margin-right: 4px;
+        }
+
+        input {
+          font-size: 14px;
+          border: none;
+          outline: none;
+          background: transparent;
+        }
+      }
+
+      .businessManagement-right-search-right {
+        div {
+          color: #FFFFFF;
+          font-size: 14px;
+          width: 78px;
+          height: 32px;
+          border-radius: 4px;
+          cursor: pointer;
+
+          img {
+            width: 14px;
+            height: 14px;
+          }
+        }
+      }
+    }
   }
 }
 
@@ -223,6 +385,7 @@ onMounted(() => {
 
 .list {
   display: flex;
+  flex-wrap: wrap;
   justify-content: space-between;
   gap: 16px;
 
@@ -281,7 +444,7 @@ onMounted(() => {
         }
 
         &:last-child {
-         color: #E43434;
+          color: #E43434;
         }
       }
     }

+ 48 - 21
src/pages/Personal/Demand.vue

@@ -6,7 +6,8 @@
           <li v-for="(item, index) in list" :key="index">
             <div class="flex-center-between">
               <div class="flex-align-center">
-                <div v-if="form.activeName == 1" class="tag" :class="{'tag_red':item.applyStatus == 2}">{{ item.applyStatus == 1 ? '报名中' : '已结束' }}{{ item.applyStatus }}</div>
+                <div v-if="form.activeName == 1" class="tag" :class="{ 'tag_red': item.applyStatus == 2 }">{{
+                  item.applyStatus == 1 ? '报名中' : '已结束' }}{{ item.applyStatus }}</div>
                 <div class="title">{{ item.title }}</div>
               </div>
               <div class="price">¥{{ item.budgetMin }}-{{ item.budgetMax }}</div>
@@ -80,7 +81,10 @@
         <div class="detail-top">
           <div class="flex-center-between">
             <div class="flex-align-center">
-              <div class="tag" :class="{'tag_red':itemData.applyStatus == '2'}">{{ itemData.applyStatus == 1 ? '报名中' : '已结束' }}</div>
+              <div class="tag" :class="{ 'tag_red': itemData.applyStatus == '2' }">{{ itemData.applyStatus == 1 ? '报名中'
+                :
+                '已结束'
+              }}</div>
               <div class="name">{{ itemData.title }}</div>
             </div>
             <div class="price">¥{{ itemData.budgetMin }}-{{ itemData.budgetMax }}</div>
@@ -105,7 +109,8 @@
           </div>
           <div class="time">{{ itemData.publishTime }} {{ $t('common.publish') }}</div>
         </div>
-        <div class="detail-txt">{{ $t('personalCenter.baomiliang') }}({{ itemData.questApplyCount || 0 }} {{ $t('personalCenter.ren') }})</div>
+        <div class="detail-txt">{{ $t('personalCenter.baomiliang') }}({{ itemData.questApplyCount || 0 }} {{
+          $t('personalCenter.ren') }})</div>
         <ul class="detail-list">
           <li v-for="(item, index) in recordList" :key="index">
             <div class="flex-align-center detail-list-left">
@@ -115,18 +120,21 @@
             </div>
             <div class="detail-list-number">{{ $t('personalCenter.gongzuoliuliang') }}:{{ item.publishCount }}</div>
             <div class="flex-align-center detail-list-right">
-              <div class="lex-align-center btn green">
-                <img src="/src/assets/imgs/my/dui@2x.png" alt="">
-                <div class="">{{ $t('common.agree') }}</div>
-              </div>
-              <div class="lex-align-center btn red">
-                <img src="/src/assets/imgs/my/quxiao@2x.png" alt="">
-                <div class="">{{ $t('common.reject') }}</div>
-              </div>
-              <div class="lex-align-center btn blue">
+              <template v-if="item.applyStatus == 0">
+                <div @click="changeDemand(item, index, 1)" class="lex-align-center btn green">
+                  <img src="/src/assets/imgs/my/dui@2x.png" alt="">
+                  <div class="">{{ $t('common.agree') }}</div>
+                </div>
+                <div @click="changeDemand(item, index, 2)" class="lex-align-center btn red">
+                  <img src="/src/assets/imgs/my/quxiao@2x.png" alt="">
+                  <div class="">{{ $t('common.reject') }}</div>
+                </div>
+              </template>
+
+              <!-- <div @click="changeDemand(item, index, 3)" class="lex-align-center btn blue">
                 <img src="/src/assets/imgs/my/jilu@2x.png" alt="">
                 <div class="">{{ $t('common.viewHomepage') }}</div>
-              </div>
+              </div> -->
             </div>
           </li>
         </ul>
@@ -149,7 +157,7 @@ import { useAppStore } from '@/pinia/appStore'
 import type { TabsPaneContext } from 'element-plus'
 import Pagination from '@/components/Pagination.vue'
 
-import { getWorkflowApplyByUserId, userQuestList, appliList, updateQuestStatus, delectQuest, cancelApply } from '@/api/my.js'
+import { getWorkflowApplyByUserId, userQuestList, appliList, updateQuestStatus, delectQuest, cancelApply, applyUpdateQuestStatus } from '@/api/my.js'
 
 import { useRoute, useRouter } from 'vue-router'
 
@@ -186,20 +194,37 @@ const itemData = ref({})
 
 const recordList = ref([])//报名记录
 
+// 同意拒绝
+const changeDemand = async (item, index, applyStatus) => {
+  if (applyStatus == 3) {
+
+  } else {
+    let res = await applyUpdateQuestStatus({
+      id: item.id,
+      applyUserId: item.applyUserId,
+      applyStatus
+    })
+    if (res.code === 200) {
+      DGTMessage.success(`${t('common.success')}`)
+      dialogVisible.value = false;
+    }
+  }
+
+}
+
 const changeItem = async (item, index, type) => {
   itemData.value = item;
   if (type == 0) {
 
     let res = await appliList({ questId: item.questId })
-    console.log(res)
     recordList.value = res.rows;
     dialogVisible.value = true;
   } else if (type == 1) {
     router.push({ path: `/workflow-trade/workflow-trade-add`, query: { id: item.questId } });
   } else if (type == 2) {
     ElMessageBox.confirm(
-      'proxy will permanently delete the file. Continue?',
-      'Warning1',
+      t('personalCenter.jieshuxuqiu') + '?',
+      t('common.warning'),
       {
         confirmButtonText: 'OK',
         cancelButtonText: t('common.cancel'),
@@ -220,8 +245,8 @@ const changeItem = async (item, index, type) => {
       })
   } else if (type == 3) {
     ElMessageBox.confirm(
-      'proxy will permanently delete the file. Continue?',
-      'Warning',
+      t('personalCenter.shifoushanchu'),
+       t('common.warning'),
       {
         confirmButtonText: 'OK',
         cancelButtonText: t('common.cancel'),
@@ -323,6 +348,7 @@ onMounted(() => {
         border-radius: 4px;
         margin-right: 8px;
       }
+
       .tag_red {
         background: #E43434;
       }
@@ -435,9 +461,10 @@ onMounted(() => {
       background: #2D71FF;
       border-radius: 4px;
     }
+
     .tag_red {
-        background: #E43434;
-      }
+      background: #E43434;
+    }
 
     .name {
       font-size: 18px;

+ 85 - 4
src/pages/Personal/Invoice.vue

@@ -6,6 +6,9 @@
     </div>
     <ul class="invoice-list">
       <li v-for="(item, index) in list" :key="index">
+        <div class="">
+          <div class="btn">{{ item.invoiceStatusName }}</div>
+        </div>
         <div class="invoice-list-t flex-center-between">
           <div class="">{{ item.content.name }}</div>
           <div class="">¥{{ item.content.price }}</div>
@@ -16,11 +19,11 @@
         </div>
         <div class="flex-center-between invoice-list-time">
           <div class="">{{ $t('common.orderCreateTime') }}:</div>
-          <div class="">2025-10-24 13:00</div>
+          <div class="">{{ item.createTime }}</div>
         </div>
-        <div class="flex-center-between invoice-list-b">
+        <div v-if="item.invoiceStatus == 2" class="flex-center-between invoice-list-b">
           <div class=""></div>
-          <div class="">
+          <div class="" @click="lookItem(item)">
             <img src="/src/assets/imgs/my/jilu@2x.png" alt="">
             <span>{{ $t('common.viewDetails') }}</span>
           </div>
@@ -32,6 +35,60 @@
         @page-change="handlePageChange" />
     </template>
     <el-empty v-else :description="$t('common.empty')" />
+
+    <el-dialog v-model="dialogVisible" title="详情" width="700">
+      <el-form :model="invoiceData">
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="购方名称">
+              <el-input v-model="invoiceData.invoiceTitle" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="invoiceData.invoiceType">
+            <el-form-item label="购方税号">
+              <el-input v-model="invoiceData.taxNumber" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <template v-if="invoiceData.invoiceType">
+          <el-row :gutter="16">
+            <el-col :span="12">
+              <el-form-item label="公司地址">
+                <el-input v-model="invoiceData.otherInfo.address" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="公司电话">
+                <el-input v-model="invoiceData.otherInfo.mobile" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="16">
+            <el-col :span="12">
+              <el-form-item label="公司开户行">
+                <el-input v-model="invoiceData.otherInfo.bank" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="开户行账号">
+                <el-input v-model="invoiceData.otherInfo.account" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </template>
+
+      </el-form>
+      <!-- <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="dialogVisible = false">Cancel</el-button>
+          <el-button type="primary" @click="dialogVisible = false">
+            Confirm
+          </el-button>
+        </div>
+      </template> -->
+    </el-dialog>
+
+
   </div>
 </template>
 <script setup lang="ts">
@@ -45,13 +102,26 @@ const form = ref({
   total: 0
 })
 
+const dialogVisible = ref(false);
+const invoiceData = ref({})
+
+const lookItem = (item) => {
+  invoiceData.value = item;
+  dialogVisible.value = true;
+}
+
+// 查看发票
+const handleClick = (item) => {
+  location.href = item.invoiceUrl;
+}
+
 
 // 获取列表
 const getList = async () => {
   let res = await invoiceList(form.value)
   console.log(res.rows)
   res.rows.forEach(element => {
-     element.content = JSON.parse(element.content)
+    element.content = JSON.parse(element.content)
   });
   list.value = res.rows || [];
   form.value.total = res.total;
@@ -85,6 +155,17 @@ onMounted(() => {
       background: #F5F7FA;
       border-radius: 16px;
 
+      .btn {
+        color: #FFFFFF;
+        width: 66px;
+        line-height: 30px;
+        font-size: 14px;
+        text-align: center;
+        background: #2D71FF;
+        border-radius: 4px;
+        margin-bottom: 8px;
+      }
+
       &:last-child {
         margin-bottom: 0;
       }

+ 49 - 11
src/pages/Personal/Orders.vue

@@ -7,10 +7,10 @@
             <div class="order-list-top flex-center-between">
               <div class="order-list-top-l flex-align-center">
                 <el-tag
-                  :type="item.orderStatus == 0 ? 'primary' : item.orderStatus == 1 ? 'success' : item.orderStatus == 3 ? 'danger' : ''">{{
+                  :type="item.orderStatus == 0 ? 'primary' : item.orderStatus == 1 ? 'success' : item.orderStatus == 2 ? 'danger' : ''">{{
                     item.orderStatus == 0 ?
                       $t('personalCenter.daifukuan') : item.orderStatus == 1 ? $t('personalCenter.yiwancheng') :
-                        item.orderStatus == 3 ?
+                        item.orderStatus == 2 ?
                           $t('personalCenter.yiquxiao') : '' }}</el-tag>
                 <div class="">{{ $t('personalCenter.dingdanhao') }}: {{ item.orderNo }}</div>
               </div>
@@ -30,20 +30,27 @@
               <div class="order-list-main-r flex">
                 <div class="order-list-con flex-center-between flex_1">
 
-                  <!-- <div class="mi_price">
-                  <div class="">{{ item.amount }}</div>
-                  <div class="">{{ item.payMethod == 'BMI' ? $t('common.baomibi') : $t('common.mibi') }}</div>
-                </div> -->
+
                   <div class="mi_price price">
                     <div class="">{{ item.amount || 0 }}{{ item.amountUnit }}</div>
-                    <div class="">{{ item.payMethod == 'BMI' ? $t('common.baomibi') : item.payMethod == 'MI' ?
-                      $t('common.mibi') : $t('common.rmb') }}</div>
+                    <div class="">{{ item.payMethodName }}</div>
+                  </div>
+                  <div class="mi_price">
+                    <div class="">{{ item.orderNum }}</div>
+                    <div class=""></div>
+                    <!-- <div class="">{{ item.payMethod == 'BMI' ? $t('common.baomibi') : $t('common.mibi') }}</div> -->
                   </div>
                   <div class="">
-                    <div v-if="item.invoiceStatus == 0" @click="applyInvoices(item, index)" class="blue btn">
+                    <div v-if="item.invoiceStatus == 0 && item.orderStatus == 1" @click="applyInvoices(item, index)"
+                      class="blue btn">
                       <img src="/src/assets/imgs/my/order3@2x.png" alt="">
                       <div class="">{{ $t('common.applyInvoice') }}</div>
                     </div>
+
+                    <div class="gradient btn" v-else-if="item.orderStatus == 0" @click="pay(item)">
+                      <img src="/src/assets/imgs/my/order1@2x.png" alt="">
+                      <div class="">{{ $t('common.goPay') }}</div>
+                    </div>
                     <div class="btn_kong" v-else></div>
                     <template v-if="false">
                       <template v-if="index == 0">
@@ -171,12 +178,31 @@
   </div>
 </template>
 <script lang="ts" setup>
+
 import { ref, onMounted, reactive } from 'vue'
 
 import type { TabsPaneContext } from 'element-plus'
+
+import { useRouter } from 'vue-router'
+
+import { useAppStore } from '@/pinia/appStore'
+
 import Pagination from '@/components/Pagination.vue'
+
 import { orderList, applyInvoice } from '@/api/my.js'
 
+import { confirmBuy } from '@/utils/util.js'
+
+import { useI18n } from 'vue-i18n'
+
+import DGTMessage from '@/utils/message'
+
+const { t } = useI18n()
+
+const appStore = useAppStore()
+
+const router = useRouter()
+
 const tabs = ref([
   { label: 'personalCenter.allOrders', name: '' },
   { label: 'personalCenter.daifukuan', name: 0 },
@@ -227,7 +253,6 @@ const rules = reactive<FormRules<RuleForm>>({
 const submitForm = async (formEl: FormInstance | undefined) => {
   if (!formEl) return
   let valid = await formEl.validate();
-  console.log(valid)
   if (valid) {
 
     let { invoiceType,
@@ -244,8 +269,8 @@ const submitForm = async (formEl: FormInstance | undefined) => {
       remark,
       otherInfo: JSON.stringify(invoiceData.value.otherInfo)
     });
-    console.log(res)
     if (res.code === 200) {
+      DGTMessage.success(`${t('common.success')}`)
       getList()
     }
     dialogVisible.value = false;
@@ -258,6 +283,19 @@ const handleClick = (tab: TabsPaneContext) => {
   getList()
 }
 
+const pay = async (item, index) => {
+  confirmBuy({
+    callback: getList,
+    appStore,
+    router,
+    type: 'baoMiBalance',
+    price: item.amount,
+    t,
+    productId: item.orderId,
+    orderType: item.orderType,
+    payMethod: item.payMethod
+  })
+}
 
 // 申请开票
 const applyInvoices = (item, index) => {

+ 4 - 1
src/pages/Personal/Wallet.vue

@@ -33,7 +33,7 @@
               <div class="">{{ item.bizTypeName }}</div>
               <div class="">{{ item.createTime }}</div>
             </div>
-            <div class="price">{{ form.changeType == 1 ? '+' : '' }}{{ item.balanceChange }}</div>
+            <div class="price" :class="{green:form.changeType == 1}">{{ form.changeType == 1 ? '+' : '' }}{{ item.balanceChange }}</div>
           </li>
         </ul>
       </el-tab-pane>
@@ -344,6 +344,9 @@ onMounted(() => {
       font-weight: bold;
       color: #F52929;
     }
+    .green {
+      color: #1FB362;
+    }
   }
 }
 

+ 173 - 16
src/pages/PersonalCenter.vue

@@ -3,7 +3,8 @@
     <Breadcrumb />
     <div class="personal-head">
       <div class="personal-head-left">
-        <el-avatar :size="100" :src="appStore?.userInfo?.userAvatar ? appStore.userInfo.userAvatar : appStore.avatarDefault" />
+        <el-avatar :size="100"
+          :src="appStore?.userInfo?.userAvatar ? appStore.userInfo.userAvatar : appStore.avatarDefault" />
         <div class="personal-user-info">
           <div class="personal-username">
             <div class="">{{ appStore?.userInfo?.nickName }}</div>
@@ -11,15 +12,19 @@
             <img :src="`/src/assets/imgs/my/vip${appStore?.userInfo?.memberType}@2x.png`" alt="">
             <!-- memberType  会员类型memberType 会员类型分为企业会员(2)和个人会员(1)、免费会员(0) -->
           </div>
-          <div class="personal-user-phone mt4">{{ $t('personalCenter.phoneNumber') }}:{{ appStore?.userInfo?.userPhone }}
+          <div class="personal-user-phone mt4">{{ $t('personalCenter.phoneNumber') }}:{{ appStore?.userInfo?.userPhone
+          }}
           </div>
-          <div class="">{{ $t('personalCenter.vipEndTime') }}: {{ appStore?.userInfo?.memberExpire }}</div>
+          <div class="" v-if="['1', '2'].includes(appStore?.userInfo?.memberType)">{{ $t('personalCenter.vipEndTime')
+          }}: {{
+              appStore?.userInfo?.memberExpire }}</div>
           <div class="mt4" v-if="appStore?.userInfo?.skillTags">
-            <el-button v-for="(item,index) in appStore.userInfo.skillTags.split(',')" type="primary" plain>{{ item }}</el-button>
+            <el-button v-for="(item, index) in appStore.userInfo.skillTags.split(',')" type="primary" plain>{{ item
+            }}</el-button>
           </div>
           <div class="personal-user-list">
             <div class="personal-user-li">
-              <span>{{ appStore?.userInfo?.pointsBalance || 0}}</span>
+              <span>{{ appStore?.userInfo?.pointsBalance || 0 }}</span>
               <span>{{ $t('common.mibi') }}</span>
             </div>
             <div class="personal-user-line"></div>
@@ -70,6 +75,41 @@
       </div>
     </div>
 
+    <!-- 工单 -->
+
+    <div class="workOrder-dot" @click="show = true">
+      <img src="/src/assets/imgs/my/icon9a@2x.png" alt="">
+      <div class="">工单</div>
+    </div>
+
+    <el-dialog v-model="show" title="工单" width="784">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+        <el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name">
+          <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules">
+            <el-form-item label="工单类型" prop="issueCategory">
+              <el-input v-model="ruleForm.issueCategory" />
+            </el-form-item>
+            <el-form-item label="工单标题" prop="issueTitle">
+              <el-input v-model="ruleForm.issueTitle" />
+            </el-form-item>
+            <el-form-item label="工单内容" prop="issueContent">
+              <el-input v-model="ruleForm.issueContent" />
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+      </el-tabs>
+      <template #footer v-if="activeName == 0">
+        <div class="dialog-footer">
+          <el-button @click="dialogVisible = false">Cancel</el-button>
+          <el-button type="primary" @click="submitForm(ruleFormRef)">
+            Confirm
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+
+
     <el-dialog v-model="dialogVisible" title="编辑资料" width="784">
       <el-form :model="userInfo" label-width="auto" label-position="top">
 
@@ -93,13 +133,32 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="登录手机号">
-              <el-input :readonly="userInfo.userPhone ? true : false" v-model="userInfo.userPhone"
+              <el-input :disabled="userInfo.userPhone ? true : false" v-model="userInfo.userPhone"
                 :placeholder="$t('common.placeholderInput')" class="inputStyle" :input-style="{
                   backgroundColor: 'transparent',
                 }" />
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="登录邮箱">
+              <el-input v-model="userInfo.name" :placeholder="$t('common.placeholderInput')" class="inputStyle"
+                :input-style="{
+                  backgroundColor: 'transparent',
+                }" />
+            </el-form-item>
+
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="验证码" prop="verifyCode">
+              <el-input v-model="userInfo.verifyCode" :placeholder="$t('common.placeholderInput')" class="inputStyle"
+                :input-style="{
+                  backgroundColor: 'transparent',
+                }" />
+            </el-form-item>
+          </el-col>
+        </el-row>
         <el-row :gutter="16">
           <el-col :span="12">
             <el-form-item label="n8n账号">
@@ -109,6 +168,17 @@
                 }" />
             </el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="n8n初始密码">
+              <el-input v-model="userInfo.name" :placeholder="$t('common.placeholderInput')" class="inputStyle"
+                :input-style="{
+                  backgroundColor: 'transparent',
+                }" />
+            </el-form-item>
+          </el-col>
+
+        </el-row>
+        <el-row :gutter="16">
           <el-col :span="12">
             <el-form-item label="Coze账号">
               <el-input v-model="userInfo.name" :placeholder="$t('common.placeholderInput')" class="inputStyle"
@@ -116,6 +186,15 @@
                   backgroundColor: 'transparent',
                 }" />
             </el-form-item>
+
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="Coze初始密码">
+              <el-input v-model="userInfo.name" :placeholder="$t('common.placeholderInput')" class="inputStyle"
+                :input-style="{
+                  backgroundColor: 'transparent',
+                }" />
+            </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="16">
@@ -128,7 +207,7 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="FastGpt账号">
+            <el-form-item label="Dify初始密码">
               <el-input v-model="userInfo.name" :placeholder="$t('common.placeholderInput')" class="inputStyle"
                 :input-style="{
                   backgroundColor: 'transparent',
@@ -137,8 +216,17 @@
           </el-col>
         </el-row>
         <el-row :gutter="16">
+
           <el-col :span="12">
-            <el-form-item label="登录邮箱">
+            <el-form-item label="FastGpt账号">
+              <el-input v-model="userInfo.name" :placeholder="$t('common.placeholderInput')" class="inputStyle"
+                :input-style="{
+                  backgroundColor: 'transparent',
+                }" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="FastGpt初始密码">
               <el-input v-model="userInfo.name" :placeholder="$t('common.placeholderInput')" class="inputStyle"
                 :input-style="{
                   backgroundColor: 'transparent',
@@ -146,6 +234,7 @@
             </el-form-item>
           </el-col>
         </el-row>
+
         <el-row>
           <el-col :span="24">
             <el-form-item label="技能标签">
@@ -191,7 +280,7 @@ import type { InputInstance } from 'element-plus'
 
 import { useRoute, useRouter } from 'vue-router'
 
-import { getUserInfo,updateUserInfo } from '@/api/auth.js'
+import { getUserInfo, updateUserInfo } from '@/api/auth.js'
 
 import { checkIn, queryCollectCount } from '@/api/my.js'
 
@@ -257,7 +346,7 @@ const navList = ref([
     path: '/personal-center/business-management',
     icon: '/src/assets/imgs/my/icon8@2x.png',
     iconActive: '/src/assets/imgs/my/icon8a@2x.png',
-    show:true,
+    show: true,
   },
   // {
   //   name: 'personalCenter.serviceManagement',
@@ -269,6 +358,39 @@ const navList = ref([
 
 const dialogVisible = ref(false)
 
+const show = ref(false)
+
+const tabs = ref([
+  { label: '提交工单', name: 0 },
+  { label: '历史工单', name: 1 },
+  { label: '常见问题', name: 2 }
+])
+
+const activeName = ref(0)
+
+const ruleForm = ref({
+  issueCategory: '',
+  issueTitle: '',
+  issueContent: ''
+})
+
+const rules = ref({
+  issueCategory: [
+    {
+      type: 'date',
+      required: true,
+      message: '请选择工单类型',
+      trigger: 'change',
+    },
+  ],
+  issueTitle: [
+    { required: true, message: '请输入标题', trigger: 'blur' },
+  ],
+  issueContent: [
+    { required: true, message: '请输入内容', trigger: 'blur' },
+  ]
+})
+
 const navIndex = computed(() => {
   switch (route.name) {
     case 'Wallet':
@@ -308,17 +430,28 @@ const userInfo = ref({})//用户信息
 
 const coverImage = ref([]);
 
+const ruleFormRef = ref()
+
+const submitForm = async (formEl: any) => {
+  if (!formEl) return
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      console.log('submit!')
+    }
+  })
+}
+
 // 更新用户信息
-const handleConfirm = async () =>{
+const handleConfirm = async () => {
   let res = await updateUserInfo({
     nickName: userInfo.value.nickName,
-    userAvatar:coverImage.value.map(item => item.url).join(';'),
-    skillTags:dynamicTags.value.join(','),
-    userPhone:userInfo.value.userPhone,
+    userAvatar: coverImage.value.map(item => item.url).join(';'),
+    skillTags: dynamicTags.value.join(','),
+    userPhone: userInfo.value.userPhone,
   })
   if (res.code === 200) {
     appStore.USERINFO();
-    DGTMessage.success(`${t('common.modify')}${t('common.success')}`)    
+    DGTMessage.success(`${t('common.modify')}${t('common.success')}`)
     dialogVisible.value = false;
   }
 }
@@ -340,7 +473,7 @@ const signIn = async () => {
 const getInfo = async () => {
   let res = await getUserInfo();
   if (res?.user?.userAvatar) {
-    coverImage.value = [{url:res.user.userAvatar}]
+    coverImage.value = [{ url: res.user.userAvatar }]
   }
   if (res?.user?.skillTags) {
     dynamicTags.value = res.user.skillTags.split(',')
@@ -580,8 +713,32 @@ div {
   background: #F5F7FA;
   border-radius: 4px;
   border: 1px solid #F2F6FC;
+
   ::v-deep .el-input__wrapper {
     background-color: transparent;
   }
 }
+
+.workOrder-dot {
+  display: flex;
+  cursor: pointer;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  right: 100px;
+  bottom: 90px;
+  width: 64px;
+  height: 64px;
+  position: fixed;
+  color: #2D71FF;
+  font-size: 14px;
+  background: #FFFFFF;
+  box-shadow: 2px 2px 10px 0px rgba(45, 113, 255, 0.15);
+  border-radius: 50px;
+
+  img {
+    width: 24px;
+    height: 24px;
+  }
+}
 </style>