xiaohaizhao 1 kuukausi sitten
vanhempi
commit
a8732c737d
5 muutettua tiedostoa jossa 389 lisäystä ja 30 poistoa
  1. 10 4
      App.vue
  2. 23 7
      components/My_upload/My_upload.vue
  3. 294 7
      pages/index/my.vue
  4. 43 9
      pages/workOrder/changeMsg.vue
  5. 19 3
      static/iconfont.css

+ 10 - 4
App.vue

@@ -14,10 +14,16 @@ export default {
 				if (res.code == 1) {
 					uni.removeStorageSync('siteP');
 					uni.setStorageSync("siteP", res.data)
-					let currentPages = getCurrentPages().pop();
-					if (currentPages.route == 'pages/login/login' || currentPages.$page.fullPath == "/pages/login/login") uni.redirectTo({
-						url: '/pages/index/index',
-					});
+					try {
+						let currentPages = getCurrentPages().pop();
+						if (currentPages.route == 'pages/login/login' || currentPages.$page.fullPath == "/pages/login/login") uni.redirectTo({
+							url: '/pages/index/index',
+						});
+					} catch (error) {
+						uni.redirectTo({
+							url: '/pages/index/index',
+						});
+					}
 				}
 			})
 		}

+ 23 - 7
components/My_upload/My_upload.vue

@@ -1,11 +1,17 @@
 <template>
-    <up-upload :fileList="fileList" @after-read="afterRead" :deletable="!disabled" @delete="deletePic"
+    <view v-if="custom">
+        <up-upload @after-read="afterRead" :deletable="!disabled" @delete="deletePic"
+            :max-count="disabled ? fileList.length : maxCount" :accept="accept" multiple @clickPreview="clickPreview">
+            <slot />
+        </up-upload>
+    </view>
+    <up-upload v-else :fileList="fileList" @after-read="afterRead" :deletable="!disabled" @delete="deletePic"
         :max-count="disabled ? fileList.length : maxCount" :accept="accept" multiple @clickPreview="clickPreview" />
 </template>
 
 <script setup>
 import { ref, reactive, defineProps, defineEmits, getCurrentInstance, onUnmounted } from 'vue'
-const emit = defineEmits(['uploadCallback'])
+const emit = defineEmits(['uploadCallback', 'startUploading'])
 const props = defineProps({
     accept: {
         type: String,
@@ -18,6 +24,9 @@ const props = defineProps({
     uploadCallback: {
         type: Function
     },
+    startUploading: {
+        type: Function
+    },
     fileList: {
         type: Array,
         default: reactive([])
@@ -37,6 +46,10 @@ const props = defineProps({
     disabled: {
         type: Boolean,
         default: false
+    },
+    custom: {
+        type: Boolean,
+        default: false
     }
 })
 const { $Http } = getCurrentInstance().proxy;
@@ -52,17 +65,18 @@ const clickPreview = (e) => {
 
 // 文件读取后处理
 const afterRead = ({ file }) => {
+    emit('startUploading', file);
     file.forEach(v => {
         // #ifdef H5
         getArrayBuffer(v).then(data => {
             data.data.url = v.url;
+            console.log("data.data", data.data)
             handleUploadFile(requestType(v), data.data)
             props.fileList.push({
                 ...v,
                 status: 'uploading',
                 message: '上传中',
             });
-
         })
         // #endif
 
@@ -136,11 +150,13 @@ const getArrayBuffer = (file) => {
                 const files = new File(
                     [myBlob],
                     file.name,
-                    { type: file.type }
+                    { type: file.type },
                 )
                 const reader = new FileReader()
                 reader.readAsArrayBuffer(files)
-                reader.onload = () => resolve(reader.result)
+                reader.onload = () => resolve({
+                    data: reader.result
+                })
                 reader.onerror = error => reject(error)
             } else {
                 reject(`文件加载失败: ${this.status}`)
@@ -152,7 +168,6 @@ const getArrayBuffer = (file) => {
 }
 
 // 上传文件到服务器
-
 const uploadFile = (res, data) => {
     uni.request({
         url: res.uploadurl,
@@ -225,6 +240,7 @@ const saveFileLinks = (ownertable, ownerid, usetype = 'default') => {
     deleteList.length && deleteFile(deleteList);
     return new Promise((resolve, reject) => {
         const list = props.fileList;
+        console.log("list", list)
         if (list.length) {
             return handleFileLink(list, ownertable, ownerid, usetype, resolve);
         } else {
@@ -304,5 +320,5 @@ onUnmounted(() => {
     clearTemporaryFiles();
 })
 
-defineExpose({ isUploading, saveFileLinks })
+defineExpose({ isUploading, handleFileLink, saveFileLinks, deleteFile })
 </script>

+ 294 - 7
pages/index/my.vue

@@ -1,26 +1,235 @@
 <template>
-    <view class="user" hover-class="navigator-hover">
+    <view class="user" hover-class="navigator-hover" @click="popupShow = true">
         <view class="profile-photo">
-            <up-image :show-loading="true" src="/static/image/user.png" width="120rpx" height="120rpx" />
+            <up-image :show-loading="true" :src="user.profilePhoto" width="120rpx" height="120rpx" />
         </view>
         <view class="user-info">
-            <view class="user-name">用户名</view>
-            <view class="user-phone">用户ID</view>
+            <view class="user-name">{{ user.name }}</view>
+            <view class="user-phone">{{ user.phonenumber }}</view>
         </view>
+        <view class="iconfont icon-shezhi" />
     </view>
+
+    <up-popup :show="popupShow" mode="right" :customStyle="{
+        width: '80vw',
+        padding: '0 20rpx',
+        background: '#F7F7FF'
+    }" zIndex="99" @close="close" @open="open">
+        <view class="change-user">
+            <view class="title">
+                账号信息
+            </view>
+            <view class="row" v-if="headportraitLoading">
+                <view class="label">
+                    点击更换头像
+                </view>
+                <view class="value">
+                    <view class="profilePhoto">
+                        <up-image :show-loading="true" :src="user.profilePhoto" width="80rpx" height="80rpx" />
+                        <view class="loading">
+                            <up-loading-icon mode="semicircle" />
+                        </view>
+                    </view>
+                    <view class="iconfont icon-a-wodetiaozhuan" />
+                </view>
+            </view>
+            <My_upload ref="upload" custom maxCount="1" @uploadCallback="uploadCallback"
+                @startUploading="startUploading">
+                <view class="row" v-if="!headportraitLoading" style="width: calc(80vw);" hover-class="navigator-hover">
+                    <view class="label">
+                        点击更换头像
+                    </view>
+                    <view class="value">
+                        <view class="profilePhoto">
+                            <up-image :show-loading="true" :src="user.profilePhoto" width="80rpx" height="80rpx" />
+                        </view>
+                        <view class="iconfont icon-a-wodetiaozhuan" />
+                    </view>
+                </view>
+            </My_upload>
+
+            <view class="row" hover-class="navigator-hover" @click="modalShow = true">
+                <view class="label">
+                    用户昵称
+                </view>
+                <view class="value">
+                    {{ user.name }}
+                    <view class="iconfont icon-a-wodetiaozhuan" />
+                </view>
+            </view>
+
+            <view class="row">
+                <view class="label">
+                    手机号码
+                </view>
+                <view class="value">
+                    {{ user.phonenumber }}
+                </view>
+            </view>
+
+        </view>
+    </up-popup>
+    <view class="but">
+        <up-button type="primary" shape="circle" size="large" color="#3874F6" text="退出登录" @tap="logOut" />
+    </view>
+    <up-modal :show="modalShow" title="修改昵称" showCancelButton @confirm="confirm" @cancel="modalShow = false"
+        ref="uModal" :asyncClose="true">
+        <up-input focus :placeholder="user.name" border="surround" v-model="userName"></up-input>
+    </up-modal>
 </template>
 
-<script>
-export default {
+<script setup>
+import { ref, reactive, getCurrentInstance } from 'vue'
+const { $Http } = getCurrentInstance().proxy;
+import { onLoad } from '@dcloudio/uni-app';
+
+let user = reactive({
+    name: '',
+    phonenumber: '',
+    profilePhoto: "",
+    attinfos: []
+});
 
+onLoad(() => {
+    getUserMsg()
+    const userInfo = uni.getStorageSync('userMsg')
+    user.name = userInfo.name;
+    user.phonenumber = userInfo.phonenumber;
+    user.attinfos = userInfo.attinfos;
+    user.profilePhoto = userInfo.profilePhoto || '/static/image/user.png';
+});
+
+let popupShow = ref(false),
+    headportraitLoading = ref(false);
+function close() {
+    popupShow.value = false
+}
+
+let uModal = ref(null),
+    modalShow = ref(false),
+    userName = ref('');
+
+function confirm() {
+    console.log('修改昵称', userName.value);
+    if (userName.value.trim() == '') {
+        modalShow.value = false;
+        return uni.showToast({
+            title: '昵称不能为空',
+            icon: 'none'
+        })
+    }
+
+    $Http.basic({
+        "classname": "common.usercenter.usercenter",
+        "method": "updateUserMsg",
+        "content": {
+            "name": userName.value,
+            "phonenumber": user.phonenumber,
+        }
+    }).then(res => {
+        console.log(res)
+        uni.showToast({
+            title: res.code == 1 ? '修改成功' : res.msg,
+            icon: 'none'
+        })
+        modalShow.value = false;
+        if (res.code == 1) {
+            userName.value = '';
+            getUserMsg();
+        }
+    })
+}
+
+// 更换头像
+let upload = ref(null);
+
+function startUploading(e) {
+    headportraitLoading.value = true;
+}
+
+function uploadCallback({ attachmentids, fileList }) {
+    if (fileList.pop().usetype == 'headportrait') return;
+    $Http.basic({
+        "classname": "system.attachment.Attachment",
+        "method": "createFileLink",
+        content: {
+            ownertable: "sys_users",
+            ownerid: uni.getStorageSync('userMsg').userid,
+            usetype: 'headportrait',
+            attachmentids,
+            siteid: uni.getStorageSync("userMsg").siteid
+        }
+    }).then(res => {
+        console.log('跟进记录绑定附件', res)
+        if (res.code != '1') return uni.showToast({
+            title: res.msg,
+            icon: "none"
+        })
+        upload.value.deleteFile(user.attinfos.filter(v => v.usetype == 'headportrait')).then(res1 => {
+            if (res1) {
+                getUserMsg();
+                setTimeout(() => {
+                    uni.showToast({
+                        title: '头像更换成功',
+                        icon: 'none'
+                    });
+                }, 100);
+            }
+        })
+
+    })
+}
+
+function getUserMsg() {
+    $Http.basic({
+        "classname": "common.usercenter.usercenter",
+        "method": "queryUserMsg",
+        "content": { "nocache": true }
+    }).then(res => {
+        console.log("res", res);
+        if (res.code == 1) {
+            user.name = res.data.name;
+            user.phonenumber = res.data.phonenumber;
+            user.attinfos = res.data.attinfos;
+            headportraitLoading.value = false;
+            const headportrait = res.data.attinfos.find(v => v.usetype == 'headportrait');
+            user.profilePhoto = headportrait ? $Http.getSpecifiedImage(headportrait) : user.profilePhoto;
+            const userMsg = uni.getStorageSync('userMsg')
+            uni.setStorageSync('userMsg', Object.assign(userMsg, user))
+        }
+    })
+}
+
+
+function logOut() {
+    console.log('退出登录');
+    uni.showModal({
+        title: '提示',
+        content: '是否确定退出登录?',
+        success: function ({ confirm }) {
+            if (confirm) {
+                $Http.logout();
+                uni.removeStorageSync('userMsg');
+                uni.reLaunch({
+                    url: '/pages/login/login',
+                    success: () => {
+                        uni.showToast({
+                            title: '退出登录成功',
+                            icon: 'none'
+                        });
+                    }
+                });
+            }
+        }
+    });
 }
 </script>
 
 <style lang="less" scoped>
 .user {
     display: flex;
+    align-items: center;
     width: 100%;
-    height: 100%;
     background-color: #fff;
     box-sizing: border-box;
     padding: 40rpx;
@@ -29,6 +238,7 @@ export default {
         width: 120rpx;
         height: 120rpx;
         border-radius: 50%;
+        overflow: hidden;
     }
 
     .user-info {
@@ -53,4 +263,81 @@ export default {
 
     }
 }
+
+.change-user {
+    position: relative;
+    padding-top: 55px;
+    box-sizing: border-box;
+    height: 100%;
+
+    .title {
+        font-size: 28rpx;
+        color: #333;
+        margin-bottom: 30rpx;
+        padding-left: 20rpx;
+    }
+
+    .row {
+        width: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        background: #fff;
+        padding: 20rpx 30rpx;
+        border-radius: 16rpx;
+        box-sizing: border-box;
+        margin-bottom: 20rpx;
+
+        .label {
+            font-size: 28rpx;
+            color: #666;
+            flex-shrink: 0;
+            margin-right: 20rpx;
+        }
+
+        .value {
+            display: flex;
+            align-items: center;
+
+            .profilePhoto {
+                position: relative;
+                width: 80rpx;
+                height: 80rpx;
+                border-radius: 50%;
+                overflow: hidden;
+
+                .loading {
+                    position: absolute;
+                    top: 0;
+                    left: 0;
+                    width: 100%;
+                    height: 100%;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    background: rgba(0, 0, 0, 0.09);
+                    z-index: 1;
+                }
+            }
+
+            .iconfont {
+                font-size: 28rpx;
+                color: #999;
+                margin-top: 5rpx;
+            }
+        }
+
+
+
+    }
+
+}
+
+.but {
+    box-sizing: border-box;
+    width: 100vw;
+    position: fixed;
+    bottom: 16%;
+    padding: 0 60rpx;
+}
 </style>

+ 43 - 9
pages/workOrder/changeMsg.vue

@@ -4,6 +4,15 @@
             <view class="title" style="margin-top: 0;">
                 服务信息
             </view>
+
+            <up-form-item label="服务类型" :required="rules.servicetype[0].required" prop="servicetype">
+                <up-radio-group v-model="form.servicetype" @change="servicetypeChange">
+                    <up-radio :customStyle="{ marginLeft: '12px' }" v-for="(item) in servertypes" :key="item"
+                        :label="item" :name="item">
+                    </up-radio>
+                </up-radio-group>
+            </up-form-item>
+
             <up-form-item label="产品品类" :required="rules.class1[0].required" prop="class1">
                 <up-radio-group v-model="form.class1">
                     <up-radio :customStyle="{ marginLeft: '12px' }" v-for="(item) in class1" :key="item.value"
@@ -12,10 +21,11 @@
                 </up-radio-group>
             </up-form-item>
 
-            <up-form-item label="服务类型" :required="rules.servicetype[0].required" prop="servicetype">
-                <up-radio-group v-model="form.servicetype">
-                    <up-radio :customStyle="{ marginLeft: '12px' }" v-for="(item) in ['安装', '维修', '清洗']" :key="item"
-                        :label="item" :name="item">
+            <up-form-item v-if="rules.class2[0].required" label="故障类型" :required="rules.class2[0].required"
+                prop="class2">
+                <up-radio-group v-model="form.class2">
+                    <up-radio :customStyle="{ marginLeft: '12px' }" v-for="(item) in class2" :key="item.value"
+                        :label="item.value" :name="item.value">
                     </up-radio>
                 </up-radio-group>
             </up-form-item>
@@ -127,6 +137,7 @@ import { onLoad } from '@dcloudio/uni-app';
 const uFormRef = ref(null);
 const form = reactive({
     class1: '', // 产品品类
+    class2: '', // 故障类型
     servicetype: '', // 服务类型
     address: "", // 详细地址
     province: '', // 省份
@@ -148,6 +159,7 @@ const form = reactive({
 });
 const rules = reactive({
     class1: [{ required: true, message: '请选择产品品类', trigger: 'change' }],
+    class2: [{ required: false, message: "请选择故障类型", trigger: 'change' }],
     servicetype: [{ required: true, message: '请选择服务类型', trigger: 'change' }],
     province: [{ required: true, message: '请选择省市县', trigger: 'change' }],
     address: [{ required: true, message: '请输入详细地址', trigger: 'blur' }],
@@ -156,18 +168,36 @@ const rules = reactive({
     scenecontactphonenumber: [{ required: true, message: '请输入联系人电话', trigger: 'blur', pattern: /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/, message: '请输入正确的手机号码' }],
 });
 
-const class1 = ref(''); // 产品品类
+// 切换服务类型
+function servicetypeChange(type) {
+    // rules.class2[0].required = type == '维修';
+    uFormRef.value.setRules(rules);
+}
+
+const class1 = ref(''),
+    servertypes = ref(['安装', '维修', '清洗']),
+    class2 = ref('');
 
 let sa_workorderid = 0;
 
 onLoad((options) => {
     sa_workorderid = options.id;
     getDetail()
+    $Http.getClass('servertype').then(res => {
+        servertypes.value = res.data.map(v => v.value);
+        if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
+    });
+
     $Http.getClass('prodclass1').then(res => {
-        uFormRef.value.setRules(rules);
         class1.value = res.data;
         if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
     });
+
+    $Http.getClass('faulttype').then(res => {
+        class2.value = res.data;
+        uFormRef.value.setRules(rules);
+        if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
+    });
 });
 
 let detail = reactive({});
@@ -185,6 +215,9 @@ function save() {
                 sa_serviceorderid: detail.sa_serviceorderid,
                 ...form
             };
+            content.customername = content.customername || content.contact;
+            content.customerphonenumber = content.customerphonenumber || content.phonenumber;
+            content.sa_customersid = content.sa_customersid || 0;
             loading.value = true;
             $Http.basic({
                 "id": "20230208140003",
@@ -210,6 +243,7 @@ function getDetail() {
         console.log("工单详情", res)
         if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
         detail = reactive(res.data);
+        rules.class2[0].required = detail.type == '维修'
         for (const key in form) {
             if (detail[key] !== undefined) {
                 form[key] = detail[key];
@@ -229,7 +263,7 @@ let querySku = ref(true); // SKU是否正确
 
 function skuConfirm() {
     if (form.sku) {
-        ['contact', 'serviceenterprisename', 'cardno', 'itemid', 'itemname', 'itemno', 'model', 'phonenumber', 'unitname', 'spec'].forEach(key => {
+        ['contact', 'serviceenterprisename', "customername", 'customerphonenumber', 'sa_customersid', 'cardno', 'itemid', 'itemname', 'itemno', 'model', 'phonenumber', 'unitname', 'spec'].forEach(key => {
             form[key] = '';
         });
         $Http.basic({
@@ -252,7 +286,7 @@ function skuConfirm() {
             querySku.value = true;
             res.data[0].contact = res.data[0].name;
             res.data[0].serviceenterprisename = res.data[0].serviceenterprisename || res.data[0].enterprisename;
-            ['contact', 'phonenumber', 'serviceenterprisename', 'cardno', 'itemid', 'itemname', 'itemno', 'model', 'unitname', 'spec'].forEach(key => {
+            ['contact', "customername", 'customerphonenumber', 'sa_customersid', 'phonenumber', 'serviceenterprisename', 'cardno', 'itemid', 'itemname', 'itemno', 'model', 'unitname', 'spec'].forEach(key => {
                 form[key] = res.data[0][key] || '';
             });
             uni.showToast({ title: '已填充表单', icon: 'none' });
@@ -283,7 +317,7 @@ function changeItem(item) {
 
     function handle() {
         item.serviceenterprisename = item.serviceenterprisename || item.enterprisename;
-        ['contact', 'serviceenterprisename', 'sku', 'cardno', 'itemid', 'itemname', 'itemno', 'model', 'phonenumber', 'unitname', 'spec'].forEach(key => {
+        ['contact', 'serviceenterprisename', "customername", 'customerphonenumber', 'sa_customersid', 'sku', 'cardno', 'itemid', 'itemname', 'itemno', 'model', 'phonenumber', 'unitname', 'spec'].forEach(key => {
             form[key] = item[key] || '';
         });
         uni.showToast({ title: '已填充表单', icon: 'none' });

+ 19 - 3
static/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 4985326 */
-  src: url('//at.alicdn.com/t/c/font_4985326_41ua1apdsq9.woff2?t=1754295970513') format('woff2'),
-       url('//at.alicdn.com/t/c/font_4985326_41ua1apdsq9.woff?t=1754295970513') format('woff'),
-       url('//at.alicdn.com/t/c/font_4985326_41ua1apdsq9.ttf?t=1754295970513') format('truetype');
+  src: url('//at.alicdn.com/t/c/font_4985326_k6gds60jjxi.woff2?t=1756186335629') format('woff2'),
+       url('//at.alicdn.com/t/c/font_4985326_k6gds60jjxi.woff?t=1756186335629') format('woff'),
+       url('//at.alicdn.com/t/c/font_4985326_k6gds60jjxi.ttf?t=1756186335629') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,22 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-a-wodetiaozhuan:before {
+  content: "\e647";
+}
+
+.icon-dianhua2:before {
+  content: "\e706";
+}
+
+.icon-jiedan:before {
+  content: "\e705";
+}
+
+.icon-shezhi:before {
+  content: "\e704";
+}
+
 .icon-dianjizhankai:before {
   content: "\e70f";
 }